1、 基于51单片机的温度检测设计一 基本功能利用AT89c51作为主控器和温度检测芯片DS18B20组成一个温度检测系统,实现温度的实时监控并由数码管显示。二 硬件设计图1.总设计图1. 单片机最小系统1.1选用AT89C51的引脚功能图2. AT89C51XTAL1:单芯片系统时钟的反向放大器输入端。XTAL2:系统时钟的反向放大器输出端,一般在设计上只要在XTAL1和XTAL2上接上一只石英震荡晶体系统就可以工作了,此外可以在两引脚与地之间加入20PF的小电容,可以使系统更稳定,避免噪音干扰而死机。RESET:重置引脚,高电平动作,当要对晶体重置时,只要对此引脚电平提升至高电平并保持两个及其
2、周期以上的时间便能完成系统重置的各项动作,使得内部特殊功能寄存器内容均被设成已知状态。I/O:端口3是具有内部提升电路的双向I/O端口,通过控制各个端口的高低电平来控制数码管得位选。端口2用来控制数码管的段选。1.2复位电路如图所示,当按下按键时,就能完成整个系统的复位,使得程序从新运行。 图3.复位电路1.3时钟电路时钟电路用于产生单片机工作所需要的时钟信号,单片机本身就是一个复杂的同步时序电路,为了保证同步工作方式的实现,电路应在唯一的时钟信号控制下严格地按时序进行工作。在AT89C51芯片内部有一个高增益反相放大器,其输入端为芯片引脚X1,输出端为引脚X2,在芯片的外部跨接晶体振荡器和微
3、调电容,形成反馈电路,就构成了一个稳定的自激振荡器。 此电路采用12MHz的石英晶体。 图4.时钟电路2. 数码管部分图5.数码管电路3. DS18B20部分图5.三 软件设计3.1编程语言及编程软件的选择本设计选择C语言作为编程语言。C语言虽然执行效率没有汇编语言高,但语言简洁,使用方便,灵活,运算丰富,表达化类型多样化,数据结构类型丰富,具有结构化的控制语句,程序设计自由度大,有很好的可重用性,可移植性等特点。 而汇编语言使用起来并没有这么方便。本设计选用了Keil作为编程软件,.Keil C51生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑,容易理解。在开发大型软件时更能体现高
4、级语言的优势。3.2 DS18B20工作原理DS18B20的读写时序和测温原理与DS1820相同,只是得到的温度值的位数因分辨率不同而不同,且温度转换时的延时时间由2s减为750ms。 DS18B20测温原理如图2-6-1所示。图中低温度系数晶振的振荡频率受温度影响很小,用于产生固定频率的脉冲信号送给计数器1。高温度系数晶振随温度变化其振荡率明显改变,所产生的信号作为计数器2的脉冲输入。计数器1和温度寄存器被预置在55所对应的一个基数值。计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重新开始对低温度系数
5、晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。图3中的斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正计数器1的预置值。图6: DS18B20测温原理框图3.3 数码管显示原理本设计使用的是共阴极的八段式LED数码管,每个数码管是由8个小LED灯组成,通过控制每个小LED灯的亮灭来显示不同的数字。通过控制相应I/O的电平变化就可以控制数码管的显示。四 程序#include#define uchar unsigned char#define uint unsigned int#define dx P2#defin
6、ewx P3sbit ds=P37;uint temp;float f_temp;uchar code t= 0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x80 ;void delayms(uchar xms)uint i,j;for(i=xms;i0;i-)for(j=120;j0;j-);void delayus(uint time)while(time-);void dsreset(void) /DS18B20复位,初始化函数 ds=0;delayus(103);ds=1;delayus(4);bit tempreadbit(v
7、oid)/读一位数据的函数uint x;bit dat;ds=0;x+; /起延时用ds=1;x+;x+;dat=ds;delayus(8);return(dat);uchar tempread(void) / 读一个字节的函数uchar i,j,dat;dat=0;for(i=1;i=8;i+)j=tempreadbit();dat=(j1); / 读出的数据最低位在前面return(dat);void tempwritebyte(uchar dat)/向DS18B20写一个字节数据uint i;uchar j;bit testb;for(j=1;j1;if(testb)ds=0;i+;i+
8、;ds=1;delayus(8);elseds=0;delayus(8);ds=1;i+;i+;void tempchange(void)/开始获取温度并转换dsreset();delayms(1);tempwritebyte(0xcc); /跳过读ROM指令tempwritebyte(0x44);/写温度指令指令uint get_temp()/读取寄存器中的温度数据uchar a,b;dsreset();delayms(1);tempwritebyte(0xcc); /跳过读ROM指令tempwritebyte(0xbe);/写暂存器a=tempread();/读低八位b=tempread(); / 读高八位temp=b;temp0;i-)dis_temp(get_temp();