基于单片机温度传感器课程设计报告书.doc
单片机课程设计所在院系专业名称班级题目指导教师成员完成时间一、设计任务及要求:设计任务:基于数字温度传感器的数字温度计的设计。要 求: 1.利用数字温度传感器DS18B20与单片机结合来测量温度;2.利用数字温度传感器DS18B20测量温度信号,计算后在LCD数码管上显示相应的温度值。其温度测量围为55125,精确到0.5;3.数字温度计所测量的温度采用数字显示,控制器使用单片机AT89C51,测温传感器使用DS18B20;4.用蜂鸣器设置警告音。指导教师签名:20XX月28日二、指导教师评语:指导教师签名:2012 年12月 28日 三、成绩 验收盖章 20XX12月28 日基于数字温度传感器的数字温度计的设计1.芯片DS18B20的说明美国Dallas 半导体公司的数字化温度传感器DS1820 是世界上第一片支持 "一线总线"接口的温度传感器,在其部使用了在板ON-B0ARD专利技术。全部传感元件及转换电路集成在形如一只三极管的集成电路。一线总线独特而且经济的特点,使用户可轻松地组建传感器网络,为测量系统的构建引入全新概念。现在,新一代的DS18B20 体积更小、更经济、更灵活。使你可以充分发挥"一线总线"的优点。DS18B20 的主要特性1.1芯片DS18B20的特点1适应电压围更宽,电压围:3.05.5V,在寄生电源方式下可由数据线供电2独特的单线接口方式,DS18B20 在与微处理器连接时仅需要一条口线即可实现微处理与DS18B20 的双向通讯3DS18B20 支持多点组网功能,多个DS18B20 可以并联在唯一的三线上,实现组网多点测温4DS18B20 在使用中不需要任何外围元件,全部传感元件及转换电路集成在形如一只三极管的集成电路5温围55125,在-10+85时精度为±0.56可编程的分辨率为912 位,对应的可分辨温度分别为0.5、0.25、0.125和0.0625,可以实现高精度测温。7在9位分辨率最多在93.75ms把温度转换成数字,12 位分辨率是最多可在750ms将温度转换成数字,速度更快。8温度测试结果直接转换成数字温度信号,以"一线总线"串行传输给CPU,同事科传送SRC检验码,菊友极强的抗干扰校正能力。9负压特性:电源极性接反时芯片不会因发热而烧毁,但不会正常工作。2. 液晶显示器LM016L的说明接口信号说明:编号符号引脚说明编号符号引脚说明1VSS电源地9D2Data I/02VDD电源正极10D3Data I/03VL液晶显示偏压信号11D4Data I/04RS数据/命令选择端12D5Data I/05R/W读/写选择端13D6Data I/06E使能信号14D7Data I/07D0Data I/015BLA背光级正极8D1Data I/016BLK背光级负极下表为控制命令表:序号指令RSR/WD7D6D5D4D3D2D1D01清显示00000000012光标返回000000001*3置输入模式00000001I/DS4显示开/关控制0000001DCB5光标或字符移位000001S/CR/L*6置功能00001DLNF*7置字符发生存贮器地址0001字符发生存贮器地址8置数据存贮器地址001显示数据存贮器地址9读忙标志或地址01BF计数器地址10写数到CGRAM或DDRAM10要写的数据容11从CGRAM或DDRAM读数11读出的数据容 l 液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符,图一是016L的部显址。图一液晶显示简介液晶显示原理 液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,有电就有显示,这样即可以显示出图形。液晶显示器具有厚度薄、适用于大规模集成电路直接驱动、易于实现全彩色显示的特点,目前已经被广泛应用在便携式电脑、数字摄像机、PDA移动通信工具等众多领域。液晶显示器的分类 液晶显示的分类方法有很多种,通常可按其显示方式分为段式、字符式、点阵式等。除了黑白显示外,液晶显示器还有多灰度有彩色显示等。如果根据驱动方式来分,可以分为静态驱动Static、单纯矩阵驱动Simple Matrix和主动矩阵驱动Active Matrix三种。字符的显示 用LCD显示一个字符时比较复杂,因为一个字符由6×8或8×8点阵组成,既要找到和显示屏幕上某几个位置对应的显示RAM区的8字节,还要使每字节的不同位为"1",其它的为"0",为"1"的点亮,为"0"的不亮。这样一来就组成某个字符。但由于带字符发生器的控制器来说,显示字符就比较简单了,可以让控制器工作在文本方式,根据在LCD上开始显示的行列号及每行的列数找出显示RAM对应的地址,设立光标,在此送上该字符对应的代码即可。3. 总体电路流程图时钟振荡主控电路LCD显示温度传感器开始DS18B20的初始化跳过读序列号的操作启动温度转换读取温度寄存器跳过读序列号的操作DS18B20的初始化结束4. 总体电路设计LCD与AT89C51的连接,如图一所示将LCD的D0D7引脚分别与单片机的P0.1P0.7相连,使LCD能接受来自单片机的信号。电路如图二所示如图可见,电路主要是由AT89C51芯片和LM016L和蜂鸣器构成了主要电路。开关的控制,可调整温度的围。5.系统程序设计程序清单:#include <AT89X51.H>#include <intrins.h>#include<absacc.h>#define uint unsigned int#define unchar unsigned charunchar templ,temph,i,y,z,n;unchar a,b;/LCD的变量unchar sign=0;/标志变量bit k;/判断正负变量sbit dq=P35;sbit rs=P20;/LCD显示的定义取值sbit rw=P21;sbit e=P22;sbit bf=P07;sbit DQ=P25;/键盘定义sbit read=P30;sbit incH=P32;sbit desH=P33;sbit reset=P34;/蜂鸣器sbit BUZZER=P26;float t4,t5,t6,t7,tt;/温度转换的变量uint tp;unchar temperature,Htemp,Ltemp;unchar D1,D2,D3;uint D4,D5,D6,D9,D7,D8;unchar code dis1="0123456789"unchar code dis2="temp:"unchar code dis3="WARN"unchar code dis4="Htemp:"unchar code dis5="working"unchar code dis6="Ltemp:"bit flag_1820_1;bit flag_1820_2;void delay_ms<unsigned char time>void ledshow<void>void keypress<void>void init<void>void gettemp<>void init1820<void>void write1820<unchar>unsigned char read1820<void>void delay_us<unchar>void delay3<unchar>/* 延时*/void delay<uint t>uint i;while<t-> for<i=0;i<125;i+> /LCD显示函数void delay1<unchar time>unchar n;n=0;while<n<time>n+;return;void delay3<unchar x> for<y=x;y>0;y->for<z=x;z>0;z->unchar testBF<> bit result;rs=0;rw=1;e=1;_nop_<>_nop_<>_nop_<>_nop_<>result=bf;e=0;return result;void writecmd<unchar ZL> while<testBF<>=1>rs=0;rw=0;e=0;_nop_<>_nop_<>P0=ZL;e=1;_nop_<>_nop_<>_nop_<>_nop_<>e=0;void pos<unchar pos>writecmd<pos|0x80>void writedate<unchar date>while<testBF<>=1>rs=1;rw=0;e=0;_nop_<>_nop_<>P0=date;e=1;_nop_<>_nop_<>_nop_<>_nop_<>e=0;void init<>delay3<20>writecmd<0x38>delay3<30>writecmd<0x0d>delay3<30>writecmd<0x06>delay3<30>writecmd<0x01>delay3<30>/键盘程序/主程序void main<void> TMOD=0x01; TH0=50000/256; TL0=50000%256; Htemp=124;Ltemp=-24; P3=0xFF; init<>if<sign=0> EA=1;TR0=1;ET0=1; EX0=0; /关闭外部中断0 EX1=0; /关闭外部中断1 while<1> if<read=0> delay3<2000> if<read=0> sign+; if<sign=1> BUZZER=1; /关闭蜂鸣器 EX0=1; /开启外部中断0 EX1=1; /开启外部中断1 init<> pos<0> for<i=0;i<6;> writedate<dis4i>i+; D6=Htemp%10; D7=Htemp%100/10; D8=Htemp/100;pos<0x6>writedate<dis1D8>writedate<dis1D7> if<sign=2> BUZZER=1; /关闭蜂鸣器 EX0=1; /开启外部中断0 EX1=1; /开启外部中断1 init<> pos<0> for<i=0;i<6;> writedate<dis6i>i+; D6=Htemp%10; D7=Htemp%100/10; D8=Htemp/100;pos<0x6>writedate<dis1D8>writedate<dis1D7>writedate<dis1D6> if<sign>2> sign=0;/中断程序void int0<void> interrupt 0EX0=0; /关外部中断0if<desH=0&&sign=1> Htemp-; if<Htemp<Ltemp> Htemp=Ltemp;else if<desH=0&&sign=2> Ltemp-;/*外部中断1服务程序*/void int1<void> interrupt 2EX1=0; /关外部中断1if<incH=0&&sign=1> Htemp+;else if<incH=0&&sign=2> Ltemp+; if<Ltemp>Htemp> Ltemp=Htemp; /定时器T0服务程序void isr_t0<void> interrupt 1TH0=50000/256;TL0=50000%256;TMOD=0x10;TH1=50000/256;TL1=50000%256;gettemp<>delay<50>if <tp<Htemp> BUZZER=1; pos<0x04>for<i=0;i<7;>writedate<dis5i>i+;pos<0x40>for<i=0;i<5;>writedate<dis2i>i+;D1=<unchar><tp%10>D2=<unchar><tp%100/10>D3=<unchar><tp/100>D4=<uint><tt*10>D5=<<uint><tt*100>>%10;if<k=1>pos<0x46> writedate<'-'> else pos<0x46> writedate<>pos<0x47>writedate<dis1D3>writedate<dis1D2>writedate<dis1D1>writedate<'.'>writedate<dis1D4>writedate<dis1D5>writedate<0xdf>writedate<'C'> else init<> pos<0x04>for<i=0;i<4;> writedate<dis3i> i+; BUZZER=0;/DS18B20读取温度void gettemp<> init1820<> write1820<0xcc> write1820<0x44> init1820<> write1820<0xcc> write1820<0xbe> templ=read1820<>/低8位其中的第四位是小数点后的 temph=read1820<>/高8位其中前五位是符号值> z=temph;/把符号位留下判断正负k=<bit><z>>7>if<k=1> /负数就取反加一 templ=templ; templ=templ+1; temph=temph; else templ=templ; temph=temph; n=templ; y=n&0x01;t7=y*0.0625; n>>=1; y=n&0x01;/小数点最后的数 t4=y* 0.125; n>>=1; y=n&0x01; t5=y* 0.25; n>>=1; y=n&0x01; t6=y*0.5;tt=t4+t5+t6+t7; init1820<> tp=temph*256+templ; temperature=tp; tp=tp>>4;/1820初始化void init1820<> DQ = 1; _nop_<> DQ = 0; delay_us<125> /延时510us, delay_us<125> DQ = 1; delay_us<15> while<DQ> _nop_<> delay_us<60> DQ = 1; /*write*void write1820<unchar a> unchar i; for<i=0;i<8;i+> if<a & 0x01> /低位在前; DQ = 0; _nop_<>_nop_<>_nop_<> DQ = 1; else DQ = 0; _nop_<>_nop_<>_nop_<> delay_us<30> DQ = 1; _nop_<> a >>= 1; /*read*unsigned char read1820<void>unsigned char i;unsigned char tmp=0; DQ = 1; _nop_<> for<i=0;i<8;i+> tmp >>= 1; DQ = 0; _nop_<> DQ = 1; delay_us<2> _nop_<> if<DQ> tmp |= 0x80; delay_us<30> DQ = 1; _nop_<> return tmp; void delay_us<unchar a>while<-a>void delay_ms<unchar a> unchar i,j;for<i=0;i<a;i+>for<j=0;j<200;j+>_nop_<>_nop_<> 6.总结1在编写程序的过程中,遇到一些C语言的语法问题,需要查找资料或者咨询同学才能完成。2在连接电路图时会时常将接口的位置混淆,记清每个接口的位置十分重要。3蜂鸣器偶尔一直响,偶尔一直不响。需用一个三极管解决。参考文献51单片机C语言教程 郭天祥 电子工业18 / 18