SDCC PIC16f737 odd problem

Discussion in 'Programmer's Corner' started by TrevorP, Mar 25, 2009.

  1. TrevorP

    Thread Starter Active Member

    Dec 8, 2006
    55
    0
    I'm writing the code for a microcontroller to control an ROV for a school competition and I've come into and interesting problem.

    I'm getting serial data from a laptop (or another chip in my case) and the packets are sending fine. So then I want to set ports based on that data.

    Anyway I've got a integer called 'packet' it contains: ##000000 00000000 00000000 10000101

    Now I've got the following two lines of code:
    Code ( (Unknown Language)):
    1. PORTB = ((packet & 0x00C0) >> 6); /* Turn on the correct direction */
    2. PORTB |= ((packet & 0x000F) << 2);
    3.  
    What's weird is that the 2nd bit of port B is not being set (seeing as the light doesn't turn on...but the 5th and 3rd bit pins do turn on as expected. If I comment out the second line the the first line works as expected.

    Also the generated assembly for those two lines are as follows:

    Code ( (Unknown Language)):
    1. ;   .line   97; "receive.c" PORTB = ((packet & 0x00C0) >> 6); /* Turn on the correct direction */
    2.     MOVLW   0xc0
    3.     ANDWF   r0x1001,W
    4.     MOVWF   r0x1002
    5.     CLRF    r0x1003
    6.     SWAPF   r0x1002,W
    7.     ANDLW   0x0f
    8.     MOVWF   r0x1004
    9.     SWAPF   r0x1003,W
    10.     MOVWF   r0x1005
    11.     ANDLW   0xf0
    12.     IORWF   r0x1004,F
    13.     XORWF   r0x1005,F
    14.     MOVLW   0xf0
    15.     BTFSC   r0x1005,3
    16.     IORWF   r0x1005,F
    17. ;shiftRight_Left2ResultLit:6080: shCount=1, size=2, sign=1, same=1, offr=0
    18.     BCF STATUS,0
    19.     BTFSC   r0x1005,7
    20.     BSF STATUS,0
    21.     RRF r0x1005,F
    22.     RRF r0x1004,F
    23. ;shiftRight_Left2ResultLit:6080: shCount=1, size=2, sign=1, same=1, offr=0
    24.     BCF STATUS,0
    25.     BTFSC   r0x1005,7
    26.     BSF STATUS,0
    27.     RRF r0x1005,F
    28.     RRF r0x1004,F
    29.     MOVF    r0x1004,W
    30.     BANKSEL _PORTB
    31.     MOVWF   _PORTB
    32. ;   .line   105; "receive.c"    PORTB = ((packet & 0x000F) << 2) | PORTB;
    33.     MOVLW   0x0f
    34.     BANKSEL r0x1001
    35.     ANDWF   r0x1001,F
    36.     CLRF    r0x1000
    37.     MOVF    r0x1001,W
    38.     MOVWF   r0x1002
    39.     BCF STATUS,0
    40.     RLF r0x1002,W
    41.     MOVWF   r0x1001
    42.     BCF STATUS,0
    43.     RLF r0x1001,F
    44.     BANKSEL _PORTB
    45.     MOVF    _PORTB,W
    46.     BANKSEL r0x1002
    47.     MOVWF   r0x1002
    48.     IORWF   r0x1001,W
    49.     BANKSEL _PORTB
    50.     MOVWF   _PORTB
    51.     GOTO    _00105_DS_
    52.  
    If you might know why this is happening or a good solution it would be greatly appreciated. (Also the tristate for Port B has been entirely set to output and there is nothing special about those pins).

    Thanks,

    Trevor
     
  2. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    If you write 0xFF to PORTB, skipping those two lines, do all pins have an output?
     
  3. TrevorP

    Thread Starter Active Member

    Dec 8, 2006
    55
    0
    Yep it does.
     
  4. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    Can you simulate the input of those 4 bytes in a debugger to make sure the logic statements are doing what you are expecting them to do?
     
  5. TrevorP

    Thread Starter Active Member

    Dec 8, 2006
    55
    0
    I could but it would be a bit difficult. I seemed to have found a solution though.

    If I do:
    Code ( (Unknown Language)):
    1.  
    2. char portb;
    3.  
    4. portb = ((packet & 0xC0) >> 6);
    5. portb |= ...;
    6.  
    7. PORTB = portb;
    8.  
    It solves the problem. It seems that the compiler makes code that doesn't like accessing the value on PORTB.
     
  6. thatoneguy

    AAC Fanatic!

    Feb 19, 2009
    6,357
    718
    Which compiler are you using?

    Please post the ASM listing for what the second version creates compared to the first.

    In the first listing, what is the define for _PORTB? where banksel _PORTB and movwf _PORTB are referencing something other than PORTB.
     
Loading...