数字式温度计.docx
《数字式温度计.docx》由会员分享,可在线阅读,更多相关《数字式温度计.docx(31页珍藏版)》请在冰豆网上搜索。
数字式温度计
长沙学院
《单片机原理及应用》
课程设计说明书
题目
12864液晶屏显示温度计的设计
系(部)
电子信息与电气工程系
专业(班级)
光电一班
姓名
陈玲芝
学号
2013041134
指导教师
刘辉、马凌云、王新辉
起止日期
《单片机原理及应用》课程设计任务书17
系(部):
电信系专业:
2013级光电信息工程
课题名称
12864液晶屏显示温度计的设计
设计内容及要求
(1)课题内容:
以单片机为核心,使用DS18B20温度传感器设计一个数字式温度计。
测量一路温度信号并用12864液晶屏显示;测温范围-55-125摄氏度,精度0.1摄氏度。
液晶屏的第一行显示“数字式温度计”,第二行显示温度值,第三行显示设计者姓名和学号。
(2)要求:
完成该系统的硬件和软件的设计,在Proteus软件上仿真通过后,提交一篇课程设计说明书。
设计工作量
1、汇编或C51语言程序设计;
2、程序调试;
3、在Proteus上进行仿真后,进行实验板下载调试;
4、提交一份完整的课程设计说明书,包括设计原理、程序设计、程序分析、仿真分析、调试过程,参考文献、设计总结等。
进度安排
起止日期(或时间量)
设计内容(或预期目标)
备注
第一天
课题介绍,答疑,收集材料,C51介绍
第二天
设计方案论证,练习编写C51程序
第三天~第六天
程序设计
第六天~第八天
程序调试、仿真
第九天~第十天
系统测试并编写设计说明书
教研室
意见
年月日
长沙学院课程设计鉴定表
姓名
陈玲芝
学号
2013041134
专业
光电
班级
1班
设计题目
12864液晶屏显示温度计
指导教师
刘辉、马凌云、王新辉
指导教师意见:
评定成绩:
教师签名:
日期:
答辩小组意见:
评定成绩:
答辩小组长签名:
日期:
教研室意见:
最终评定等级:
教研室主任签名:
日期:
说明
课程设计成绩分“优秀”、“良好”、“中等”、“及格”、“不及格”五等。
目录
一.数字式温度计原理分析4
二.设计方案4
1.DS18B20采集电路4
2.MCU主控电路5
3.LCD12864液晶显示模块6
4.供电方式6
三.数字式温度计C51程序编写C51程序主体6
1.程序模块7
2.程序流程框图7
3.实现效果8
四.总结与心得9
参考文献9
一.数字式温度计原理分析
该数字式温度计采用STC89C52单片机作为核心控制芯片,并且采用达拉斯公司的DS18B20温度采集芯片来采集温度,通过一块带字库的LCD12864液晶显示屏显示采集的当前温度以及当前时间等信息。
DS18B20是本设计的核心传感器,它接线方便,封装成后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式,型号多种多样,有LTM8877,LTM8874等等。
主要根据应用场合的不同而改变其外观。
封装后的DS18B20可用于电缆沟测温,高炉水循环测温,锅炉测温,机房测温,农业大棚测温,洁净室测温,弹药库测温等各种非极限温度场合。
耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。
另外,DS18B20的采集范围为-55℃——+125℃。
二.设计方案
1.DS18B20采集电路
DS18B20作为一款集成性很高的传感器芯片,几乎不要为之搭建其他电路,只需要接上+5V的Vcc电源和地即可正常工作。
DS18B20引脚:
面对铭牌时左负右正,中间一个引脚为采集数据引脚。
如图1所示。
图1DS18B20温度传感器实物图
DS18B20采集电路如图2所示。
P33为单片机I/O口P3.3。
图2DS18B20温度采集电路
2.MCU主控电路
由于该系统较为简单、易于实现,所以采用51系列单片机作为主控芯片已经足够。
51单片机选用当今市场上最常见的STC公司的STC89C52。
STC89C52是STC公司生产的一种低功耗、高性能CMOS8位微控制器,具有8K在系统可编程Flash存储器。
STC89C52使用经典的MCS-51内核,但做了很多的改进使得芯片具有传统51单片机不具备的功能。
在单芯片上,拥有灵巧的8位CPU和在系统可编程Flash,使得STC89C52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。
具有以下标准功能:
8k字节Flash,512字节RAM,32位I/O口线,看门狗定时器,内置4KBEEPROM,MAX810复位电路,3个16位定时器/计数器,4个外部中断,一个7向量4级中断结构,兼容传统51的5向量2级中断结构,全双工串行口。
STC89C52单片机直插式封装实物如图3所示。
图3STC89C52直插式封装实物图
STC89C52单片机正常工作的最小系统如图4所示。
STC89C52单片机最小系统包括按键复位电路和晶振电路。
图4STC89C52单片机最小工作系统电路图
3.LCD12864液晶显示模块
LCD12864显示模块采用一块带字库的12864液晶显示屏和一个最大阻值10K的电位器。
电位器用于调节液晶显示屏的屏幕灰度。
LCD12864液晶显示模块电路如图5所示。
图5LCD12864液晶显示模块电路图
4.供电方式
STC89C52单片机的正常工作电压为+5V,DS18B20和LCD12864也为+5V,所以采用+5V直流电源为系统供电。
所以直接采用电脑或输出+5V的电源适配器为该系统供电。
三.数字式温度计C51程序编写C51程序主体
#include
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbit…
sbit…
sbit…
voidInit_Timer0(void);//定时器初始化
{
…
…
}
voidds1820disp2();
{
…
…
}
voidds1820disp3();
{
…
…
}
voidzhb(void)interrupt0//外部中断子程序(译码过程)
{
…
…
}
voidlcd_delay(unsignedintt)
{
…
…
}
…
…
voidmain()
{
…
…
}
1.程序模块
该程序分为LCD12864显示模块,DS18B20数据传送模块,单片机最小系统等。
2.
程序流程框图
3.实现效果
经过软硬件的联合调试,最终数字式温度计调试成功。
硬件软件效果如图9所示。
图9数字式温度计效果图
最终LCD12864显示屏的第一行温度计,第二行显示当前温度,精度0.1℃,;第三行显示本人姓名和学号。
上述效果全部调试成功,数字式温度计达到预期效果。
四.总结与心得
我对自己的C51编程能力一向比较有信心,但是,经过了这一周的单片机课程设计,我切实体会到了自己在这方面存在的不足。
途中遇到了很多问题,类似于lcd12864屏幕的显示,一般相对于显示程序都是运用的LED数码管,比较简单,但是这次运用的lcd的话就比较复杂,找了一些资料之后,才将lcd12864加到这个数字式温度计中;我按照自己最初的想法,开始着手写程序。
这部分程序还是比较容易,只需要写入正确的计算算法和送数据的函数就可以顺利地加入到上面的主程序中。
在显示当前温度值的时候还是出现了问题。
当前温度值明明是阿拉伯数字,在12864液晶显示屏却占用了一个汉字的位置,并且“数字式”这三个字我一写上去,下在单片机里面就变成乱码,我把阿拉伯数字按照一位一位拆开再送数据,又让小数点无法存在。
尝试了送“℃”的字模后没用。
当然这次在网络上参考了一些别人的程序,但是与我的约有不同,但是我发现,修改之后就可以使用,这也算是一种收获。
在课程设计中,还发现一些显示的问题:
在使用lcd12864时,本来可以很好的显示一行字,但是在关闭程序后,再启动,就发现不能很好的显示相同的字,可能已经是一堆乱码了,这个还有疑问。
由于遇到问题没有完全解决,连续几天都没有吃中饭,茶不思饭不想,咨询同学无解,自己调不好,这一周都呆在实验室B310,努力改进程序,光电检测的报告也快要交了但却还没写,内心实在焦急;不放弃的念头让我们最后都顺利地完成了设计,还耐心地帮助了其他同学,帮忙查找程序错误和调整。
虽然有时候会觉得烦心,但却又很充实,能做到连零食都不想吃,连吃饭的时间都忘记。
晚上同学带电脑回去请我帮忙查看,一起看程序改程序,找资料等等、、、
这几天的学习,不仅学会了一些C语言的程序的编程,还对单片机的一些扩展运用有了新的认识。
在学习过程中,这些在平时不注意的,但是在课程设计中运用到了,所以对此有了一定的了解,有了一定程度上的熟练运用。
这一次的单片机课程设计,在上次的单片机实习的基础上又对单片机系统有了新的认识,对单片机的拓展应用有了一定的了解,这都是对于学习单片机来说是很宝贵的经验。
而且简单的单片机也可以是贴近生活的,一些小的项目都可以在生活中运用,这样的话,学习单片机就可以很有兴趣,学习起来也是有动力的。
这次的单片机课程设计,收获很多以前不巩固的知识,类似于C语言编程、lcd12864、显示取模等等一系列的问题,但实际上这些远远不够的,要想学好单片机,并熟练掌握应用,还需要很长一段时间的学习。
此次单片机课程设计提高了我的C51程序编写调试能力,让我对自己的专业有了更深的理解。
同时,我锻炼了自己的心理素质和软硬件协调的能力。
相信单片机课程设计一定会成为我以后学习工作中的一笔宝贵财富。
谢谢刘辉老师和马凌云老师的悉心指导和同学们的热心帮助,我的努力和上述元素对我的课程都是不可或缺的。
参考文献
[1]郭天祥.51单片机C语言教程[M].北京:
电子工业出版社,2009.01,342~354.
[2]曾屹.单片机原理与应用[M].长沙:
中南大学出版社,2009.06,99~125.
[3]臧春华.综合电子设计与实践[M].北京:
北京航空航天大学出版社,2009.11,403~406.
附:
源程序:
#include
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitDQ=P3^7;//ds18b20与单片机连接口
//sbitPWM=P2^5;//控制信号的输出
unsignedcharcodestr[]={"温度值:
℃"};
//unsignedcharcodestr1[]={"temper:
"};
//unsignedcharcodenul[]={""};
//unsignedcharcodestr_[]={"MADEINNUPT..."};
unsignedcharstr4[2];//设定温度的存储
uchardatadisdata[1];
uchara[4]={0,0,0,0},j,i,k,num=0;//定义变量
sbitjs=P3^5;//红外接收端
ucharzhb_flag=0;//保证一次解码,只执行一次代码
uinttvalue;//温度值
uchartflag;//温度正负标志
uintnumber=4;//暂时规定输入的温度为xx.x的形式
ucharj;
uinttime_flag=0;
uintnew_t;//转化后的十进制实时温度
//------------定义接口-------------//
sbitRS=P2^6;
sbitRW=P2^5;
sbitE=P2^7;
sbitPSB=P3^2;//H=并口;L="串口";
#defineLcd_BusP0
#defineucharunsignedchar
#defineFIRST_ADDR0
bitReadTempFlag;//定义读时间标志
voidInit_Timer0(void);//定时器初始化
voidds1820disp2();
voidds1820disp3();
//定义字符/汉字显示起始位置
/*------------------检查忙位-----------------------------*/
voidchk_busy()
{
RS=0;
RW=1;
E=1;
Lcd_Bus=0xff;
while((Lcd_Bus&0x80)==0x80);
E=0;
}
/*------------------延时子程序-----------------------------*/
voidlcd_delay(unsignedintt)
{
unsignedinti,j;
for(i=0;ifor(j=0;j<10;j++);
}
/*------------------写命令到LCD------------------------------*/
voidwrite_com(unsignedcharcmdcode)
{
chk_busy();
RS=0;
RW=0;
E=1;
Lcd_Bus=cmdcode;
lcd_delay(5);
//------------------在数据写入的时候加入适当的延时
E=0;
lcd_delay(5);
}
/*-------------------写数据到LCD----------------------------*/
voidwrite_data(unsignedcharDispdata)
{
chk_busy();
RS=1;
RW=0;
E=1;
Lcd_Bus=Dispdata;
lcd_delay(5);
//------------------在数据写入的时候加入适当的延时
E=0;
lcd_delay(5);
}
/*------------------初始化LCD屏--------------------------*/
voidlcdreset()
{
PSB=1;
lcd_delay(2000);
write_com(0x30);
lcd_delay(10);
//选择基本指令集
//write_com(0x03);//0x30
//选择8bit数据流
lcd_delay(5);
write_com(0x0c);
//开显示(无游标、不反白)
lcd_delay(10);
write_com(0x01);
//清除显示,并且设定地址指针为00H
lcd_delay(500);
write_com(0x06);
//指定在资料的读取及写入时,设定游标的移动方向及指定显示的移位
lcd_delay(0);
}
/*------------------显示字符串--------------------------*/
voidhzkdis(unsignedcharcode*s)
{
while(*s>0)
{
write_data(*s);
s++;
lcd_delay(50);
}
}
/*------------------首屏显示--------------------------*/
voidceshi()
{
write_com(0x01);
//清除显示,并且设定地址指针为00H
lcd_delay(5);
write_com(0x80);
//第一行(如果是地址是:
80H,即LCD的第一行的第一个位置显示)
hzkdis("温度计");
write_com(0x90);
hzkdis("温度值:
");
ds1820disp3();
//第二行(如果是地址是:
94H,即LCD的第二行的右半平面第一个位置显示)
write_com(0x88);
write_data(disdata[1]);
//第三行(如果是地址是:
88H,即LCD的第二行的第一个位置显示)
write_com(0x98);
hzkdis("陈玲芝2013041134");
//第四行(如果是地址是:
98H,即LCD的第二行的第一个位置显示)
}
//------------------清整个GDRAM空间----------------------------
voidclrgdram()
{
unsignedcharx,y;
for(y=0;y<64;y++)
for(x=0;x<16;x++)
{
write_com(0x34);
write_com(y+0x80);
//行地址
write_com(x+0x80);
//列地址
write_com(0x30);
write_data(0x00);
write_data(0x00);
}
}
voidclrscreen()
{
write_com(0x01);
lcd_delay(10);
}
unsignedcharReadByte(void)
{
unsignedcharbyReturnValue;
chk_busy();
Lcd_Bus=0xff;
RS=1;
RW=1;
E=0;
E=1;
byReturnValue=Lcd_Bus;
E=0;
returnbyReturnValue;
}
voidsend_to_pc(void)
{
uintpc_flag=0;
SCON=0x50;//串口方式1,允许接收
TMOD=0x20;//定时器1,定时方式2
TCON=0x40;//设定时器1开始计数
TH1=0xE8;//11.0592MHz,1200波特率
TL1=0xE8;
TI=1;//允许串行端口发送中断
TR1=1;//启动定时T1
while
(1)
{
if(pc_flag==1)
{
TMOD=1;
}
else
{
printf("Nowtempertureis");
printf(disdata);
printf("*0.1°C");
pc_flag++;
}
}
}
voiddelay_18B20(unsignedinti)//延时1微秒
{
while(i--);
}
voidds1820rst()/*ds1820复位*/
{
unsignedcharx=0;
DQ=1;//DQ复位
delay_18B20(4);//延时
DQ=0;//DQ拉低
delay_18B20(100);//精确延时大于480us
DQ=1;//拉高
delay_18B20(40);
}
uchards1820rd()/*读数据*/
{
unsignedchari=0;
unsignedchardat=0;
for(i=8;i>0;i--)
{
DQ=0;//给脉冲信号
dat>>=1;
DQ=1;//给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(10);
}
return(dat);
}
voidds1820wr(ucharwdata)/*写数据*/
{
unsignedchari=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=wdata&0x01;
delay_18B20(10);
DQ=1;
wdata>>=1;
}
}
read_temp1()/*读取温度值并转换*/
{
ds1820rst();
ds1820wr(0xcc);//*跳过读序列号*/
ds1820wr(0x44);//44*启动温度转换*/
ds1820rst();
}
read_temp2()
{
uchara,b;
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*(0.625);//温度值扩大10倍,精确到1位小数
return(tvalue);
}
/*******************************************************************/
voidds1820disp1()//温度值显示
{
//ucharflagdat;
disdata[0]=tvalue/1000+0x30;//百位数
disdata[1]=tvalue%1000/100+0x30;//十位数
disdata[2]=tvalue%100/10+0x30;//个位数
disdata[3]=tvalue%10+0x30;//小数位
//if(tflag==0)
//flagdat=0x20;//正温度不显示符号
//else
//flagdat=0x2d;//负温度显示负号:
-
//if(disdata[0]==0x30)
//{
//disdata[0]=0x20;//如果百位为0,不显示
//if(disdata[1]==0x30)
//{
//disdata[1]=0x20;//如果百位为0,十位为0也不显示
//}
//}
}
voidds1820disp3()
{
lcd_delay(5);
write_com(0x90);
hzkdis("温度值:
");
lcd_delay(50);
write_com(0x8A);
write_data(disdata[1]);
write_com(0x8B);
write_data(disdata[2]