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

There was an error while thanking
Thanking...
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod