基于单片机的数字温度测量系统设计报告
- 格式:doc
- 大小:284.02 KB
- 文档页数:11
数字温度测量系统一、实习目的与要求1、目的及意义课题是数字温度测量系统的设计,利用数单片机测量温度信号,计算后在LED数码管上显示相应的温度值。
通过本次实习使学生了解和掌握工程设计所应遵循的步骤和程序,实习结束时,同学应具有以下的能力:(一)综合应用的能力。
(二)应用参考文献的能力。
(三)电路设计能力。
(四)分析问题的能力。
(五)创新能力。
2、总体设计方案本设计采用一只温度传感器DS18B20,此传感器,可以很容易直接读取被测温度值,进行转换,就可以满足设计要求。
而且此方案电路比较简单,软件设计也比较容易实现。
DS18B20可以直接温度转换为串行数字信号,供单片机进行处理,具有低功耗、商性能、抗干扰能力强等优点。
本设计采用STC89C52RC单片机实现。
单片机软件编程的自由度大,可通过编程实现各种各样的算术算法和逻辑控制。
而且体积小,硬件实现简单,安装方便。
既可以单独对多DS18B20控制工作,还可以与PC机通信。
另外STC89C52RC在工业控制上也有着广泛的应用,编程技术及外围功能电路的配合使用都很成熟。
单总线数字温度计DS1820采用基板专利技术来测量温度,温度传感器及各种数字转换电路都集成在一起,由总线串行输出测量值(9位二进制编码)。
测温范围从- 55~+125℃,还可以读内部计数器,获得较高的分辨率。
本课题主要研究如何利用DS18B20智能温度传感器实时显示温度,并将其与LED显示键盘合并使用,制成一个能实时显示温度的数字温度计。
本设计将利用DS18B20智能温度传感器和单片小系统,设计一个数字温度采集系统。
并设计一个人机接口电路:键盘采用独立按键(功能自定义),显示器采用共阴极4位LED显示。
系统的总体设计方案框图如图1所示:图1 总体设计方案框图按照系统设计功能的要求,系统主要由单片机、温度传感器DS18B20、LED数码显示管和PC机组成。
系统的硬件电路主要由复位电路、测温电路、显示电路、晶振电路组成,系统总体结构方框图如图2所示:图2 系统总体结构框图二、单片机开发板原理及各部分功能说明1、整体功能:(1)八个数码管显示(数字和字母显示)(2)20个按键:包括4个独立按键和4*4矩阵键盘(人机接口输入)(3)8个发光二极管(流水灯、指示灯、红灯)(4)USB打印口(串口通信、USB供电)(5)红外接收头(高灵敏度,可做红外遥控器解码)(6)蜂鸣器(报警和音乐播放)(7)EEPROM 24C02(数据存储)(8)DS18B20(精密温度检测)(9)晶振采用焊接方式,可以使用不同频率的晶振(10)DS1302实时时钟(11)标准1602和12864液晶接口2、开发板总原理图如图3所示:图3 开发板总原理图3、DS18B20原理图如图4所示:图4 DS18B20原理图4、数码管原理图如图5所示:图5 数码管原理图三、软件编程1、程序流程图主程序是系统的监控系统,在程序运行的过程中必须先经过初始化,包括键盘程序,中断程序,以及各个控制端口的初始化程序。
系统在初始或完成之后进入温度测量程序,实时的测量当前的温度通过电路在数码管上显示。
程序中已中断的方式来重新设定温度上下限。
根据温度传感器度温度的的测量。
按下键盘上的A 键可以设定温度上限,按下B 键可以设定温度下线,流程图如6所示。
是否图6 流程图开始系统初始化Int0=0温度上下限设定温度测量数码管显示系统温度测量四、系统调试1、系统硬件调试系统软硬件调试的目的是通过控制程序和硬件电路的配合工作,进行一些操作,以验证系统的软、硬件是否能够完成设计的功能。
调试的过程是按照系统的设计功能来划分的。
硬件电路系统测试首先是保证各个元件之间以及各个模块之间的连接正确并且接触良好,这是整个硬件电路系统正常工作的前提。
接着分别测试各个硬件模块的性能。
按照测试性质的不同可分为电压测试和信号测试两种。
电源模块主要是电压测试。
测试结果为:小型变压器输出为18v和8v的交流电,经过二极管整流桥整流,再通过稳压芯片7805和7815、7915输出的电压分别是+5v和+15v、-15v,电压测试的结果与预期目的一致,从而确保了提供给其它模块电压的稳定性。
单片机输入输出接口主要是信号测试。
根据理论计算和软件仿真的预期结果,再通过对响应的信号进行测试。
测试结果与预期结果基本一致,保证了系统按照设计的思路正常运行。
通过测试硬件电路系统中的几个测试点,确保关键的电压信号满足要求,确保系统正常运行。
2、系统软件调试系统的软件调试借助于TKS仿真器,在进行系统软件的连续调试之前要先进行软件的初调,就是要使各个子程序模块运行正确,程序的运行流程正确。
软件调试主要分以下几个步骤进行:1.功能子程序的调试功能子程序的调试包括运算、采样、数字滤波以及PID运算等子程序的调试。
在调试功能子程序时,许多参数都是未知的,要根据其所需的条件,给出假定的数据,使其运行,如果能完成预定的处理功能或与手工计算的结果相符,就说明该子程序己调试通过。
调试时由小到大,由里到外。
例如,调试PID算法子程序时,先调通其包含的各个运算子程序和参数处理子程序,然后将它们连起来进行通调。
通调时,也是假定一些数据、参数和初始条件,然后运行程序。
当运算结果与手工计算的结果相同时,该算法子程序则调试完成,反之,就要进行相应的修改。
其它子程序的调试同理。
2.程序流程的调试程序流程的调试主要是查看程序运行的步骤是否正确,在某时刻程序运行所处的位置是否正确,是否能正确运行各个中断服务程序。
在调试过程中,先将PID算法子程序屏蔽,输出可控硅导通时间用一个固定的常数代替,在各个中断服务子程序设置断点,然后运行程序,查看程序是否能运行到所有的断点,若所有断点都能运行到,则程序流程基本正确。
去掉所有断点,再一次运行程序,查看可控硅状态,从而判断程序流程正确,反之,若程序流程不正确,做相应的修改后,重新调试。
3.功能程序与算法程序的通调在完成整个程序流程的调试后,将PID等算法子程序加入,在算法子程序前或后设置断点,运行整个程序。
当程序在断点处暂停时,查看PID计算的控制量与手工计算的值是否相同。
多运行几次,若每次的结果都正确,则说明程序各个部分互相没有矛盾,反之,则说明算法子程序和其它子程序之间有影响,需要做相应的修改后重新调试四、总结及体会本文重点介绍了单片机和数字传感器DS18B20的原理和功能,并用DS18B20与STC89C52单片机组成数字温度计。
在本次设计的过程中,我发现很多的问题,虽然以前还做过这样的设计,但这次设计真的让我长进了很多,单片机设计重点就在于软件程序的设计,需要有很巧妙的程序算法,虽然以前写过几次程序,但我觉的写好一个程序并不是一件简单的事,举个例子,以前写的那几次,数据加减时,我用的都是BCD码,这一次,我全部用的都是16进制的数直接加减,显示处理时在用除法去删分,感觉效果比较好,有好多的东西,只有我们去试着做了,才能真正的掌握,只学习理论有些东西是很难理解的,更谈不上掌握。
五、附录:#include <reg52.h>#include <intrins.h>sbit DQ = P2^0; //定义DS18B20端口DQbit presence;unsigned char code LEDData[] ={0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82,0xF8, 0x80, 0x90, 0xff, 0xc6, 0x9c, 0xbf};unsigned char data temp_data[2];unsigned char data display[7] ={0x0b, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d};char code reserve[3]_at_ 0x3b; //保留0x3b开始的3个字节/**********************************************************us延时函数(8*1.085)*num**********************************************************/void Delay(unsigned int num) //延时函数{while (--num);}/********************************************************** 延时子程序**********************************************************/ void delayms(unsigned int ms){unsigned char k;while (ms--){for (k = 0; k < 114; k++);}}/********************************************************** DS18B20初始化presence=0 OK presence=1 ERROR**********************************************************/ unsigned char Init_DS18B20(void){DQ = 0; //单片机发出低电平复位信号Delay(60); //延时>480usDQ = 1; //释放数据线Delay(8); //延时>64us,等待应答presence = DQ; //接收应答信号Delay(50); //延时>400us,等待数据线出现高电平DQ = 1; //释放数据线return (presence); //返回presence信号}/********************************************************** 读一个字节数据**********************************************************/ unsigned char ReadOneChar(void){unsigned char i = 0;unsigned char dat = 0;DQ = 1;for (i = 0; i < 8; i++)//一个字节8个bit{DQ = 0; //给低脉冲信号dat >>= 1;DQ = 1; //释放总线_nop_();_nop_();if (DQ)//读总线电平状态dat |= 0x80;//最高位置1Delay(6); //延时>45usDQ = 1; //释放总线,表示此次读操作完成}return (dat); //返回所读得数据}/********************************************************** 写一个字节数据**********************************************************/ void WriteOneChar(unsigned char dat){unsigned char i = 0;for (i = 0; i < 8; i++)//一个字节8个bit{DQ = 0; //给低脉冲信号Delay(1); //延时<15usdat >>= 1; //数据右移一位,最低位移入CYDQ = CY; //写1bit数据Delay(6); //延时>45usDQ = 1; //释放总线,表示此次写操作完成}}/********************************************************** 温度数据转换子程序**********************************************************/ void Temperature_conver(){unsigned char minus = 0;// display[0]=0x0b; //显示C// display[1]=0x0c; //显示°if (temp_data[1] > 127)//温度为负值{temp_data[0] = (~temp_data[0]) + 1; //取反加一,将补码变成原码if ((~temp_data[0]) >= 0xff)temp_data[1] = (~temp_data[1]) + 1;elsetemp_data[1] = ~temp_data[1];minus = 1; //温度为负值标志}display[6] = temp_data[0] &0x0f; //取小数位数据display[2] = (display[6] *10) / 16; //保留一位小数display[6] = ((temp_data[0] &0xf0) >> 4) | ((temp_data[1] &0x0f) << 4);//取整数display[5] = display[6] / 100; //百位display[4] = (display[6] % 100) / 10; //十位display[3] = display[6] % 10; //个位if (!display[5])//高位为0,不显示{display[5] = 0x0a;if (!display[4])//次高位为0,不显示display[4] = 0x0a;}if (minus){display[5] = 0x0d; //显示负号}}/**********************************************************数码管显示子函数**********************************************************/ void ledplay(){unsigned char n, shift;shift = 0xfe; //位码初值for (n = 0; n < 6; n++)//6位数码管显示{if (n == 3)P0 = (LEDData[display[n]]) &0x7f;//加小数点显示elseP0 = LEDData[display[n]];//输出段码P1 = shift; //输出位码shift = (shift << 1) | 0x01; //修改位码delayms(1);}P1 = 0xff; //关闭显示delayms(1);}/********************************************************** 主函数**********************************************************/ void main(void){unsigned char m;P0 = 0xff;P1 = 0xff;while (1){Init_DS18B20();if (presence == 0){WriteOneChar(0xCC); //跳过ROM匹配操作WriteOneChar(0x44); //启动温度转换for (m = 0; m < 120; m++)//数码管初始化显示ledplay();//等待数据转换完成}Init_DS18B20();if (presence == 0){WriteOneChar(0xCC); //跳过ROM匹配操作WriteOneChar(0xBE); //读取温度寄存器temp_data[0] = ReadOneChar(); //温度低8位temp_data[1] = ReadOneChar(); //温度高8位Temperature_conver(); //数据转换for (m = 0; m < 120; m++)ledplay();//温度显示}}}10。