毕业设计(论文)--基于单片机的温度控制系统的设计与实现 下载本文

开始 发DS18B20复位命令

发跳过ROM命令 初始化 获取温度值 发读取温度命令 读取操作,CRC校验 与温度上下限比较 YES 报警 Y N 9字节完? Y CRC校验正?N 转换并显示 移入温度暂存器

结束

图21主程序流程图 图22读温度流程图

4.2开机数码管显示设置

/*****显示开机初始化等待画面*****/ Disp_init() {

P2 = 0xfe; //显示- P0 = 0xbf; Delay(200); P0 = 0xef; Delay(200); P0 = 0xfb; Delay(200); P0 = 0xfe; Delay(200);

P0 = 0xff; //关闭显示 }

给单片机上电后,18B20读取温度值需要一定的时间,故上数码管显示一定时间的“-”。

4.3 DS18B20采集温度程序

#define DQ P3_4 //定义DS18B20总线I/O

21

/*****延时子程序*****/

void Delay_DS18B20(int num) {

while(num--) ; }

/*****初始化DS18B20*****/ void Init_DS18B20(void) {

unsigned char x=0;

DQ = 1; //DQ复位

Delay_DS18B20(8); //稍做延时 DQ = 0; //单片机将DQ拉低

Delay_DS18B20(80); //精确延时,大于480us DQ = 1; //拉高总线 Delay_DS18B20(14);

x = DQ; //稍做延时后,如果x=0则初始化成功,x=1则初始化失败 Delay_DS18B20(20); }

/*****读一个字节*****/

unsigned char ReadOneChar(void) {

unsigned char i=0; unsigned char dat = 0; for (i=8;i>0;i--) {

DQ = 0; // 给脉冲信号 dat>>=1;

DQ = 1; // 给脉冲信号 if(DQ) dat|=0x80;

Delay_DS18B20(4); }

return(dat); }

/*****写一个字节*****/

void WriteOneChar(unsigned char dat) {

unsigned char i=0; for (i=8; i>0; i--) {

DQ = 0;

DQ = dat&0x01; Delay_DS18B20(5); DQ = 1;

22

dat>>=1; } }

/*****读取温度*****/

unsigned int ReadTemperature(void) {

unsigned char a=0; unsigned char b=0; unsigned int t=0; float tt=0; Init_DS18B20();

WriteOneChar(0xCC); //跳过读序号列号的操作 WriteOneChar(0x44); //启动温度转换 Init_DS18B20();

WriteOneChar(0xCC); //跳过读序号列号的操作 WriteOneChar(0xBE); //读取温度寄存器 a=ReadOneChar(); //读低8位 b=ReadOneChar(); //读高8位 t=b; t<<=8; t=t|a;

tt=t*0.0625;

t= tt*10+0.5; //放大10倍输出并四舍五入 return(t); }

/*****END*****/

读取18B20的程序,需要单片机发送读命令和写命令。 读出温度子程序的主要功能是读出RAM中的9字节,在读出时需进行CRC校验,校验有错时不进行温度数据的改写。其程序流程图如图18示

发DS18B20复位命令

发跳过ROM命令

发温度转换开始命令

结束

图23温度转换流程图

4.4读取温度程序

23

/*****读取温度*****/ void check_wendu(void) {

uint a,b,c;

c=ReadTemperature()-5; //获取温度值并减去DS18B20的温漂误差 a=c/100; //计算得到十位数字 b=c/10-a*10; //计算得到个位数字 m=c/10; //计算得到整数位

n=c-a*100-b*10; //计算得到小数位 if(m<0){m=0;n=0;} //设置温度显示上限

if(m>99){m=99;n=9;} //设置温度显示上限 }

读取的18B20程序需要转换出要显示的温度值。 4.5显示温度程序

/*****显示温度子程序*****/

Disp_Temperature() //显示温度 {

P2 =0x27; //显示C P0 = 0xfe; Delay(300);

P2 =LEDData[n]; //显示个位 P0 = 0xfb; Delay(300);

P2 =LEDData[m]; //显示十位 DIAN =0; //显示小数点 P0 = 0xef; Delay(300);

P2 =LEDData[m/10]; //显示百位 P0 = 0xbf; Delay(300);

P0 = 0xff; //关闭显示 }

/*****显示报警温度子程序*****/ Disp_alarm(uchar baojing) {

P2 =0x27; //显示C P0 = 0xfe; Delay(200);

P2 =LEDData[baojing]; //显示十位 P0 = 0xfb; Delay(200);

P2 =LEDData[baojing/10]; //显示百位 P0 = 0xef; Delay(200);

24

if(set_st==1)P2 =0x8c;

else if(set_st==2)P2 =0xa7; //上限H、下限L标示 P0 = 0xbf; Delay(200);

P0 = 0xff; //关闭显示 }

根据数码管和单片机管脚的连接顺序,算出P2口发送的数据为LEDData[]={0x28,0xeb,0x32,0xa2,0xe1,0xa4,0x24,0xea,0x20,0xa0};分别对应0 1 2 3 4 5 6 7 8 9.

5.调试过程

5.1数码管显示乱码

由于P2口的P2.0到P2.7并没有按照顺序和数码管的a,b,c,d,e,f,g相连,所以需要重新编码,因为用的是共阳数码管,所以数据端低电平亮,故

LEDData[]={0x28,0xeb,0x32,0xa2,0xe1,0xa4,0x24,0xea,0x20,0xa0}; 。 5.2 按键处理问题

由于按键采用的是机械按键,会发生抖动,所以程序中要加延时,去抖动。 5.3 DS18B20时序问题

DS18B20对于时序要求很严格,所以读写数据时要严格按照时序图上的时间来编写程序。

6.结论

本文详细讲述了系统设计方案,并给出了相关程序流程。本设计应用性比较强,可以应用在仓库温度、大棚温度、机房温度等的监控。另外,如果把本设计方案扩展为多点温度控制,加上上位机,则可以实现远程温度监控系统,将具有更大的应用价值。

本文的创新点在于详细设计了基于单片机AT89C51的温度监控系统,并且已经在硬件平台上成功运行.此系统可广泛用于温度在DSl8820测温范围之内的场合,有良好的应用前景。

25