A way to define specific ports for output bits? start output in middle port?


Closed Thread
Results 1 to 12 of 12
  1. #1
    Join Date
    Dec 2012
    Location
    Tennessee
    Posts
    262

    Default A way to define specific ports for output bits? start output in middle port?

    say I wanted to output binary numbers (4bit, or 3 bit, or 5 bit) my choice- but lets say 3bit right now so I want to output a number (0-7). the trick is I dont want to start with PORTx.0 to PORTx.2, say i want to use PORTx 3 - 5. is this possible and how would I do it. ???

    also if this is possible can you use any ports to build an output, say you need 8 ports to build a byte output could you build 8 seperate I/O's from different ports like

    Code:
    MYBYTE VAR BYTE
    
    MYBYTE.0 = PORTA.7
    MYBYTE.1 = PORTA.3
    MYBYTE.2 = PORTB.4
    MYBYTE.3 = PORTB.5
    MYBYTE.4 = PORTB.6
    MYBYTE.5 = PORTC.2
    etc....
    the first question is primary, the second is elective, just curious

  2. #2
    Join Date
    Dec 2012
    Location
    Tennessee
    Posts
    262


    Did you find this post helpful? Yes | No

    Default Re: A way to define specific ports for output bits? start output in middle port?

    Ok right now Im having a problem, On PORTB.0 = INT0
    now I want to use PORTB.1-3 as a binary output from 0-7
    but since my portb.0 isnt available, how do i set it to start my output at bit 2 (portb.1)
    my only available pins right now is portb 1-5, I need a 3bit binary output that will go to a 3bit to 8decimal chip that drives 8 leds.
    I was hoping theres a command like in the LCD commands to say start bit = ?

  3. #3
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,520


    Did you find this post helpful? Yes | No

    Default Re: A way to define specific ports for output bits? start output in middle port?

    Hi,
    A bit convoluted but it hopefully shows what's happening:
    Code:
    Temp = PortB.0 & %11110001        ' Read PortB into Temp and clear bits 1-3 ( & is bitwise AND)
    Value = 5                                      ' This is the value that will be written to bits 1-3
    Value = Value << 1                          ' Shift value to the left one place to "align it" with bits 1-3 
    PortB = Temp | Value                     ' Write new value back to PortB. ( | is bitwise OR )
    Or
    Code:
    Temp = PortB.0
    Value = 5
    Temp.1 = Value.0
    Temp.2 = Value.1
    Temp.3 = Value.2
    PortB.0 = Temp
    Or, if a bit bitflipping on the port doesn't matter
    Code:
    Value = 5
    PortB.1 = Value.0
    PortB.2 = Value.1
    PortB.3 = Value 2
    And I'm sure there are other ways.

    /Henrik.
    Last edited by Ioannis; - 12th January 2013 at 12:50. Reason: Corrected the < error

  4. #4
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,614


    Did you find this post helpful? Yes | No

    Default Re: A way to define specific ports for output bits? start output in middle port?

    Hi,

    I think Darrel wrote something about that ... some times ago.

    this was the origin of "LCD on Any pin" !

    Here it is ...

    Code:
    '****************************************************************
    '*  Name    : VirtualPort.bas                                   *
    '*  Author  : Darrel Taylor                                     *
    '*  Date    : 3/20/2006                                         *
    '*  Version : 1.1                                               *
    '*  Notes   : Allows you to control non-contiguous PINs/BITs    *
    '*          : as if they were a contiguous PORT/Register        *
    '****************************************************************
    '*  See this Webpage for more info                              *
    '*  http://www.picbasic.co.uk/forum/showthread.php?t=4074       *
    '****************************************************************
    '*  with assistance from:                                       *
    '*   1.1    SteveB                                              *
    '*   1.2    ?                                                   *
    '****************************************************************
    
    disable debug
    
    
    VP_DelayCount  VAR WORD BANK0  ; Used for internal Delay only
    
    ASM
    PortVar set 0
       ; nolist
    
    ;----[Defines a Virtual PIN in a Virtual PORT]--------------------------------
    Vpin  macro  Vb, P, Pbit
      local Vaddr, VarBit
        if (Vb < 16)                                 ; If Var bit# is < 16 
          if (Pbit < 8)                              ; and Port bit# is < 8
              if (PortAction < 2)                      
                  if (Vb > 7)                        ; Var Bit > 7, use high word
    Vaddr  = PortVar + 1
    VarBit = Vb - 8
                  else
    Vaddr  = PortVar
    VarBit = Vb
                  endif
              endif
              if (PortAction == 0)                   ; read
                  MOVE?TT  P, Pbit, Vaddr, VarBit      
              else
                  if (PortAction == 1)               ; write
                      MOVE?TT  Vaddr, VarBit, P, Pbit  
                  else
                      if (PortAction == 2)           ; output
                          PhysicalPort  P            ; only if it's a Real PORT
                          if (Found == 1)
                              OUTPUT?T  P, Pbit
                          endif
                      else
                          if (PortAction == 3)       ; input
                              PhysicalPort  P        ; only if it's a Real PORT
                              if (Found == 1)
                                  INPUT?T  P, Pbit
                              endif       
                          endif
                      endif
                  endif
              endif
          else
                error Vpin - PORT BIT [Pbit] Out of Range
          endif  
        else
            error Vpin - Variable BIT [Vb] Out of Range
        endif  
      endm
    
    ;----[Copy a bit to a Pin]----------------------------------------------------
    Vbit  macro  Rin,Bin, Rout,Bout
        MOVE?TT  Rin,Bin, Rout,Bout
      endm
      
    ;----[Read a Virtual Port]----------------------------------------------------
    ReadPort  macro PortVar, PinMacro
      ; nolist
    PortAction = 0  ; Read
           PinMacro
        list  
      endm
        
    ;----[Write a variable to a Virtual Port]-------------------------------------
    WritePort  macro PortVar, PinMacro
      ; nolist
    PortAction = 1
            PinMacro
        list  
      endm
      
    ;----[Set ALL pins of a virtual Port to OUTPUT]-------------------------------
    OutputPort  macro  PinMacro
      ; nolist
    PortAction = 2
            PinMacro
        list  
      endm
        
    ;----[Set ALL pins of a virtual Port to INPUT]--------------------------------
    InputPort  macro PinMacro
      ; nolist
    PortAction = 3
            PinMacro
        list  
      endm
    
    ; These 4 are useful for Port Control Pins, such as Enable and Direction pins
    ; They don't change the TRIS state during INPUT/OUTPUT calls, which makes
    ; bi-directional ports a lot easier.
      
    ;----[Make a Pin LOW]---- Does not change TRIS bit ---------------------------
    PinHigh  macro  P, B
      ; nolist
        if (PortAction < 2)   ; Don't do anything on Input or Output pass
            MOVE?CT  1, P, B  ; Make Pin HIGH
        endif
        list  
      endm
    
    ;----[Make a Pin LOW]---- Does not change TRIS bit ---------------------------
    PinLow  macro  P, B
      ; nolist
        if (PortAction < 2)   ; Don't do anything on Input or Output pass
            MOVE?CT  0, P, B  ; Make Pin LOW
        endif
        list  
      endm
    
    ;----[Similar to PAUSEUS, but ASM interrupt compatible]---(accurate to 1uS)---
    DelayUS  macro T
      ; nolist
      local InstCount, LoopCount, DelayLoop, LoopsDone, LeftOver, Offset
    ; -- Calculate number of 3 cycle loops plus leftover nop's to execute --
    InstCount = ((OSC*10/4)*T+5)/10  ; Inst cycles required for delay (Rounded UP)
    LoopCount = InstCount / 3
        if (LoopCount > 255)
    Offset = (LoopCount >> 8) * 7 + 4
        else
    Offset = 0
        endif
    ; -- Adjust for HighByte --
    InstCount = InstCount - Offset
        if (Offset > (LoopCount & 0FFh))
    InstCount = InstCount - 4
        endif
    LoopCount = InstCount / 3
        if (LoopCount > 255)
    Offset = (LoopCount >> 8) * 7
        else
    Offset = 0
        endif
    LeftOver  = InstCount % 3
    ;-------------------------------------------
        if (LoopCount > 0)
            MOVE?CW  LoopCount, _VP_DelayCount
    DelayLoop
            decfsz   _VP_DelayCount, F               ;  1
            goto     DelayLoop                       ;  2    3 per loop, under 256
        
            if (LoopCount > 255)
                movf     _VP_DelayCount + 1, W       ;  1    
                btfsc    STATUS, Z                   ;  1    
                goto     LoopsDone                   ;  2    4 on last loop
                
                decf     _VP_DelayCount + 1, F       ;  1    
                goto     DelayLoop                   ;  2    7 per highbyte count 
    LoopsDone
            endif
        endif
        if (LeftOver > 0)
            nop
        endif
        if (LeftOver > 1)
            nop
        endif
    
        list  
      endm
      
    ;----[Pulse a Pin LOW for a specified number of uS]---------------------------
    PulseLow  macro P, B, Time
      ; nolist
        PhysicalPort  P            
        if (Found == 1)            ; only if it's a Real PORT
            if (PortAction < 2)
              MOVE?CT  0, P, B
              DelayUS  Time
              MOVE?CT  1, P, B
            endif
        else
            error "PulseLow - Can only Pulse a Physical Pin"
        endif
        list  
      endm
    
    ;----[Pulse a Pin HIGH for a specified number of uS]---------------------------
    PulseHigh  macro P, B, Time
      ; nolist
        PhysicalPort  P            
        if (Found == 1)            ; only if it's a Real PORT
            if (PortAction < 2)
              MOVE?CT  1, P, B
              DelayUS  Time
              MOVE?CT  0, P, B
            endif
        else
            error "PulseHigh - Can only Pulse a Physical Pin"
        endif
        list  
      endm
      
    ;----[Is the PIN a Physical PIN or just a register?]-----(Compile Time Only)--
    PhysicalPort macro P
      ; nolist
    Found = 0
        ifdef GPIO
            if P == GPIO
    Found = 1
            endif
        endif
        ifdef PORTA
            if P == PORTA
    Found = 1
            endif
        endif
        ifdef PORTB
            if P == PORTB
    Found = 1
            endif
        endif
        ifdef PORTC
            if P == PORTC
    Found = 1
            endif
        endif
        ifdef PORTD
            if P == PORTD 
    Found = 1
            endif
        endif
        ifdef PORTE
            if P == PORTE
    Found = 1
            endif
        endif
        ifdef PORTF
            if P == PORTF
    Found = 1
            endif
        endif
        ifdef PORTG
            if P == PORTG
    Found = 1
            endif
        endif
        ifdef PORTH
            if P == PORTH
    Found = 1
            endif
        endif
        ifdef PORTI
            if P == PORTI
    Found = 1
            endif
        endif
        ifdef PORTJ
            if P == PORTJ
    Found = 1
            endif
        endif
        ifdef PORTK
            if P == PORTK
    Found = 1
            endif
        endif
      
        list
      endm
        
      list
    ENDASM
                                                        
    disable debug
    ;----[Trick PBP into including certain macro's]---Doesn't use any code space--
    @  ifdef NotCompiled
    @DummyPort = 0
     DummyPort VAR BYTE EXT
           OUTPUT DummyPort.0       ; OUTPUT?T
           INPUT  DummyPort.0       ; INPUT?T
    @  endif
    
    enable debug
    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  5. #5
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,803


    Did you find this post helpful? Yes | No

    Default Re: A way to define specific ports for output bits? start output in middle port?

    OK, Alain. Very nice idea to set or reset a bit!



    Ioannis

  6. #6
    Join Date
    Dec 2012
    Location
    Tennessee
    Posts
    262


    Did you find this post helpful? Yes | No

    Default Re: A way to define specific ports for output bits? start output in middle port?

    I kinda like your idea henrik, but im alittle confused on a couple of the terms "bitwise, shifting" I dont normally do this kind of thing in code.
    My PORTB.0 is being used as a interupt, is there a way to do something to shift the number over
    Sorry ACE i was totally confused by that code.

    What I need with very little coding.
    MYVAL = 7 ' 00000111
    SHIFTCODE MYVAL < ? & make bit.0 1 ' New MYVAL = 00001111
    PORTB = MYVAL

    now as far as i understand I need to make sure any code that is sent to portb has portb.0 as a 1, since i need to keep it high, until a button is pressed. I dont want to trigger a INT by sending a low to that pin. but I need to shift the first 3 bits to the left and make sure the first bit ends up a 1.

  7. #7
    Join Date
    Dec 2012
    Location
    Tennessee
    Posts
    262


    Did you find this post helpful? Yes | No

    Default Re: A way to define specific ports for output bits? start output in middle port?

    heres a copy of an sample program code needs to be fixed, think of it lighting 3 led's in binary sequence

    Code:
    PORTB.0 = INT ' Just a INT Code Placeholder
    X VAR Byte : X = 0
    
    MyLOOP:
    PORTB.1-3 = X ' Shifting Code Needed
    pause 1000
    X = X + 1
    if X > 7 then X = 0
    Goto MyLoop

  8. #8
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,520


    Did you find this post helpful? Yes | No

    Default Re: A way to define specific ports for output bits? start output in middle port?

    Hi,
    First of all, there's an error in my previous example. The shift left operator is of course << and nothing else, sorry about that. The "edit window" is closed so I can't go back and fix it.

    With your code as an example, try this:
    Code:
    MyLoop:
      Temp = PortB & %11110001
      PortB = Temp | (X << 1)
      X = X + 1
      IF X > 7 THEN X = 0
      PAUSE 1000
    Goto MyLoop
    Lets go thru the two first lines:
    Temp = PortB & %11110001 - This reads the state of PortB into a variable called Temp and ANDS it with the value 14. What's happening there is that Temp will be whatever PortB is except for bits 1-3 which will be cleared to 0.
    PortB = Temp | (X << 1) - This takes the value of Temp and ORs with the value of X shifted one "step" to the left. Remember that Temp is a copy of what PortB was except bits 1-3 which are now 0. So if X is 3 (%00000011) PortB will be %xxxx011x where x is whatever was there before because X is shifted one "step" before ORing it with Temp.

    When doing a bitwise AND on two numbers each bit must be '1' in BOTH numbers for the bit to be '1' in the "result. So when doing a bitwise and with a value where certain bits are '0' those bits will be '0' in the result, example.
    %11111111 & %00000000 = %00000000
    %11111111 & %11110000 = %11110000
    %11001000 & %00001111 = %00001000

    When doung a biteise OR on two numbers it's enough that a bit in either number is '1' for that bit to be '1' in the result, example:
    %11111111 | %00000000 = %11111111
    %00000000 | %00001111 = %00001111
    %11110000 | %00001111 = %11110000

    So in the above code we read in PortB, clear bits 1-3 and put the value of X in those 3 bits.

    /Henrik.
    Last edited by HenrikOlsson; - 12th January 2013 at 11:46.

  9. #9
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,614


    Did you find this post helpful? Yes | No

    Default Re: A way to define specific ports for output bits? start output in middle port?

    just some MORE browsing job ...

    http://www.picbasic.co.uk/forum/showthread.php?p=22065

    yes ... relevant threads already exist

    @#14 ... how to use Virtualport.bas

    Next step ???

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  10. #10
    Join Date
    Dec 2012
    Location
    Tennessee
    Posts
    262


    Did you find this post helpful? Yes | No

    Default Re: A way to define specific ports for output bits? start output in middle port?

    So if i dont care about PORTB's other bits could it work like this?

    Code:
    MyLoop:
    Temp = X << 1
    TEMP.0 = 1 ' to Keep PORTB.0 High
    PortB = Temp
    X = X + 1
    IF X > 7 THEN X = 0
    PAUSE 1000
    Goto MyLoop

  11. #11
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,520


    Did you find this post helpful? Yes | No

    Default Re: A way to define specific ports for output bits? start output in middle port?

    Hi,
    Yes, if you don't care what's happening with PortB.4-7 then that should work.

    If PortB.4-7 are outputs then your aproach won't work properly since you'll overwrite those bits with the value of Temp. That's the reason for first reading PortB and ANDing it with %11110001 so that we ONLY change the state of bits 1-3 when ORing Temp with X. If all bits except 1-3 are inputs then your aproach should work - which brings me to the next point...

    I suspect the purpose with "keeping PortB.0 high" is to prevent it from tripping an interrupt? If so I don't think you need to worry about that.
    When PortB.0 is setup as an input, it doesn't matter what you write to PortB.0 - it'll never actually "get to" the actual pin since the output driver is disabled. Look at the block diagram of the pin in the datasheet, this is for the 16F887 it may differ slightly from whatever device you're using:

    Name:  887_PortB.png
Views: 575
Size:  36.1 KB

    The "interrupt path" is drawn in blue here. The output driver is circled in red. As you can see the output driver is enabled/disabled by D-type flip-flop which is controlled by writing to TRISB. So, even if you write '0' to PortB.0 it'll never reach the pin and cause an interrupt since that '0' won't "go thru" the output driver.

    /Henrik.

  12. #12
    Join Date
    Dec 2012
    Location
    Tennessee
    Posts
    262


    Did you find this post helpful? Yes | No

    Default Re: A way to define specific ports for output bits? start output in middle port?

    ok thanks henrik, yes there is nothing connected to portb 4-7, theres no room for me to add those ports to anything as the ports are blocked by other circuit traces. and yes I was thinking of the INT on portb.0 , but I do see your logic there, since ive made it a tris=1 then it shouldnt change state even if I tell it to in code., thanks for the diagram, if I didnt need the INT and if I could get to the other B pins i would just use the 8 leds direct but I dont have that option so this will work, thanks.

Similar Threads

  1. Changing bits in a byte for multiple output
    By tazntex in forum Serial
    Replies: 3
    Last Post: - 11th August 2008, 19:10
  2. Replies: 5
    Last Post: - 30th April 2008, 20:01
  3. 28 bits --> DEC output on LCD
    By SteveB in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 1st August 2006, 19:33
  4. Serial Output 10 Bits
    By GEEZER in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 17th May 2005, 02:14
  5. Duplicating port input to port output
    By lwindridge in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 26th April 2004, 21:43

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts