Saturday, November 1, 2008

Embedded C Code

PLEASE READ THE POST ABOVE
-----------------------------------------------------------------------------------------
Below I have posted the content of the Embedded C PIC program (CC5X compiler) that drives the software inside the microcontroller. It basically sends the readings from the 2 potentiometers at the very beginning, and then stop transmitting, until it notices a change in any value. If that happens it modifies the high order byte of the conversion in order to notify the computer as to which potentiometer has changed its value.


#pragma chip PIC16F870

#include

#pragma origin 4

bit channel_is_0; //global variable to flag that first A/D channel is selected
unsigned char old_low0; //last converted low byte of channel 0
unsigned char old_high0; //last converted high byte of channel 1
unsigned char old_low1; //last converted low byte of channel 0
unsigned char old_high1; //last converted high byte of channel 1

interrupt isr(void)
{
int_save_registers
if (ADIF == 1) //if we have an interrupt from ADC conversion
{
// if channel 0 conversion and low byte value is different than the last, OR
// if channel 1 conversion and low byte value is different than the last
if (((ADRESL != old_low0) && (channel_is_0)) || ((ADRESL != old_low1) && (!channel_is_0)))
{
while (TXIF !=1 );
if (channel_is_0)
ADRESH.7 = 1; //signal the computer that this is the reading for the first channel
TXREG = ADRESH; //send last 2 bits of the conversion

while (TXIF !=1 );
TXREG = ADRESL; //send first 8 bits of the conversion
}
if (channel_is_0)
{
old_high0 = ADRESH;
old_low0 = ADRESL;
}
else
{
old_high1 = ADRESH;
old_low1 = ADRESL;
}

ADIF = 0; //clear the flag
}
if (RCIF == 1) //we have a byte received in the buffer
{
if (RCREG == 255)
ADIE = 1; //enable A/D interrupt
else
ADIE = 0; //disable A/D interrupt
}

int_restore_registers
}


void main(void)
{
//configuration of ADC
ADCON1 = 0b.1000.0100; //RIGHT Justified format, all pins of PORTA are analog inputs)
ADCON0 = 0b.0100.0001; //FOSC/8, channel 0, ADC module is now ON
//next we must enable global interrupt from ADC complete conversion
INTCON.6 = 1;
INTCON.7 = 1;
//clear ADC interrupt flag bit
ADIF = 0;
ADCON0.2 = 0;
RCIE = 1; //enable reception interrupt
//next we must configure the UART Transmit
SPBRG = 25; //this would generate a 9600 baud rate
TXSTA = 0b.0010.1100; //8 bit trabsmission, enable transmit, async mode, high baud rate
RCSTA = 0b.1001.0000; //serial port enable, 8 bit reception, enable reception
while(1)
{
if (ADCON0.2 == 0) //if ADC GO bit is not set
{
if (ADCON0.3 == 1) //if first channel is selected
{
ADCON0.3 = 0; //select the second channel
channel_is_0 = 0;
}
else
{
ADCON0.3 = 1; //else select the first channel to convert
channel_is_0 = 1;
}

ADCON0.2 = 1; //Set ADC GO bit
}
}
}