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


Closed Thread
Results 1 to 12 of 12

Hybrid View

  1. #1
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    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

  2. #2
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,653


    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 " !!!
    *****************************************

  3. #3
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    4,139


    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

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 : 0

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