基于51单片机温度检测LCD显示课程设计报告Word文档下载推荐.docx
《基于51单片机温度检测LCD显示课程设计报告Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《基于51单片机温度检测LCD显示课程设计报告Word文档下载推荐.docx(26页珍藏版)》请在冰豆网上搜索。
![基于51单片机温度检测LCD显示课程设计报告Word文档下载推荐.docx](https://file1.bdocx.com/fileroot1/2023-1/30/8fb040d7-b5fb-4fdd-88f7-5401251a1c70/8fb040d7-b5fb-4fdd-88f7-5401251a1c701.gif)
AT89S52是一个低功耗,高性能CMOS8位单片机,片内含8kBytesISP(In-systemprogrammable)的可反复擦写1000次的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统及80C51引脚结构,芯片内集成了通用8位中央处理器和ISPFlash存储单元,功能强大的微型计算机的AT89S52可为许多嵌入式控制应用系统提供高性价比的解决方案。
AT89S52具有如下特点:
40个引脚,8kBytesFlash片内程序存储器,256bytes的随机存取数据存储器(RAM),32个外部双向输入/输出(I/O)口,5个中断优先级2层中断嵌套中断,2个16位可编程定时计数器,2个全双工串行通信口,看门狗(WDT)电路,片内时钟振荡器。
AT89S52引脚图
此外,AT89S52设计和配置了振荡频率可为0Hz并可通过软件设置省电模式。
空闲模式下,CPU暂停工作,而RAM定时计数器,串行口,外中断系统可继续工作,掉电模式冻结振荡器而保存RAM的数据,停止芯片其它功能直至外中断激活或硬件复位。
同时该芯片还具有PDIP、TQFP和PLCC等三种封装形式,以适应不同产品的需求。
电源
时钟
晶振原理图
I/O接口
外围电路工作原理及硬件图
四软件系统设计
软件流程框图
系统设计原理:
本次课程设计是基于单片机的数字温度计设计,在开始课程设计的时候我们要理解并掌握对单片机的开发,学会使用KEIL及Proteus等仿真软件。
根据设计任务要求选择好器件,编写好程序运行成功之后进行软件联调,验证系统是否正确。
通过筛选,我们组选用单片机AT89S52作为主控制系统;
用1602液晶显示模块芯片作为温度数据显示装置;
智能温度传感器采用DS18B20器件作为测温电路主要组成部分。
五仿真调试
(1)KeilC51单片机软件开发系统的整体结构
C51工具包的整体结构,uVision与Ishell分别是C51forWindows和forDos的集成开发环境(IDE),可以完成编辑、编译、连接、调试、仿真等整个开发流程。
开发人员可用IDE本身或其它编辑器编辑C或汇编源文件。
然后分别由C51及C51编译器编译生成目标文件(.OBJ)。
目标文件可由LIB51创建生成库文件,也可以与库文件一起经L51连接定位生成绝对目标文件(.ABS)。
ABS文件由OH51转换成标准的Hex文件,以供调试器dScope51或tScope51使用进行源代码级调试,也可由仿真器使用直接对目标板进行调试,也可以直接写入程序存贮器如EPROM中。
(2)使用独立的Keil仿真器时,注意事项
●仿真器标配11.0592MHz的晶振,但用户可以在仿真器上的晶振插孔中换插其他频率的晶振。
●仿真器上的复位按钮只复位仿真芯片,不复位目标系统。
●仿真芯片的31脚(/EA)已接至高电平,所以仿真时只能使用片内ROM,不能使用片外ROM;
但仿真器外引插针中的31脚并不与仿真芯片的31脚相连,故该仿真器仍可插入到扩展有外部ROM(其CPU的/EA引脚接至低电平)的目标系统中使用。
●调试结果
●
(3)结果分析
在运行仿真结果时通过改变温度传感器DS18B20的温度,然后调用各种子函数,可以改变液晶显示1602的第二行显示数据,说明程序编写正确。
(4)系统设计电路的特点和方案的优缺点
我们组设计的数字温度计系统知识运用简单的AT89S52芯片的I/O口传输功能,通过几个小的读数据、传递数据、延时子函数实现温度的读取传输功能,是比较简单,容易实现的,所以我们的系统只是实现了一些简单的功能,系统整体来说比较简易,但好像这个温度计没有多大的应用价值,所以我们后续分析觉得这个系统可以加一个温度复位系统提高AT89S52芯片的功能价值,也提高数字温度计的智能价值,还可以增加一个报警子函数,实现智能数字温度计更高的应用价值。
六结论
虽然基本功能已经做好了,但还可以有很多的扩展功能,如串口设计和时钟显示,由于时间有限,但对于单片机的设计还在继续…
参考文献
附录一
程序代码:
#include<
reg52.h>
intrins.h>
#defineucharunsignedchar
#defineuintunsignedint
sbitDQ=P2^2;
//定义DS18B20端口DQ
sbitBEEP=P2^3;
//蜂鸣器驱动线
bitpresence,flag;
bitcompare_th,compare_tl,alarm_on_off=0,temp_th,temp_tl;
sbitLCD_RS=P3^5;
sbitLCD_RW=P3^6;
sbitLCD_EN=P3^4;
ucharcodecdis1[]={"
READ_ROMCORD"
};
ucharcodecdis2[]={"
"
ucharcodecdis3[]={"
DS18B20ERR0R"
ucharcodecdis4[]={"
PLEASECHECK"
ucharcodecdis5[]={"
TEMP:
ucharcodecdis6[]={"
TH:
TL:
unsignedchardatatemp_data[2]={0x00,0x00};
unsignedchardatatemp_alarm[2]={0x20,0x10};
unsignedchardatadisplay[5]={0x00,0x00,0x00,0x00,0x00};
//温度值显示
unsignedchardatadisplay1[3]={0x00,0x00,0x00};
//温度报警值显示
unsignedchardataRomCode[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
unsignedcharcodemytab1[8]={0x0C,0x12,0x12,0x0C,0x00,0x00,0x00,0x00};
#definedelayNOP();
{_nop_();
_nop_();
unsignedcharTemp,temp_comp,timecount,count;
unsignedcharcrc;
voidDisp_Temp_alarm(ucharaddr,ucharnum);
voidspk(ucharaddr);
voidset_temp_alarm();
voidtemp_compare();
voidbeep();
/*******************************************************************/
voiddelay1(intms)
{
unsignedchary;
while(ms--)
{
for(y=0;
y<
250;
y++)
_nop_();
}
}
/******************************************************************/
/**/
/*检查LCD忙状态*/
/*lcd_busy为1时,忙,等待。
lcd-busy为0时,闲,可写指令与数据。
*/
/******************************************************************/
bitlcd_busy()
{
bitresult;
LCD_RS=0;
LCD_RW=1;
LCD_EN=1;
delayNOP();
result=(bit)(P0&
0x80);
LCD_EN=0;
return(result);
/*写指令数据到LCD*/
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。
voidlcd_wcmd(ucharcmd)
{
delay1(10);
LCD_RW=0;
P0=cmd;
/*写显示数据到LCD*/
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。
voidlcd_wdat(uchardat)
LCD_RS=1;
P0=dat;
/*自定义字符写入CGRAM*/
voidwritetab()
unsignedchari;
lcd_wcmd(0x40);
//写CGRAM
for(i=0;
i<
8;
i++)
lcd_wdat(mytab1[i]);
lcd_wdat(mytab2[i]);
/*LCD初始化设定*/
voidlcd_init()
delay1(15);
lcd_wcmd(0x01);
//清除LCD的显示内容
lcd_wcmd(0x38);
//16*2显示,5*7点阵,8位数据
delay1(5);
lcd_wcmd(0x0c);
//显示开,关光标
lcd_wcmd(0x06);
//移动光标
//清除LCD的显示内容
writetab();
//自定义字符写入CGRAM
/*设定显示位置*/
voidlcd_pos(ucharpos)
lcd_wcmd(pos|0x80);
//数据指针=80+地址变量
/*us级延时函数*/
voidDelay(unsignedintnum)
while(--num);
/*初始化ds1820*/
Init_DS18B20(void)
DQ=1;
//DQ复位
Delay(8);
//稍做延时
DQ=0;
//单片机将DQ拉低
Delay(90);
//精确延时大于480us
//拉高总线
presence=DQ;
//如果=0则初始化成功=1则初始化失败
Delay(100);
return(presence);
//返回信号,0=presence,1=nopresence
/*读一个字节*/
ReadOneChar(void)
unsignedchari=0;
unsignedchardat=0;
for(i=8;
i>
0;
i--)
//给脉冲信号
dat>
>
=1;
if(DQ)
dat|=0x80;
Delay(4);
return(dat);
/*写一个字节*/
WriteOneChar(unsignedchardat)
DQ=dat&
0x01;
Delay(5);
dat>
=1;
/*温度报警值写入DS18B20*/
Write_Temperature_alarm(void)
Init_DS18B20();
WriteOneChar(0xCC);
//跳过读序号列号的操作
WriteOneChar(0x4e);
//将设定的温度报警值写入DS18B20
WriteOneChar(temp_alarm[0]);
//写TH
WriteOneChar(temp_alarm[1]);
//写TL
WriteOneChar(0x7f);
//12位精确度
WriteOneChar(0x48);
//把暂存器里的温度报警值拷贝到EEROM
/*读取64位序列码*/
Read_RomCord(void)
unsignedcharj;
WriteOneChar(0x33);
//读序列码的操作
for(j=0;
j<
j++)
RomCode[j]=ReadOneChar();
/*DS18B20的CRC8校验程序*/
ucharCRC8()
uchari,x;
ucharcrcbuff;
crc=0;
for(x=0;
x<
8;
x++)
crcbuff=RomCode[x];
for(i=0;
i<
if(((crc^crcbuff)&
0x01)==0)
crc>
else{
crc^=0x18;
//CRC=X8+X5+X4+1
crc|=0x80;
}
crcbuff>
returncrc;
/*数据转换与显示*/
Disp_RomCode(ucharH_num)
ucharj;
if(H_num==1)
lcd_pos(0x00);
if(H_num==2)
lcd_pos(0x40);
for(j=0;
j<
j++)
Temp=RomCode[j];
display[0]=((Temp&
0xf0)>
4);
if(display[0]>
9)
{display[0]=display[0]+0x37;
else{display[0]=display[0]+0x30;
}
lcd_wdat(display[0]);
//高位数显示
display[1]=(Temp&
0x0f);
if(display[1]>
{display[1]=display[1]+0x37;
else{display[1]=display[1]+0x30;
lcd_wdat(display[1]);
//低位数显示
/*读取温度*/
Read_Temperature(void)
uchari;
TR0=0;
//关中断,防止读数错误
//跳过读序号列号的操作
WriteOneChar(0x44);
//启动温度转换
WriteOneChar(0x55);
//匹配ROM命令
for(i=0;
i<
i++)
WriteOneChar(RomCode[i]);
WriteOneChar(0xBE);
//读取温度寄存器
temp_data[0]=ReadOneChar();
//温度低8位
temp_data[1]=ReadOneChar();
//温度高8位
temp_alarm[0]=ReadOneChar();
//温度报警TH
temp_alarm[1]=ReadOneChar();
//温度报警TL
temp_comp=((temp_data[0]&
4)|((temp_data[1]&
0x0f)<
<
//取温度整数值
TR0=1;
//开中断
/*数据转换与温度显示*/
/************************************************************