单片机温度计设计仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
设计文档:
第一章 概述
1.1 设计目的
通过对温度控制系统的设计、仿真,实现温度的信息采集,能够自由设置温度上下限报警值。
1.2 设计任务
设计一个智能温度计,并使其具有如下功能:
(1)一路室温检测,误差:≤±0.5℃;
(2)温度液晶屏显示(XX.X);
(3)配矩阵键盘;
(4)配报警指示灯及蜂鸣器;
第二章 系统选择及论证
室温测控系统要能够对室温进行实时监测,并通过与设定值的对比决策出是否应该加热或降温,使温度保持在一定的范围内。当温度超出上下极限时,要发出报警信号并切断电路,以保证设备工作性能不被破坏。
在日常生活及工农业生产中,经常要用到温度的检测及控制,传统的测温元件有热电偶和热电阻。而热电偶和热电阻测出的一般都是电压,在转换成相应的温度,需要比较多的外部硬件支持。其缺点如下:
硬件电路复杂;
软件调试复杂;
制作成本高。
本设计采用AT89C51单片机,并利用美国DALLAS半导体公司的智能温度传感器DS18B20作为检测元件,测温范围为0~50℃,最高分辨率可达0.0625℃。它具有精度高、可靠性好和能直接将模拟被测量直接转换成数字量输出,因此不需要加A/D转换器,电路简单。加上单片机软件编程灵活、自由度大,可用软件编程实现各种控制算法和逻辑控制。单片机系统可采用LCD显示室温的实际值,可用键盘输入设定值。本设计可实现显示、键盘设定、报警等功能,大大的提高了系统的智能化,也使得系统所测结果精度大大提高。DS18B20可直接读出被测温度值,而且采用三线制与单片机相连,减少了外部的硬件电路,具有低成本和易使用的特点。
2.1 系统总体框图按照系统设计功能要求,确定系统由温度数据采集、键盘设定、电源电路、主控制器、显示电路、超限报警6个模块组成。总体结构框图如图2-1所示: 图2-1 系统总体结构框图
第三章 硬件电路的设计3.1单片机最小系统 本设计采用的是AT89C51芯片作为核心部件。 单片机最小系统组成:XTAL1(19 脚)和XTAL2(18 脚)为振荡器输入输出端口,外接11.0592MHz晶振。RST/Vpd(9 脚)为复位输入端口,外接电阻电容组成的复位电路。VCC(40 脚)和VSS(20 脚)为供电端口,分别接+5V电源的正负端。P0~P3 为可编程通用I/O 脚,其功能用途由软件编程定义。 单片机最小系统如图3-1所示。 3.2温度数据采集电路本设计的温度采集电路主要由DS18B20组成,因为该芯片是集成芯片,故可不加其他电路,直接将芯片数据输出口接到CPUI/O口上。温度数据采集电路如图3-2所示。 图3.1 单片机最小系统
图3.2 温度数据采集电路 3.3键盘设定 图3.3 键盘电路 3.4 显示电路 显示电路如图3-4所示 图3.4 显示电路 3.5 温度报警 报警电路利用P1.5进行控制有源蜂鸣器,当温度超过设定的上下限温度值时,开始报警。如图3-5所示。 图3.5 报警电路 3.7硬件原理总图硬件原理总图如图3-6所示。 图3-6 硬件原理总图 第四章 系统软件的设计4.1各部分程序设计及其子程序流程图系统程序主要包括主程序,读出温度子程序,温度转换命令子程序,计算温度子程序,报警子程序和显示数据刷新子程序等。 - 主程序:主程序的主要功能是负责温度的实时显示,读出并处理DS18B20的测量温度值。温度测量每5s进行一次。主程序流程图如图4.1所示。
图4-1 主程序流程图 - 读出温度子程序:读出温度子程的主要功能是读出RAM中的9字节。在读出时须进行CRC校验,校验有错时不能进行温度数据的改写。读出温度子程序流程图如图4.2所示。
图4-2 温度子程序流程图 温度转换命令子程序:温度转换命令子程序主要是发温度转换开始命令。当采用12位分辨率时,转换时间约为750 ms。在本程序设计中,采用5s显示程序延时法等待转换的完成。温度转换命令子程序流程图如图4.3所示。 图4-3 温度转换子程序流程图 计算温度子程序:计算温度子程序将RAM中读取的值进行十进制的转换运算,并进行温度值正负的判断。其流程图如图4.4所示。 图4-4 计算温度子程序流程图 显示数据刷新子程序:显示数据刷新子程序主要是对显示缓冲器中的显示数据进行刷新操作,当最高数据显示位为0时,将符号显示位移入下一位。显示数据刷新子程序流程图如图4.5所示。 图4-5 显示数据刷新子程序流程图 4.2 温度采集DS18B20部分程序设计分析由于DS18B20单线通信功能是分时完成的,它有严格的时隙概念,因此读写时序很重要。系统对DS18B20的一般操作过程为:初始化DS18B20(发复位脉冲)→发ROM功能命令→发存储器操作命令→处理数据。 ①初始化:单片机将数据线拉低480-960us后释放,等待15-60us,单总线器件即可输出一个持续时间为60-240us的低电平(应答信号),单片机收到此应答后即可进行后续操作; ②写时序:当主机将数据线的电平从高拉到低时,形成写时序,有写0和写1两种时序。写时序开始后,DS18B20在15-60us期间从数据线上采样,如果采样到低电平,则向DS18B20写0,否则写1,两个独立的时序之间至少需要1us的回复时间按(拉高总线电平); ③读时序:当主机从DS18B20读取数据时,产生读时序,此时,主机将数据线的电平从高拉到低使读时序被初始化。如果此后5s内,主机在总线上采样到低电平,则从DS18B20读0,否则读1。 总结 本系统是以单片机为核心部件的水温控制系统,利用软件编程,最终实现各项设计要求。在设计过程中,我们对设计中用到的相关软件有基本简单的了解及简单使用,同时对AT89S51单片机以及DS18B20温度传感器有了更深的认识。做设计的时候,不仅要有足够的知识储备,而且也需要耐心和细心,很多时候小失误就会导致电路不通。只有做到细心检查,才能减少出错的机率,只有不断发现问题,并自己寻求解决问题的方法,正确解决问题,我们才能从中得到成长,提升自己的能力。 从最初拿到文档项目时的毫无头绪,到开始着手搜集资料,再到后来一起整理资料,到最后商量确定好最后的设计,我们一步一步的做下来。这期间,也曾有过一些分歧,也有过小争吵,但最后两个人还是达成一致,齐心完成了设计。不论是个人还是一个小组、一个团队,做任何事都少不了身边人的帮助,在此,我们也衷心感谢老师的耐心指导和同学的热心帮忙。
单片机源程序如下:
- #include <reg51.h>
- #include <intrins.h> //_nop_();延时函数用
- #define Disdata P0 //段码输出口
- #define discan P2 //扫描口
- #define uchar unsigned char
- #define uint unsigned int
- uint h;
- uint temp;
- sbit DQ=P3^7; //共阴数码管
- uchar ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,
- 0x06,0x06,0x07,0x08,0x08,0x09,0x09};
- uchar xianshi1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
- //不带小数点的0-9编码
- uchar scan_con[4]={0xf7,0xfB,0xfD,0xfe}; //列扫描控制字
- uchar temp_data[2]={0x00,0x00}; //读出温度暂放
- uchar display[5]={0x00,0x00,0x00,0x00,0x00};
- //显示单元数据,共4个数据和一个运算暂用
- void delay(uint t)
- {
- for (;t>0;t--);
- }
- void scan(void)
- {
- char k;
- for(k=0;k<4;k++) //4位LED扫描控制
- {
- Disdata=xianshi1[display[k]]; //数据显示
- if (k==1)
- Disdata=xianshi1[display[k]]|0x80; //小数点显示
- discan=scan_con[k]; //位选
- delay(90);
- discan=0xff;
- }
- }
- /****************DS18B20复位函数************************/
- void ow_reset(void)
- {
- char presence=1;
- while(presence)
- {
- while(presence)
- {
- DQ=1;_nop_();_nop_();//从高拉倒低
- DQ=0;
- delay(50); //550 us
- DQ=1;
- delay(6); //66 us
- presence=DQ; //presence=0 复位成功,继续下一步
- }
- delay(45); //延时500 us
- presence=~DQ;
- }
- DQ=1; //拉高电平
- }
- /*向DS18B20写入一个字节*/
- void write_byte(uchar val)
- {
- uchar i;
- for(i=8;i>0;i--)
- {
- DQ=1;_nop_();_nop_(); //从高拉倒低
- DQ=0;_nop_();_nop_();_nop_();_nop_(); //5 us
- DQ=val&0x01; //最低位移出
- delay(6); //66 us
- val=val/2; //右移1位
- }
- DQ=1;
- delay(1);
- }
- /*从DS18B20读出一个字节*/
- uchar read_byte(void)
- {
- uchar i;
- uchar value=0;
- for(i=8;i>0;i--)
- {
- DQ=1;_nop_();_nop_();
- value>>=1;
- DQ=0;_nop_();_nop_();_nop_();_nop_(); //4 us
- DQ=1;_nop_();_nop_();_nop_();_nop_(); //4 us
- if(DQ)value|=0x80;
- delay(6); //66 us
- }
- DQ=1;
- return(value);
- }
- uint read_temp(void)
- {
- ow_reset(); //总线复位
- delay(200);
- write_byte(0xcc); //发命令
- write_byte(0x44); //发转换命令
- ow_reset();
- delay(1);
- write_byte(0xcc); //发命令
- write_byte(0xbe);
- temp_data[0]=read_byte(); //读温度值的第字节
- temp_data[1]=read_byte(); //读温度值的高字节
- temp=temp_data[1];
- temp<<=8;
- temp=temp|temp_data[0]; // 两字节合成一个整型变量。
- return temp; //返回温度值
- }
- void work_temp(uint tem)
- {
- uchar n=0;
- if(tem>6348) // 温度值正负判断
- {tem=65536-tem;n=1;} // 负温度求补码,标志位置1
- display[4]=tem&0x0f; // 取小数部分的值
- display[0]=ditab[display[4]]; // 存入小数部分显示值
- display[4]=tem>>4; // 取中间八位,即整数部分的值
- display[3]=display[4]/100; // 取百位数据暂存
- display[1]=display[4]%100; // 取后两位数据暂存
- display[2]=display[1]/10; // 取十位数据暂存
- display[1]=display[1]%10;
- if(!display[3])
- {
- display[3]=0x00; //最高位为0时不显示
- if(!display[2])
- {
- display[2]=0x3f; //次高位为0时不显示
- }
- }
- if(n=1){ display[3]=0x40;} //负温度时最高位显示"-"
- }
- void main(void)
- {
- Disdata=0x00; //初始化端口
- discan=0x00;
- for(h=0;h<4;h++) //开机显示"0000"
- {display[h]=0;}
- ow_reset(); //开机先转换一次
- write_byte(0xcc); //Skip ROM
- write_byte(0x44); //发转换命令
- for(h=0;h<100;h++) //开机显示"0000"
- {scan();}
- while(1)</font>
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
本人初学,仅供参考,存在错误和不足之处,请大家回帖多多指教,切勿照搬,文件下载:
求指导如何完善:
单片机课设(张明倩).rar
(352.21 KB, 下载次数: 205)
|