LM35 is an analog temperature sensor built in an integrated circuit. It could work in voltage range of -55 to +150 degree Celsius. It could be supply by a DC voltage between 4 to 30 V. It analog output is the temperature data. It is a linear output, 10 mV per degree Celsius.
Using the MCU ADC, it's easy to access rather using a complex protocol like one-wire or I2C bus.
LM35 IC in TO-92 package and its pin out. |
To find the analog temperature data, we can find the digital ADC result per 10 mV. Or we can find the total voltage reading, multiplied by 100 to get the equivalent temperature in degree Celsius.
In this example, I use the ADC module to read the temperature data between -55 to 150 degree Celsius. The internal ADC module of PIC16F887 use -2.5 V to +2.5 V reference voltage, to make the device be able to read both negative and positive voltage.
I use timer 0 overflow interrupt to schedule the ADC reading for every one second.
The SSD is multiplexed with seven digits. Each digit turn on for every 5 milli seconds.
Schematic diagram. The LM35 connects to RB4/AN11 to convert the analog temperature data. The display is multiplexed with seven digits SSD. |
Source code's here:
#include<xc.h>
// PIC16F887 Configuration Bit Settings
// CONFIG1
#pragma config FOSC = XT
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config IESO = ON
#pragma config FCMEN = ON
#pragma config LVP = ON
// CONFIG2
#pragma config BOR4V = BOR40V
#pragma config WRT = OFF
/*_XTAL_FREQ use for __delay*/
#define _XTAL_FREQ 4000000
#define ssdRate 5
void driveDisplays( int analogRead){
unsigned char ssd[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,
0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
float voltage;
int _voltage;
/*Voltage Calculation total reference is
+5V with centered ground*/
voltage=(5*((float)(analogRead)/1024))-2.5;
voltage*=10;
/*Now _voltage becomes temperature,
multiply it by 100 to convert it
to the SSD data*/
_voltage=(voltage*100);
/*Check negative voltage*/
if(_voltage&0x8000){
_voltage=-_voltage;
PORTD=0x00;
PORTC=0x40;
if((_voltage<1000)|(_voltage>-1000))
PORTD=0x02;
else
PORTD=0x01;
__delay_ms(ssdRate);
}
/*Decimal Place*/
if((_voltage>=1000)|(_voltage<=-1000)){
PORTD=0x00;
PORTC=ssd[_voltage/1000];
PORTD=0x02;
__delay_ms(ssdRate);
}
PORTD=0x00;
PORTC=ssd[(_voltage%1000)/100];
if(_voltage>=100)
PORTD=0x04;
__delay_ms(ssdRate);
/*Floating point*/
PORTD=0x00;
PORTC=ssd[(_voltage%100)/10]|0x80;
PORTD=0x08;
__delay_ms(ssdRate);
PORTD=0x00;
PORTC=ssd[_voltage%10];
PORTD=0x10;
__delay_ms(ssdRate);
PORTD=0x00;
PORTC=0x63;
PORTD=0x20;
__delay_ms(ssdRate);
PORTD=0x00;
PORTC=0x39;
PORTD=0x40;
__delay_ms(ssdRate);
}
int readADC(void){
GO=1;
while(GO);
/*Return a 10-bit result*/
return (ADRESH<<8)+ADRESL;
}
void portSetup(void){
/*Analog and digital Port
Configuration*/
PORTB=0x00;
PORTC=0x00;
PORTD=0x00;
/*RB4 for analog input*/
TRISB4=1;
TRISC=0x00;
TRISD=0x00;
}
void timer0Setup(void){
/*Select FOSC*/
T0CS=0;
/*Select timer 0 Prescaler*/
PSA=0;
/*Enable Timer 0 Overflow
interrupt*/
T0IE=1;
/*Turn on Global interrupt
Control*/
GIE=1;
/*Clear interrupt flage*/
T0IF=0;
/*Clear timer 0 register*/
TMR0=0;
}
void adcSetup(void){
/*Analog and digital Port
Configuration*/
PORTB=0x00;
PORTC=0x00;
PORTD=0x00;
/*RB4 for analog input*/
TRISB4=1;
TRISC=0x00;
TRISD=0x00;
/*Select external Voltage reference
+2.5V to -2.5V*/
VCFG1=1;
VCFG0=1;
/*Result is right justify*/
ADFM=1;
/*By default is analog,
but again set it to analog*/
ANS11=1;
/*Select FRC Clock of ADC module*/
ADCON0bits.ADCS=0x03;
/*Turn on ADC Module*/
ADON=1;
/*Select AN11 RB4*/
ADCON0bits.CHS=0x0B;
/*initiate a conversion*/
GO=1;
/*Wait until GO=0 "done"*/
while(GO);
}
int adcResult;
int cnt=10;
void main(void){
portSetup();
adcSetup();
timer0Setup();
while(1){
//adcResult=readADC();
driveDisplays(adcResult);
}
}
void interrupt _ISR(void){
if(T0IF){
cnt+=1;
T0IF=0;
}
if(cnt>=15){
adcResult=readADC();
cnt=0;
}
}
A sample of simulation |
Back to main tutorials page.
No comments:
Post a Comment