I am working on several home automation projects with PIC12F675. To maximize portability, I am using bit-shift operations to map GPIOs, like this:
// Hardware Mapping
#define pressure_pin (1<<0) // Pressue sensor output (analog input)
#define button_pin (1<<1) // Multi-function button (digital input)
#define buzzer_pin (1<<2) // NPN transitor to activate buzzer (digital output)
#define pause_pin (1<<4) // NPN transistor to pause button (digital output)
#define led_pin (1<<6) // Led (digital output)
#define PORT GPIO // Port
To set input pins ('pressure_pin" and 'button_pin'), it is necessary change TRISIO, ANSEL and ADCON0 registers. TRISIO and ANSEL changes are easily done by:
TRISIO |= (button_pin | pressure_pin); // Output pins
ANSEL = (0x50 | pressure_pin); // Fosc/16 and 'pressure_pin' as analog input`
ADCON0 must have bits 7 and 0 setted and bits 3 and 2 must receive the GPIO number used as analog input, as shown in the figure below (extracted from PIC12F675 datasheet)
So, I need ADCON0 to receive one of the following values (according to 'pressure_pin' definition):
pressure_pin | ADCON0 |
---|---|
(1<<0) |
0x81 |
(1<<1) |
0x85 |
(1<<2) |
0x89 |
(1<<3) |
0x8D |
My solution was:
ADCON0 = 0x81; // 0b10000001. ADC value right justified ; ADC turned on
ADCON0 |= (((0x82>>(pressure_pin-1))&0x1)<<2) | (((0x88>>(pressure_pin-1))&0x1)<<3);
This code snippet reproduces my solution in C language:
int main(int, char**)
{
unsigned char pressure_pin = (1<<3);
unsigned char ADCON0 = 0x81;
ADCON0 |= (((0x82>>(pressure_pin-1))&0x1)<<2) | (((0x88>>(pressure_pin-1))&0x1)<<3);
return 0;
}
Considering PIC12F675 restrictions,is there a more elegant and/or more efficient solution for this conversion?
Thanks in advance.
Maybe lookup table. No calculations needed.
const unsigned char data[] = {[1 << 0] = 0x81, [1 << 1] = 0x85, [1 << 2] = 0x89, [1 << 3] = 0x8D};
unsigned char foo(unsigned pressurepin)
{
return data[pressurepin];
}
I do not have pic compiler but similar 8 bit code generated for AVR shows that it will be much faster (and most likely smaller)