#1745 PIC16: (val + 2) & 0x1 always even?

open
nobody
PIC16
5
2013-07-16
2011-01-18
Herbert Pötzl
No

basically loop for (val=0; val<16; val++) and output to pin (led) like this:
LED_PIN = val & 0x1; results in blinking led while
LED_PIN = (val + 2) & 0x1; results in dark led

code generated looks complicated and strange ...
compiled with --use-non-free -mpic16 -p18f26j50

--- bug01_good.asm 2011-01-18 01:41:44.000000000 +0100
+++ bug01_bad.asm 2011-01-18 01:41:32.000000000 +0100
@@ -466,10 +466,16 @@ _00112_DS_:
MOVLW 0x10
SUBWF r0x00, W
BC _00116_DS_
-; .line 35; bug01.c LED_PIN = val & 0x1;
+; .line 37; bug01.c LED_PIN = (val + 2) & 0x1;
+ MOVFF r0x00, r0x01
+ CLRF r0x02
+ MOVLW 0x02
+ ADDWF r0x01, F
+ BTFSC STATUS, 0
+ INCF r0x02, F
MOVLW 0x01
- ANDWF r0x00, W
- MOVWF r0x01
+ ANDWF r0x01, F
+ CLRF r0x02
MOVF r0x01, W
ANDLW 0x01
MOVWF PRODH

Discussion

  • Herbert Pötzl
    Herbert Pötzl
    2011-01-18

    example source code

     
    Attachments
  • Raphael Neider
    Raphael Neider
    2011-01-18

    What's the data type of val? If it's bit, use char instead -- the pic backends do not support the bit data type.

    Besides, the code looks OK to me: val+2 requires val (r0x00) to be cast to int (16 bit) (r0x02:r0x01), which is incremented by 2 (MOVLW, ADDWF) and propagated to the hight byte (BTFSC, INCF), before being ANDed with 0x1 (MOVLW, ANDWF) -- in resulting in a cleared high byte (CLRF). The purpose of the (second) ANDLW is not clear to me -- what's LED_PIN? Another bit? In that case, the second ANDLW might be the cast of (val+2)&1 back to bit.

    Raphael

     
  • Maarten Brock
    Maarten Brock
    2011-10-31

    • summary: (val + 2) & 0x1 always even? --> PIC16: (val + 2) & 0x1 always even?
     
    • Category: --> PIC16