本课题用一种基于单片机的数据采集系统方案,该方案根据热敏电阻随温度变化而变化的特性,采用串联分压电路。单片机采集热敏电阻的电压,通过A/D转换将模拟量电压信号转换成数字量电压信号,经过查表转换得到温度值,控制液晶屏实时显示温度值。本系统中所用到的器件是STC89C52单片机、NTC热敏电阻和LCD1602液晶显示屏。
原理图如下
单片机源程序如下:
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit rs=P0^5;
sbit rw=P0^6;
sbit e= P0^7;
sbit ADCS=P1^0;
sbit ADCLK=P1^1;
sbit ADDI=P1^2;
sbit ADDO=P1^2;
uchar code tab3[]="Low-temperature ";
uchar code tab4[]="Over-temperature";
uchar code tab5[]=" Error ";
uchar code tab6[]=" Temp:";
uchar code tab7[]=" Normal ";
uchar code tab1[]="0123456789";
uchar code tab2[]=
{79,78,77,76,75,74,73,72, //温度补偿表
71,70,69,68,67,67,66,65,
64,63,63,62,61,60,60,59,
58,58,57,56,56,55,54,54,
53,53,52,52,51,50,50,49,
49,48,48,47,47,46,46,45,
45,44,44,43,43,43,42,42,
41,41,40,40,39,39,39,38,
38,37,37,36,36,36,35,35,
34,34,34,33,33,33,32,32,
31,31,31,30,30,30,29,29,
28,28,28,27,27,27,26,26,
26,26,25,25,24,24,23,23,
23,22,22,22,21,21,21,20,
20,20,19,19,19,18,18,18,
17,17,17,16,16,16,15,15,
15,14,14,13,13,13,12,12,
12,11,11,11,10,10,10,9,
9,9,8,8,7,7,7,6,
6,6,5,5,4,4,4,3,
3,3,2,2,1,1,1,0,
0,1,1,2,2,2,3,3,
4,4,5,5,6,6,7,7,
8,8,9,9,10,10,11,11,
12,12,13,14,15,15,16,17,
17,18,19,19,20};
uint ad,ad1;
//*********延时50us*t*******************
void delay_50us(uint t)
{
uchar j,z;
for(z=t;z>0;z--)
for(j=19;j>0;j--);
}
//**************************************
//**********延时1ms*z*******************
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
//**************************************
//*********写指令****************
void write_com(uchar com1)
{
e=0;
rs=0;
rw=0;
P2=com1;
delay_50us(10);
e=1;
delay_50us(20);
e=0;
}
//**********写数据*******************
void write_data(uchar dat1)
{
e=0;
rs=1;
rw=0;
P2=dat1;
delay_50us(10);
e=1;
delay_50us(20);
e=0;
}
//*****液晶初始化*******************
void lcd1602init()
{
delay_50us(300);
write_com(0x38);
write_com(0x08);
write_com(0x01);
write_com(0x06);
write_com(0x0c);
}
//***********AD转换模块**************
uint ADC0832(uchar channel)
{
uchar i;
uint dat=0;
uchar ndat=0;
if(channel==0)channel=2;
if(channel==1)channel=3;
ADDI=1;
_nop_();
_nop_();
ADCS=0;//拉低CS端
_nop_();
_nop_();
ADCLK=1;//拉高CLK端
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成下降沿1
_nop_();
_nop_();
ADCLK=1;//拉高CLK端
ADDI=channel&0x1;
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成下降沿2
_nop_();
_nop_();
ADCLK=1;//拉高CLK端
ADDI=(channel>>1)&0x1;
_nop_();
_nop_();
ADCLK=0;//拉低CLK端,形成下降沿3
ADDI=1;//控制命令结束
_nop_();
_nop_();
dat=0;
for(i=0;i<8;i++)
{
dat|=ADDO;//收数据
ADCLK=1;
_nop_();
_nop_();
ADCLK=0;//形成一次时钟脉冲
_nop_();
_nop_();
dat<<=1;
if(i==7)dat|=ADDO;
}
for(i=0;i<8;i++)
{
ndat>>=1;
if(ADDO==1)
ndat|=0x80;
ADCLK=1;
_nop_();
_nop_();
ADCLK=0;//形成一次时钟脉冲
_nop_();
_nop_();
}
ADCS=1;//拉低CS端
ADCLK=0;//拉低CLK端
ADDO=1;//拉高数据端,回到初始状态
if(dat==ndat)
{
return(ndat);
}
else
{
return(0x00);
}
}
//**************显示模块***********************
void disp()
{
ad1=ad-29;
write_com(0x80);
if(ad<29)
{
uchar i;
for(i=0;i<16;i++)
{
write_data(tab4[i]);
}
write_com(0x80+0x40);
for(i=0;i<16;i++)
{
write_data(tab5[i]);
}
}
else if(ad>233)
{
uchar i;
for(i=0;i<16;i++)
{
write_data(tab3[i]);
}
write_com(0x80+0x40);
for(i=0;i<16;i++)
{
write_data(tab5[i]);
}
}
else if(ad>=29&&ad<=233)
{
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』