I have the following code in my microcontroler program:
int analogValue = ADCH; // ADC Data Register // // Simple analog comparator. // If analogValue lower than threshold then toggle output high, // Otherwise toggle it low. // if ( analogValue > 128 ) { PORTB = 0; // Port B Data Register } else { PORTB = _BS( outputPin ); // Port B Data Register } Where:
- ADCH is the register that contains the value from the ADC
- PORTB is a dital output port that toggles an LED
Looking at the resulting assembly code, I noticed that it is doing a 16 bit compare (lines 40-44) where strictly speaking only 8 bits would have been sufficient:
40: 90 e0 ldi r25, 0x00 ; 0 42: 81 38 cpi r24, 0x81 ; 129 44: 91 05 cpc r25, r1 46: 14 f0 brlt .+4 ; 0x4c <__SREG__+0xd> 48: 18 ba out 0x18, r1 ; PORTB 4a: f5 cf rjmp .-22 ; 0x36 <__CCP__+0x2> 4c: 28 bb out 0x18, r18 ; PORTB 4e: f3 cf rjmp .-26 ; 0x36 <__CCP__+0x2> I realize I declared analogValue as int, which indeed is 16 bit on AVR, but ...
How can I instruct the compiler to use 8 bit comparison? The Arduino IDE allows me to use byte, but avr-gcc by default doesn't.
Check this page for the complete program and its disassembled resulting code.
EDIT1:
Changing int to char changes the assembly code to:
14: 11 24 eor r1, r1 ; r1 = 0 3e: 18 ba out 0x18, r1 ; PORTB Basically skipping the test entirely.
EDIT2: (Thnx: Wouter van Ooijen)
Changing int to unsigned char changes the assembly code to:
3c: 85 b1 in r24, 0x05 ; ADCH 3e: ... 40: 87 fd sbrc r24, 7 ; compare < 128 (well optimized) 42: 02 c0 rjmp .+4 ; 0x48 <__SREG__+0x9> 44: 18 ba out 0x18, r1 ; 24 46: f7 cf rjmp .-18 ; 0x36 <__CCP__+0x2> 48: 98 bb out 0x18, r25 ; 24 4a: f5 cf rjmp .-22 ; 0x36 <__CCP__+0x2>