资源描述
武汉理工大学《单片机原理与接口技术》课程设计说明书
附件1:
学 号:
0121218700312
课 程 设 计
题 目
数字式温度计
学 院
物流工程学院
专 业
物流工程
班 级
姓 名
指导教师
2015
年
1
月
18
日
附件2:
课程设计任务书
学生姓名: 专业班级:
指导教师: 工作单位:
题 目: 数字式温度计设计
初始条件:
1、设计与仿真软件:Keil uVision 和Proteus
要求完成的主要任务: (包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)
1.18B20 设计一款能够显示当前温度值的温度计;
2. 切换按钮可以切换华氏度和摄氏度显示;
3.其他功能
时间安排:
2015年1月4 - 5日 选择题目,布置任务
2015年1月6 — 8日 功能分析,硬件设计及修改
2015年1月9 -13日 软件设计与编程
2015年1月14-18日 调试并修改硬件组成
2015年1月19—20日 编写任务说明书
2015年1月21—22日 确认提交版、答辩
指导教师签名: 年 月 日
系主任(或责任教师)签名: 年 月 日
附件6:
本科生课程设计成绩评定表
姓 名
性 别
专业、班级
课程设计题目: 数字式温度计
课程设计答辩或质疑记录:
1. Respack—8是什么?作用是什么?
答:Respack—8是排阻,作上拉电阻,使得单片机P0口具备I/O能力
2. 如何实现复位?
答:接通复位回路,按下复位按钮,保持两个机器周期以上的时间,即可实现复位。
3. DS18B20是什么芯片?有何特点
答:DS18B20是一种常用的温度传感器,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。测温范围为—55℃~+125℃,固有测温误差为1℃。
成绩评定依据:
1。硬件电路和软件程序的正确性
2。设计说明书的规范性和完整性
3.答辩情况
4。功能实现的难易程度
最终评定成绩(以优、良、中、及格、不及格评定)
指导教师签字:
年 月 日
目 录
1 设计任务2
2设计方案3
2.1 任务分析3
2.2 方案设计3
3系统硬件设计5
3.1时钟电路设计5
3.2复位电路设计5
3.3 1602控制电路5
3.4 DS18B20通信电路,开关电路设计6
3.5系统原理图 7
4系统软件设计8
4.1 1ms定时8
4.2 DS18B20初始化程序8
4.3对DS1802写一个字节的数据8
4.4 1602的操作程序 8
4.5温度测算及转换程序10
5仿真与性能分析11
5.1系统仿真过程11
5.2系统性能分析11
6.小结与展望13
参考文献14
附录1 元件清单15
附录2 系统程序16
数字式温度计的设计
摘要
温度是一种最基本的环境参数,人民的生活、生产与环境的温度息息相关。 在工业生产过程中需要实时测量温度,在农业生产中也离不开温度的测量,因此 研究温度的测量方法和装置也有重要的意义。
本文将介绍智能集成温度传感器 DS18B20 的结构特征及控制方法,并以此为传感器 DS18B20 和 AT89C52 单片机为控制器构成的温度测量装置的工作原理做了详细的介绍。该产品适用于人民的日常生活和工、农业生产,用于温度测量.
关键词
AT89C52;DS18B20;LM016L;数字;温度计。
1设计任务
1.1设计任务
(1)用 DS18B20 设计一款能够显示当前温度值的温度计;
(2)通过切换按钮可以切换华氏度和摄氏度显示;
(3)其他功能(创新部分)
设计例图如图1。1所示
图1。1 设计例图
1.2基本要求
(1)用 DS18B20 设计一款能够显示当前温度值的温度计;
(2)通过切换按钮可以切换华氏度和摄氏度显示;
1。3拓展要求
选作:实现测量多组的温度,都可以显示出来.
2设计方案
2.1任务分析
数字式温度传感器就是使用单片机来实现与 DS18B20 温度传感器的通信,实现温度计 的功能。温度由单片机计算出后,显示在 1602 液晶上,并且可以通过转换按钮实现显示 华氏温度和摄氏温度的转换。
2。2方案设计
2。2.1硬件方案
根据设计的要求可知,系统的硬件原理框图如图 2.1 所示.
按 键
1602液晶
单片机
DS18B20
图2.1 硬件原理框图
单片机选用AT89C51,设计时无需外接程序存储器,为设计和调试带来极大的方便。DS18B20 与单片机的通信是通过 1—wire 总线方式。我将该通信线路与单片机 P3。2
口连接,从该口对 DS18B20 进行读写操作。另外,将一个按键开关与 P3。7 口连接,进行摄氏华氏温度的换算。
2。2.2软件方案
根据设计要求,程序框图如图 2.2 所示。软件可由汇编语言完成,也可由 C 语言完成,我选择的C语言。 软件设计可以分为以下几个功能模块:
(1)主程序:初始化及键盘.
(2)延时子程序:由_nop_()及 while 执行空循环来实现。用于通信时序。
(3)LM160LCD液晶初始化及读写 RAM 子程序:初始化 1602 液晶,读写 1602RAM.
(4)18B20 初始化及读写 RAM 程序:初始化 18B20 以及读写 18B20 片内 RAM 的程序. 键盘扫描程序模块:扫描键盘有无按键按下。
开始
初始化
启动温度转换
读取温度数值
摄
氏
或
华
氏
计算数据
更新温度显示
判断键值
图2.2 程序框图
3。系统硬件设计
3.1时钟电路设计
如图3。1所示,采用内部时钟产生方式,在XTAL1和XTAL2两端跨接晶体或陶瓷振荡器,与内部反相器构成稳定的自击震荡。其发出的时钟脉冲直接送入片内定时控制部件.我采用的是12MHZ的晶振。
图3.1单片机时钟电路
3。2复位电路设计
如图3。2所示,采用上电+按钮电平复位方式,当按下按钮时,RST 管脚高电平触发。 为保证复位可靠,RC 时间常数应大于两个机器周期,电容取30pF,电阻10k欧.
3.2单片机复位电路
3.3 1602 控制电路
如图3。3所示,通过上拉电阻使得单片机P0口具备I/O能力,P0与1602的数据端口依次连接.RS、RW、EN分别连接单片机P1.0,P1。1,P1.2口。上拉电阻1口为+5v。
图3。3控制电路
3.4 DS18B20 通信电路,开关电路设计
如图3.4所示,由DS18B20的数据通信端口与P3。2连接,开关电路与单片机P3.7口
连接,按下开关即可将摄氏温度转化成华氏温度并显示在LCD上,保持闭合状态则可以实时显示华氏温度。
图3.4 DS18B20通信电路,开关电路电路
3。5系统电路图
如图3。5所示。
图3。5 系统电路图
4系统软件设计
4。1 1ms定时
在这里我们并不需要太精确的定时,故我采用的是执行无实际意义的语句的方法定时。采用了2层while语句,内层为执行while空循环110次,通过keil软件的调试可以发现, 该空循环可延时约1ms,这样只用确定外层while执行的次数,就能实现大约毫秒级的延时。
4。2 1820初始化程序
18b20的复位时序图如图4.1所示。 单片机io口必须要维持400~960us的低电平,以显示单片机现在接管总线,然后释放总线至少15us(即给单片机IO口给高电平),此后,18b20会拉低总线约200us,并释放总线, 此时代表ds18b20复位成功。按照对应时序用软件给单片机IO口赋值即可。
图4。1 18b20复位时序图
4。3 对18B20 写一个字节数据
18b20写操作时,先必须保证总线是高电平。写 0 时,拉低总线至少 60us,ds18b20 会在 15~60us 完成读入 0。然后释放总线至少1us,完成一次写 1 操作。写 1 时,也是先拉低总线,然后必须在 15us 之内拉高总线超过 60us,在 15us 之后 ds18b20会完成读入 1。如此就完成了一次写 1 抄作. 将一字节数据的低位先写入,完成一次字节的写入。读出时也是先读出的是低位数据.
4.4 1602的操作程
1602操作指令如下:
读状态:输入:RS=L,RW=H,E=H 输出:D0-D7=状态字
写指令:输入:RS=L,RW=L,D0—D7=指令码,E=高脉冲 输出:无
读数据:输入:RS=H,RW=H,E=H 输出:D0—D7=数据
写数据: 输入:RS=H,RW=L,D0—D7=数据,E=高脉冲 输出:无
这使得1602显示字符的程序流程图如图4。2所示.
开始
忙
检测不忙信号
不忙
设置显示模式等
写指令,给出字符的ram地址
写出数据库,给出字符的ASCII码
图4。2 1602显示字符流程图
先写指令 55H,判断 1602 是否忙。写指令 38H 设置显示模式,写指令 06H,0CH 设置光标及数据地址指针移动方向。总的方法就是,在数据地址指针指向的 RAM 内写字符
的ASCII 码,该地址对应的 lcd 块就会显示相应的字符。数据地址映射图如图 4.3。
图4。3 1602数字地址映射图
4。5 温度测算及转换程序
DS18B20 的在完成温度测量之后会发送 11 位 2 进制数,以表征温度的绝对值前 5位为温度的符号位,见图 4。4 所示.
图4。4 DS18B20温度输出
软件的思路为,先将 2 个八位数据存在一个无符号整形的变量中,再将 2 个八位数据 拼接在一起存放在一个有符号的 16 位整形变量中。然后将其后 4 位分离出来,这是小数 部分。前 12 位要判断最高 5 位是否为 1。若为 1,代表为温度为负值,如此低 7 位就是反码,取反再加 1 求得温度的绝对值;若为 0,代表温度是正值,读出低 7 位的值就是温度 的绝对值。如此一来就得出了摄氏温度值。
华氏温度摄氏温度转换关系式:华氏度 = 32 + 摄氏度 ×1。8
5仿真与性能分析
5.1系统仿真过程
1。利用 protues 平台做仿真。
2。搭建如图 5.1 所示电路,配置电源端子为设计值,运行.
3。通过图上每个 IO 口的颜色(红色表示高电平,蓝色表示低电平)判断程序的执行是否符合预期。
4.调整 DS18B20 上面的温度按钮,看看温度显示能否跟随 DS18B20 处温度变化而变化。
图5。1 系统仿真图
5。2系统性能分析
当系统上电后,LCD大约1s后显示DS18B20所设温度,并保持恒定不会变化,如图5。2所示。当按下切换按钮后,LCD上排即对此时温度进行换算,显示当前摄氏温度所对应的华氏温度。调整DS18B20温度后,LCD温度随即更改,再次按下切换按钮,即可显示当前新温度所对应的华氏温度,如图5。3所示。如果将切换按钮处于长期闭合状态,则可以同时显示摄氏温度及华氏温度,当调节DS18B20温度后,两排温度都会发生变化。
图5。2系统仿真结果
图5。3系统仿真图
6小结与展望
这次单片机课程设计我受益良多,不仅学会了两款软件:Keil uVision 和Proteus的使用方法,也学习到了许多硬件电路设计的基本准则和软件编制的好习惯。为了达到设计功能要求,我接触了自己以前从没接触过的DS18B20温度传感器和LCD1602液晶芯片,虽然在有限的设计时间内没有把这两个芯片的应用原理研究透彻,但可以实现基本的应用编程。设计的这几天时间里,我阅读了单片机电路设计与仿真的相关资料,虽然是特别枯燥的,但收获到了新知识是值得高兴的,比如了解了温度传感器 DS18B20 的功能,如何编写单片机AT89C51的程序来实现数码管直接显示环境温度等等知识,与此同时还巩固了以前学过的知识。最值得一说的收获我觉得还是通过课程设计我能利用硬件和软件的结合,完成一个产品的设计和制作!
在这个课程设计完成的过程中,我感觉是对单片机课程的重温以及相关知识的拓展,让我知道如何有计划、有条理地去完成一项任务.同时,让我觉得自己所掌握的只是其实是很少量的,完全谈不上专业人才.这对自己大学有限的未来的发展是一个启发。
我做的这个温度传感器设计并不是最佳的,还有很多功能等待去完善和开发,比如如何提高温度测量的范围,如何设置温度警告等等.
参考文献:
[1]李全利.单片机原理及接口技术[M]。2版。北京:高等教育出版社,2009。
[2]杨居义.单片机课程设计指导[M].北京:清华大学出版社,2009.
[3]阎石.数字电子技术基础[M]。3版.北京:电子工业出版社,2009.
[4]马忠梅,刘滨。单片机 C 语言 Windows 环境编程宝典[M]。北京:北京航空航天大学出版社,2003。
[5]欧阳文.ATMEL89系列单片机的原理与开发实践[M].北京:中国电力大学出版社,2006。
[6]杨欣,王玉凤,刘湘黔,张延强。51单片机应用从零开始[M].北京:清华大学出版社,2008.
附录1 元件清单
如表1所示。
表1 数字式温度计设计元件清单
元件名
规格
标号
数目
单片机
AT89C51
1
电阻
10k
R2,R3,R4
3
电容
20pF
C1,C2
2
电容
47uF
C3
1
电位计
RP1
1
传感器
DS18B20
1
显示屏
LM016L
LCD
1
按钮
2
附录2 系统程序
#include<reg51。h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P3^2;
sbit RS=P1^0;
sbit RW=P1^1;
sbit EN=P1^2;
sbit sw0=P3^7;
sbit led=P2^0;
unsigned char code str1[]= {”H: ”};
unsigned char code str2[]= {”temp: ”};
uchar data disdata[5];
uchar data disdata1[5];
uchar data disdata2[5];
uint tvalue, tvalueh;
uchar tflag;
void delay1ms(unsigned int ms)
{
unsigned int i,j;
for(i=0;i〈ms;i++)
for(j=0;j<100;j++);
}
void wr_com(unsigned char com)
{
delay1ms(1);
RS=0;
RW=0;
EN=0;
P0=com;
delay1ms(1);
EN=1;
delay1ms(1);
EN=0;
}
void wr_dat(unsigned char dat)
{
delay1ms(1);;
RS=1;
RW=0;
EN=0;
P0=dat;
delay1ms(1);
EN=1;
delay1ms(1);
EN=0;
}
void lcd_init()
{
delay1ms(15);
wr_com(0x38);
delay1ms(5);
wr_com(0x08);delay1ms(5);
wr_com(0x01);delay1ms(5);
wr_com(0x06);delay1ms(5);
wr_com(0x0c);delay1ms(5);
}
void display(unsigned char *p)
{
while(*p!='\0')
{
wr_dat(*p);
p++;
delay1ms(1);
}
}
void init_play()
{
lcd_init();
wr_com(0x80);
display(str1);
wr_com(0xc0);
display(str2);
}
void delay_18B20(unsigned int i)
{
while(i—-);
}
void ds1820rst()
{
unsigned char x=0;
DQ = 1;
delay_18B20(4);
DQ = 0;
delay_18B20(100);
DQ = 1;
delay_18B20(40);
}
uchar ds1820rd()
{
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_18B20(10);
}
return(dat);
}
void ds1820wr(uchar wdata)
{
unsigned char i=0;
for (i=8; i〉0; i——)
{
DQ = 0;
DQ = wdata&0x01;
delay_18B20(10);
DQ = 1;
wdata>〉=1;
}
}
read_temp()
{
uchar a,b;
ds1820rst();
ds1820wr(0xcc);
ds1820wr(0x44);
ds1820rst();
ds1820wr(0xcc);
ds1820wr(0xbe);
a=ds1820rd();
b=ds1820rd();
tvalue=b;
tvalue<<=8;
tvalue=tvalue|a;
if(tvalue<0x0fff)
tflag=0;
else
{
tvalue=~tvalue+1;
tflag=1;
}
tvalue=tvalue*(6.25);
return(tvalue);
}
/*******************************************************************/
void writebsg(uchar add,uchar date)
{
uchar bai,shi,ge;
bai=date/100;
shi=date%100/10;
ge=date%10;
wr_com(0x80+add);
wr_dat(0x30+bai);
wr_dat(0x30+shi);
wr_dat(0x30+ge);
}
void ds1820disp()
{ uchar flagdat;
disdata[0]=tvalue/10000+0x30;
disdata[1]=tvalue%10000/1000+0x30;
disdata[2]=tvalue%1000/100+0x30;
disdata[3]=tvalue%100/10+0x30;
disdata[4]=tvalue%10+0x30;
if(tflag==0)
flagdat=0x20;
else
flagdat=0x2d;
if(disdata[0]==0x30)
{
disdata[0]=0x20;
if(disdata[1]==0x30)
{
disdata[1]=0x20;
}
}
wr_com(0x80+0x40+8);
wr_dat(flagdat);
wr_com(0x80+0x40+9);
wr_dat(disdata[0]);
wr_com(0x80+0x40+10);
wr_dat(disdata[1]);
wr_com(0x80+0x40+11);
wr_dat(disdata[2]);
wr_com(0x80+0x40+12);
wr_dat(0x2e);
wr_com(0x80+0x40+13);
wr_dat(disdata[3]);
wr_dat(disdata[4]);
}
void delay()
{
unsigned int i;
i=50;
while(i-—);
}
void ds1820disp1()
{ uchar flagdat;
tvalue=tvalue*1.8+3200;
disdata[0]=tvalue/10000+0x30;
disdata[1]=tvalue%10000/1000+0x30;
disdata[2]=tvalue%1000/100+0x30;
disdata[3]=tvalue%100/10+0x30;
disdata[4]=tvalue%10+0x30;
if(tflag==0)
flagdat=0x20;
else
flagdat=0x2d;
if(disdata[0]==0x30)
{
disdata[0]=0x20;
if(disdata[1]==0x30)
{
disdata[1]=0x20;
}
}
wr_com(0x80+8);
wr_dat(flagdat);
wr_com(0x80+9);
wr_dat(disdata[0]);
wr_com(0x80+10);
wr_dat(disdata[1]);
wr_com(0x80+11);
wr_dat(disdata[2]);
wr_com(0x80+12);
wr_dat(0x2e);
wr_com(0x80+13);
wr_dat(disdata[3]);
wr_dat(disdata[4]);
}
void qh()
{
if (sw0==0)
{
ds1820disp1();
}
else
{
ds1820disp();
}
}
/********************主程序***********************************/
void main()
{
init_play();
while(1)
{
read_temp();
ds1820disp();
qh();
}
}
- 16 -
展开阅读全文