本课题用一种基于单片机的数据采集系统方案,该方案根据热敏电阻随温度变化而变化的特性,采用串联分压电路。单片机采集热敏电阻的电压,通过A/D转换将模拟量电压信号转换成数字量电压信号,经过查表转换得到温度值,控制液晶屏实时显示温度值。本系统中所用到的器件是STC89C52单片机、NTC热敏电阻和LCD1602液晶显示屏。
原理图如下
图1 总体电路原理图
单片机源程序如下:
- #include<reg52.h>
- #include<intrins.h>
- #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)
- {
- uchar i;
- for(i=0;i<16;i++)
- {
- write_data(tab7[i]);
- }
- write_com(0x80+0x40);
- for(i=0;i<7;i++)
- write_data(tab6[i]);
- if(ad>197)
- {
- write_data('-');
- write_data(tab1[(tab2[ad1])/10]);
- write_data(tab1[(tab2[ad1])%10]);
- }
- else
- {
- write_data(' ');
- write_data(tab1[tab2[ad1]/10]);
- write_data(tab1[tab2[ad1]%10]);
- }
- write_data(0xdf); //显示温度符号
- write_data('C');
- }
- }
- //***************主函数***********************
- void main()
- {
- lcd1602init(); //液晶初始化
- while(1)
- {
- ad=ADC0832(0); //读取温度值
- disp(); //调用显示程序
- }
- }
复制代码
完整的Word格式文档51黑下载地址:
基于单片机的温度测量仪的设计.docx
(495.57 KB, 下载次数: 142)
|