Electronics > Microcontrollers
PIC18 interfacing with LM35
(1/1)
Udayan Sinha:
I am trying to interface an LM35 with a PIC18F4550 & get it to transmit the temperature (floating values) via UART. Since I am using a float data type to calculate & store the temperature value, how do I send it byte by byte to the TXREG (as TXREG is only a byte wide & float data type is 4 bytes wide)?
P.S. I have not written the serial() function in the code (that is where I am getting the problem :-// ). Let me know if you need the configuration bit settings & a schematic of the circuit I used.
Code I used -
void interrupt isr(void);
void adc_isr(void);
void serial(void);
void delay(unsigned int x);
float adc_output;
void main()
{
SPBRG=0x0C; //9600bps, 8-bit BRG
SPEN=1; //enable serial port
IPEN=1; //enable interrupt priority
INTCON=0xC0; //GIEL=1, GIEH=1
ADIE=1; //enable ADC interrupt
ADIP=1; //ADC interrupt is of high priority
ADON=1; //enable ADC module
TRISA=0xFF; //PORTA is input
ADCS0=1; //clock=F/8
ACQT0=1; //acquisition time=t*2
ADFM=1; //right justified
while(1)
{
GO=1; //start A/D conversion
delay(1000);
}
}
void interrupt isr(void)
{
asm("CALL _adc_isr");
}
void adc_isr(void)
{
ADIF=0;
adc_output=ADRES;
adc_output=adc_output*50;
adc_output=adc_output/1023;
adc_output=adc_output*10;
serial(); //used to transmit temp value via serial
}
void delay(unsigned int x)
{
unsigned char y;
unsigned int i;
for(i=0; i<x; i++)
{
for(y=0; y<255; y++);
}
}
c4757p:
Well.... you really shouldn't be using a float in the first place. Huge waste of memory... you can just use an integer value in units of "tenths of a degree" or whatever suits your application.
But if you really want to transmit a float byte for byte, that's easy. Make a union of a float and four bytes, and transmit the bytes:
--- Code: ---union {float f; unsigned char bytes[4];} adc_output;
// Set or read ADC output:
adc_output.f = 2.3;
// Transmit:
serial(adc_output.bytes[0]);
serial(adc_output.bytes[1]);
serial(adc_output.bytes[2]);
serial(adc_output.bytes[3]);
--- End code ---
RoadRunner:
where is the code for PIC18F458 with LM35 , although it use LCD instead off serial port , all you have to do is send the same char to serial port instead of LCD
http://www.circuitvalley.com/2011/11/nokia-3315-lcd-based-temperature-meter.html
Udayan Sinha:
--- Quote from: c4757p on December 28, 2013, 04:23:30 am ---Well.... you really shouldn't be using a float in the first place. Huge waste of memory... you can just use an integer value in units of "tenths of a degree" or whatever suits your application.
But if you really want to transmit a float byte for byte, that's easy. Make a union of a float and four bytes, and transmit the bytes:
--- Code: ---union {float f; unsigned char bytes[4];} adc_output;
// Set or read ADC output:
adc_output.f = 2.3;
// Transmit:
serial(adc_output.bytes[0]);
serial(adc_output.bytes[1]);
serial(adc_output.bytes[2]);
serial(adc_output.bytes[3]);
--- End code ---
--- End quote ---
Yeah I know I can make do with integers but the problem would have remained (I actually didn't know how to use structures & unions :palm:). Used integers finally. Thanks a lot.
So here's the final code (tested and working) :-+ -
void interrupt isr(void);
void adc_isr(void);
void serial(void);
void delay(unsigned int x);
unsigned int l;
union temperature
{
unsigned int z; //calculated output
unsigned char y[2]; //for sending via serial
}adc_output;
void main()
{
SPBRG=0x0C; //9600bps, 8-bit BRG
SPEN=1; //enable serial port
IPEN=1; //enable interrupt priority
INTCON=0xC0; //GIEL=1, GIEH=1
ADIE=1; //enable ADC interrupt
ADIP=1; //ADC interrupt is of high priority
ADON=1; //enable ADC module
TRISA=0xFF; //PORTA is input
ADCS0=1; //clock=F/8
ACQT0=1; //acquisition time=t*2
ADFM=1; //right justified
while(1)
{
GO=1; //start A/D conversion
delay(1000);
}
}
//isr
void interrupt isr(void)
{
asm("CALL _adc_isr");
}
//isr for adc
void adc_isr(void)
{
ADIF=0;
l=ADRES;
l=l*50;
l=l/1023;
l=l*10;
adc_output.z=l;
serial();
}
//function to send ADC output via serial
void serial(void)
{
TXREG=adc_output.y[1];
TXEN=1;
while(TRMT==0);
TXREG=adc_output.y[0];
while(TRMT==0);
TXREG='\n';
while(TRMT==0);
}
//delay function
void delay(unsigned int x)
{
unsigned char y;
unsigned int i;
for(i=0; i<x; i++)
{
for(y=0; y<255; y++);
}
}
P.S. - yeah i know the serial() would have looked a lot better if I had allowed input arguments to the TXREG but for now i guess this will do ;D
Navigation
[0] Message Index
Go to full version