Reassigning I/O within the program ?


Closed Thread
Results 1 to 18 of 18
  1. #1
    Join Date
    Nov 2007
    Posts
    24

    Question Reassigning I/O within the program ?

    I would like to reassign I/O pins to specific variables based on the state of an input pin. Can I do this? e.g.

    If Input = 1 then
    Variable1 = PORTB.1
    else
    Variable1 = PORTB.2
    endif

    But the above doesn't work. Is there another way? I would like to do this at the beginning of the program, just once.

  2. #2
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    You could use PIN numbers instead of PORT.bit.


    Code:
    InputSelect  VAR PORTB.0
    myPIN        VAR BYTE
    
    Test:
        IF InputSelect = 1 THEN
            myPIN = 1            ; PORTB.1 selected
        ELSE
            myPIN = 2            ; PORTB.2 selected
        ENDIF
    
        HIGH myPIN
        PAUSE 500
        LOW myPIN
        PAUSE 500
    GOTO Test
    Or, a similar version.
    The Inputselect will always read 0 or 1. Add 1 to it to make 1 or 2, for PORTB.1 and PORTB.2.
    Code:
    InputSelect  VAR PORTB.0
    myPIN        VAR BYTE
    
    Test:
        myPIN = InputSelect + 1
    
        HIGH myPIN
        PAUSE 500
        LOW myPIN
        PAUSE 500
    GOTO Test
    The ports used depends on the chip you are using.
    Check the .bas file for the PIC you are using in the PBP folder. (ex. 16F877a.bas)

    PORTL and TRISL determine which PORT that pin numbers 0-7 go to.
    PORTH and TRISH determine which PORT that pin numbers 8-15 go to.
    <br><br>
    Last edited by Darrel Taylor; - 6th June 2010 at 01:23. Reason: Forgot PIN was a reserved word, changed to myPIN
    DT

  3. #3
    Join Date
    Nov 2007
    Posts
    24


    Did you find this post helpful? Yes | No

    Default

    Yes, there are many ways to achieve this within the loop of the main program. I was trying avoid having to make pin decisions every time I wanted to collect data. I just want to reassign the pins at the beginning of the program, and never worry about it again (i.e. less code).

    Having thought about this for awhile now, I think the easiest way is to just make a subroutine for each data input (e.g. Get_Data) that makes the I/O pin decision each time I need the data. It still gobbles up a bunch of code, but is still relatively easy to follow the logic.

  4. #4
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Del Tapparo View Post
    Yes, there are many ways to achieve this within the loop of the main program. I was trying avoid having to make pin decisions every time I wanted to collect data. I just want to reassign the pins at the beginning of the program, and never worry about it again (i.e. less code).
    I don't see a difference there.

    If you set the PIN variable at the top of the program instead of in the main loop, it's the same thing.

    Best regards,
    DT

  5. #5
    Join Date
    Nov 2007
    Posts
    24


    Did you find this post helpful? Yes | No

    Thumbs up

    I get it now ....

    In my case, all of the reassigned inputs use the PULSIN command. I simply assign a variable to the pin portion of the PULSIN command, separate from the resulting input data variable.

    Thanks Darrel! Much appreciated.

  6. #6
    Join Date
    Sep 2007
    Location
    USA, CA
    Posts
    271


    Did you find this post helpful? Yes | No

    Default

    I don't like needing to check the compiler files for information, because changing PICs can be a hassle, especially when you forget about it.

    When I did it (years ago) I had to do something like this...
    myPIN = 2 ...set this in your IF statements
    low portb.0[myPIN] ...allows you to use any port you like, and changing PICs is easy.

  7. #7
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    >myPIN = 2 ...set this in your IF statements
    >low portb.0[myPIN]


    That would READ PORTB.2, and set either PORTB.0 or PORTB.1 low depending on the state of RB2(0 or 1).

    portb.0[myPIN] = 1 ; lets you control any pin, assuming TRIS has been set

    But it can't be used in SERIN/OUT, PULSIN/OUT, RCTIME, HIGH/LOW, etc., like the PIN numbers can.
    DT

  8. #8
    Join Date
    Sep 2007
    Location
    USA, CA
    Posts
    271


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Darrel Taylor View Post
    >myPIN = 2 ...set this in your IF statements
    >low portb.0[myPIN]


    That would READ PORTB.2, ....
    How in the world wout that READ a pin?

  9. #9
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by tenaja View Post
    How in the world wout that READ a pin?
    With most PBP statements, you only have 3 options for the PIN's.
    It's usually described like this in the manual ...
    Pin may be a constant, 0-15, or a variable that contains a number 0-15 (e.g. B0) or a pin name (e.g. PORTA.0).
    But portb.0[myPIN] is an Array operation.
    The only one of the 3 options that fits an array result is "or a variable that contains a number 0-15".

    In order to know which PIN to use, it has to READ the variable, or in this case do the array operation (reading a PIN).
    Since it's a BIT array, it will only see a 1 or a 0.

    hth,
    DT

  10. #10
    Join Date
    Sep 2007
    Location
    USA, CA
    Posts
    271


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by Darrel Taylor View Post
    With most PBP statements, you only have 3 options for the PIN's.
    It's usually described like this in the manual ...


    But portb.0[myPIN] is an Array operation.
    The only one of the 3 options that fits an array result is "or a variable that contains a number 0-15".

    In order to know which PIN to use, it has to READ the variable, or in this case do the array operation (reading a PIN).
    Since it's a BIT array, it will only see a 1 or a 0.

    hth,
    Either we are miscommunicating, or they have changed the way bit arrays work, or you must be misunderstanding bit arrays. I have been using this method for 8 years:
    PORTB.0[PinToChange] = NewPinState

    The value for PinToChange can be any number 0 to7, and this allows you to use it on ANY PORT. The value for NewPinState must be 0 or 1.

    PORTA.0[4] = NewPinState
    PORTB.0[4] = NewPinState

    Will set PortA.4 AND PortB.4 to the NewPinState

  11. #11
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by tenaja View Post
    Either we are miscommunicating, or they have changed the way bit arrays work, or you must be misunderstanding bit arrays. I have been using this method for 8 years:
    PORTB.0[PinToChange] = NewPinState
    Obviously miscommunicating.

    In post #6 you originally said
    myPIN = 2 ...set this in your IF statements
    low portb.0[myPIN] ...allows you to use any port you like, and changing PICs is easy.
    In my reply I stated that portb.0[myPIN] = 1 will work, but it can't be used as a PIN in PBP statements like SERIN/OUT, PULSIN/OUT, RCTIME, HIGH/LOW, etc.

    LOW is a PBP statement with a PIN parameter.
    DT

  12. #12
    Join Date
    Sep 2007
    Location
    USA, CA
    Posts
    271


    Did you find this post helpful? Yes | No

    Default

    Oops, well, I meant them to match.
    The second was pasted from a working file. I don't know why the syntax wouldn't work for a LOW, though.

    The point is, though, that there are ways to do it without the IFs. On the other hand, PBP is dreadfully inefficient, so it might be better to use the IFs anyway.

  13. #13
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by tenaja View Post
    ... I don't know why the syntax wouldn't work for a LOW, though.
    That's what I was trying to explain in post#9.
    If there's something in that post you don't understand, I'll try to go a little deeper.

    The point is, though, that there are ways to do it without the IFs. On the other hand, PBP is dreadfully inefficient, so it might be better to use the IFs anyway.
    I completely disgree.
    There are many ways to be inefficient with PBP, but PBP itself is not the bottleneck.
    DT

  14. #14
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    Originally Posted by tenaja
    ... I don't know why the syntax wouldn't work for a LOW, though.
    LOW sets the TRIS and an array can not be TRISed.

    PBP is dreadfully inefficient,
    For what it is worth I also disagree. That almost sounds like the poster that says "I know my code is good so it has to be something else". 99% of the time the problem is the person on the keyboard. If you understand PBP and the understand the chip you are using PBP is very efficient.
    Dave
    Always wear safety glasses while programming.

  15. #15
    Join Date
    Sep 2007
    Location
    USA, CA
    Posts
    271


    Did you find this post helpful? Yes | No

    Default

    Ah, yes, I'd forgotten about the tris part.

    Quote Originally Posted by mackrackit View Post
    For what it is worth I also disagree. That almost sounds like the poster that says "I know my code is good so it has to be something else". 99% of the time the problem is the person on the keyboard. If you understand PBP and the understand the chip you are using PBP is very efficient.
    Regarding your (plural) responses here, then we will respectfully disagree. For there to be "efficient" code, there must be something "inefficient" to compare it to. If you were to compare it to asm, then PBP is horrendous--as most compilers are, if the asm author knows his head from a hole in the ground. So that point is moot. However, if you compare it to a similar compiler, say, Proton, then PBP still only gets a "B" grade, which in my opinion is inefficient. In almost every instance I have compared, PBP is a minimum of 10% less efficient than Proton. In some instances, I've saved noticeably more.

    The task in this simple topic here shows it:

    PBP:
    Code:
    PinToChange        Var Byte
    NewPinState        Var bit 
    
    pintochange = 4
    newpinstate = 1
    
    PORTB.0[PinToChange] = NewPinState 
    pintochange = 2
    newpinstate = 0
    PORTB.0[PinToChange] = NewPinState 
    
    low PORTB.0
    end     '74 words used
    Proton:
    Code:
    PinToChange        Var Byte 
    NewPinState        Var Bit  
    
    pintochange = 4
    newpinstate = 1
    LoadBit PORTB, PinToChange, NewPinState
    
    pintochange = 2
    newpinstate = 0
    LoadBit PORTB, PinToChange, NewPinState
    
    Low PORTB.0
    End     '67 words used
    Just on this simplest of examples, PBP takes up more than 10% extra code space.

    On top of that, I can actually EASILY see the generated asm code, and see where inefficiencies take place:
    Code:
    PROTON#CODE#START
            ORG 0
            GOTO PROTON#MAIN#START
    A@BIT
            MOVWF 13
            ANDLW 248
            MOVWF 12
            RRF 12,F
            RRF 12,F
            RRF 12,W
            ADDWF 4,F
            CALL C@BT
            MOVWF 13
            ANDWF 0,W
            GOTO I@NT
    C2@FB
            MOVF 13,W
            SKPC
            CLRW
            XORWF 0,W
            ANDWF 13,W
            XORWF 0,F
            GOTO I@NT
    C@BT
            MOVLW (C@TBL >> 8)
            MOVWF 10
            MOVF 13,W
            ANDLW 7
            ADDWF 2,F
    C@TBL
            RETLW 1
            RETLW 2
            RETLW 4
            RETLW 8
            RETLW 16
            RETLW 32
            RETLW 64
            RETLW 128
    I@NT
            BCF 3,7
    I@NT2
            BCF 3,5
            BCF 3,6
            RETURN
    PROTON#MAIN#START
    F2_SOF EQU $ ; TEST.PRP
    F2_EOF EQU $ ; TEST.PRP
    F1_SOF EQU $ ; TEST.BAS
    F1_000012 EQU $ ; IN [TEST.BAS] PINTOCHANGE        VAR BYTE
    F1_000013 EQU $ ; IN [TEST.BAS] NEWPINSTATE        VAR BIT
    F1_000015 EQU $ ; IN [TEST.BAS] PINTOCHANGE = 4
            MOVLW 4
            MOVWF PINTOCHANGE
    F1_000016 EQU $ ; IN [TEST.BAS] NEWPINSTATE = 1
            BSF _B#VR1,0
    F1_000017 EQU $ ; IN [TEST.BAS] LOADBIT PORTB, PINTOCHANGE, NEWPINSTATE
            MOVLW PORTB
            MOVWF FSR
            MOVF PINTOCHANGE,W
            ADDLW 0
            CALL A@BIT
            BCF STATUS,0
            BTFSC _B#VR1,0
            BSF STATUS,0
            CALL C2@FB
    F1_000019 EQU $ ; IN [TEST.BAS] PINTOCHANGE = 2
            MOVLW 2
            MOVWF PINTOCHANGE
    F1_000020 EQU $ ; IN [TEST.BAS] NEWPINSTATE = 0
            BCF _B#VR1,0
    F1_000021 EQU $ ; IN [TEST.BAS] LOADBIT PORTB, PINTOCHANGE, NEWPINSTATE
            MOVLW PORTB
            MOVWF FSR
            MOVF PINTOCHANGE,W
            ADDLW 0
            CALL A@BIT
            BCF STATUS,0
            BTFSC _B#VR1,0
            BSF STATUS,0
            CALL C2@FB
    F1_000023 EQU $ ; IN [TEST.BAS] LOW PORTB.0
            BSF STATUS,5
    RAM_BANK = 1
            BCF TRISB,0
            BCF STATUS,5
    RAM_BANK = 0
            BCF PORTB,0
    F1_000024 EQU $ ; IN [TEST.BAS] END
    PB@LB2
            SLEEP
            GOTO PB@LB2
    F1_EOF EQU $ ; TEST.BAS
    PB@LB3
            GOTO PB@LB3
    If I find a bottleneck that I need to speed up, I can count the words right there. If I want, I can recode it in basic, or copy/paste the asm and edit with my own optimizations.

    See, my comments were directly related to the efficiency of the COMPILER. They had nothing to do with your coding or your abilities.

  16. #16
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    Then why do you even bother with PBP? Just stick with Proton.
    Dave
    Always wear safety glasses while programming.

  17. #17
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by tenaja View Post
    On top of that, I can actually EASILY see the generated asm code, and see where inefficiencies take place:
    For the beniefit of those of us that don't use PROTON....
    And since you only gave the ASM generated by PROTON...

    Could you please explain the difference.
    Relative to PINS and ARRAY's. And the ASM generated by PBP?
    DT

  18. #18
    Join Date
    Sep 2007
    Location
    USA, CA
    Posts
    271


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by mackrackit
    Then why do you even bother with PBP? Just stick with Proton.
    For the most part, I do. But I have PBP, and it's very similar to PDS in syntax (based on BS2), so I hang out here to learn and share.

    Quote Originally Posted by Darrel Taylor View Post
    For the beniefit of those of us that don't use PROTON....
    And since you only gave the ASM generated by PROTON...

    Could you please explain the difference.
    Relative to PINS and ARRAY's. And the ASM generated by PBP?
    ASM code for PBP?
    Code:
    	MOVE?CB	0C0h, ADCON0
    	MOVE?CB	004h, _PinToChange
    	MOVE?CT	001h, _NewPinState
    	AIN?TTB	_NewPinState, _PORTB??0, _PinToChange
    	MOVE?CB	002h, _PinToChange
    	MOVE?CT	000h, _NewPinState
    	AIN?TTB	_NewPinState, _PORTB??0, _PinToChange
    	LOW?T	_PORTB??0
    	END?
    Hardly indicative of the amount of code space used...
    You actually have to use the LST file. I'll post it later...

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