51单片机时钟显示+温度显示.docx
- 文档编号:10741337
- 上传时间:2023-02-22
- 格式:DOCX
- 页数:29
- 大小:65.78KB
51单片机时钟显示+温度显示.docx
《51单片机时钟显示+温度显示.docx》由会员分享,可在线阅读,更多相关《51单片机时钟显示+温度显示.docx(29页珍藏版)》请在冰豆网上搜索。
51单片机时钟显示+温度显示
南华大学
计算机技术综合课程
设计报告
学院:
湘南学院
题目:
单片机LCD时钟显示和温度测量
学生姓名:
专业班级:
指导老师:
教研室主任:
■Z..--X_■■■I;
2012年6月29日
一、概述:
本次设计的LCD时钟显示和温度测量系统是由中央控制器、温度检测器、时钟系统、显示器及键盘部分组成。
控制器采用单片机STC89C51RC温度检测部分采用DS18B20温度传感器,时钟系统用时钟芯片DS1302用LCD液晶1602作为显示器,用蜂鸣器构成闹铃模块。
单片机通过时钟芯片DS1302获取时间数据,对数据处理后显示时间;温度传感器DS18B20采集温度信号送该给单片
机处理;单片机再把时间数据和温度数据送液晶显示器1602显示;键盘是用来调整时间的。
二、方案设计及方案论证
1.时钟显示和温度测量的总体设计思路
按照系统的设计功能要求,本时钟显示和温度测量系统的设计必须采用单片机软件系统实现,用单片机的自动控制能力配合按键控制,来控制时钟、温度的调整及显示。
获得时钟显示和温度测量数据信息,单片机对其进行一系列的处理,最后通过液晶显示出来。
2.时钟显示和温度测量系统方案论证
2.1时钟系统方案选择
方案1:
通过单片机内部的定时器/计数器,用软件实现,直接用单片机的定时器编程以实现时钟;
方案2:
用专门的时钟芯片实现时钟的记时,再把时间数据送入单片机,由单片机控制显示。
虽然用软件实现时钟硬件线路简单,但是程序运行的每一步都需要时间,多一步或少一步程序
――仅供参考
都会影响记时的准确度,对定时器定时也不是十分准确,时钟精度很低,对于我们实现所需要的功能造成软件编程非常复杂。
用专用时钟芯片硬件成本相对较高,但它的精度很高,软件编程很简单。
综上所述,选择方案2。
本次设计采用具有涓细电流充电能力的低功耗实时时钟电路DS1302它可以对年、月、日、
周日、时、分、秒进行计时,且具有闰年补偿等多种功能。
它采用主电源和备用电源双电源供电。
它的工作电压范围2.0~5.5V,在2.2V时,小于300nA。
它内部含有31个字节的静态RAM可提供用户访问。
?
DS1302可以对年、月、日、周日、时、分、秒进行计时,可以达到我们设计的基本的要求。
内部的寄存器为我们调时,闹钟定时提供了寄存空间。
备用用电源也实现了当系统断电后,时钟仍然可以保持。
而且它是串行接口,与单片机通信所需要的接口少。
2.2显示系统的方案比较
方案1:
用数码管或LED显示。
方案2:
用液晶1602显示。
方案3:
用液晶12864显示。
时钟和温度的显示可以用数码管或LED而且价格便宜。
但是数码管的只能显示简单的设计的系统,与我们设计要求也不相符。
有很多东西需要显示,还是用显示功能更好的液晶显示器比较好,它能显示更多的数据,用12864显示略想复杂,用1602液晶显示可以完全满足本次设计的数据显示要求。
2.3温度系统方案选择
方案1:
用热敏电阻等测温元件测出电压,再转换成对应的温度。
需要比较多的外部元件支持,且硬件电路复杂,制作成本相对较高。
方案2:
用DS18B2C直接测温。
DS18B20温度传感器是美国DALLAS#导体公司最新推出的一种改进型智能温度传感器,它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9~12
位的数字值读数方式。
经比较,我们选择方案2。
温度实现只能通过外部的温度传感器来实现。
经上网查阅,DS18b20体积小,只有3只脚,电
路接法简单。
精度为0.5°C,也符合我们设计的要求。
DS18B20也是我们通常使用的型号,因此温度传感器用DS18B20
2.4键盘控制方案选择
方案1:
购买集成键盘,采用矩阵形式连接。
方案2:
购买单个复位开关做成键盘。
虽然集成键盘美观,与单片机的接口少,但是它的成本比较高。
单片机的10口对于我们的设
计绰绰有余。
通常我们选用价格便宜单个复位开关做成键盘。
3.时钟显示和温度测量系统总体设计
初步确定设计系统由单片机主控模块、时钟模块、测温模块、闹铃模块、显示模块、键盘接口
模块共6个模块组成,电路系统框图如下图所示
图1:
电路系统框图
三、硬件电路单元设计
1、单片机最小系统设计
1.1复位电路:
■Ix\\\
复位电路有两种方式:
上电复位和按钮复位,我们主要用按钮复位方式。
如下图所示:
图2:
复位电路
1.2晶振电路
晶振电路选取条件:
晶振12M电容20pF到30pF,本电路选取20pF。
晶振电路原理如下图:
图3:
晶振电路
2、时钟系统设计
DS1302时钟电路晶振选用3.2678KHZ原理图如下:
图4:
基于ds1302时钟系统设计电路
3、温度系统设计
DS18B2C温度传感DC端接单片机P1.3口,电路原理图如下:
图5:
基于DS18b20温度系统设计电路
4、液晶显示系统设计
1602液晶显示电路由1K电阻和10K的精密电阻组成,控制端接P1.0、P1.1、P1.2口,数据端接P2口,电路图如下:
图6:
液晶1602显示电路
把15脚的10K电阻改成1K电阻
5、蜂鸣器系统设计
蜂鸣器闹铃电路由蜂鸣器跟1K限流电阻组成,电路图如下:
图7:
蜂鸣器电路
6、电源模块
本系统采用USB供电,用发光二极管显示通电状况,电源电源电路如下:
图8:
电源电路
7、时间调节模块
本系统采用3个按键调节时间。
S1是菜单键,选择要调节的位;S2按一下表示加一;S3按一下表示减一。
电路如下:
图9:
时钟调节电路
四、软件调试
1、程序流程图如下:
图10:
程序流程图
2、程序见附录
五、硬件调试
1、原理图如下:
图11:
总原理图
2、PCB图如下:
图12:
PCB图
其中红色部分为跳线;
3、实物测试
板子制作完成后上电测试发现电源灯没有显示,用万用表测量之后发现精密电阻接线错误,导致VCC与GND直接连通。
修正之后发现电源指示灯还是没有亮,测量USB两端电压为-4.88V,卸掉
USB口,插上排针用杜邦线连接单片机的VCC和GND之后,电源灯能够点亮,液晶能够驱动,但是亮度不够。
测量液晶两端的电压发现只有2.5V,用导线将液晶背光的VCC直接接上电源VCC后,
液晶亮度正常。
将程序下载之后经过几次调试和修改,最终实现了想要达到的效果。
六、总结与体会
在开始本次课程设计前花费了十多天的时间认真学习了单片机,通过书本和视频的学习,对单片机有了进一步的掌握并学会C51编程的一些方法。
这对于完成本次课程设计提供了很大的帮助。
从这次的课程设计中,我真真正正的意识到,在写程序时,逻辑思维要清晰,要有耐心。
同时要巧妙的利用C语言的可移植性,这对写程序有很大的帮助。
参考文献:
1•郭天祥单片机学习板配套资料
2.《51单片机C语言教程》郭天祥主编电子工业出版社
3.《C语言程序设计》尹业安,白燕主编国防科技大学出版社
4.《单片机原理与应用及C51程序设计》谢维成杨加国主编清华大学出版社程序如下:
#include
#includevintrins.h>
#defineucharunsignedchar
#defineuintunsignedint
#defineLCDIOP2
sbitDQ=P1A3;//ds18b20与单片机连接口
sbitrs=P1A0;
――仅供参考
sbitrd=P1A1;
sbitIcden=PM2;
〃移位时的第0位
//移位时用的第7位
sbitacc0=ACCA0;
sbitacc7=ACCA7;
ucharsecond,minute,hour,day,month,year,week,count=0;ucharReadValue,num,time;
uinttvalue;//温度值
uchartflag;
ucharcodetable[]={"2012-06-29FIR"};
ucharcodetable1[]={"08:
45:
00000.0C"};
ucharcodetable2[]="FRISATSUNMONTUEWESTUR";
uchardatadisdata[5];
sbitDATA=P0A1;//时钟数据接口
sbitRST=P0A2;
sbitSCLK=P0A0;
//菜单
〃加一
〃减一
sbitmenu=P3A5;
sbitadd=P3A6;
sbitdec=P3A7;
voiddelay(uintz)
{
uintx,y;
for(x=z;x>0;x__)
for(y=110;y>0;y--);
}
voiddelay1(uintz)
{for(;z>0;z--);
}
voidwrite_com(ucharcom)
{_
rs=0;
rd=0;
lcden=0;
P2=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidwrite_date(uchardate)
{_
rs=1;
rd=0;lcden=0;
P2=date;
delay(5);
――仅供参考
1/
//led写命令指令:
RS=L,RW=L,D0~D7=指令码,E=高脉冲
//led写数据指令:
RS=H,RW=L,D0~D7=数据,E=高脉冲
lcden=1;delay(5);lcden=0;
}
voidinit()
{
ucharnum;lcden=0;write_com(0x38);write_com(0x0c);
显光标,光标不闪
write_com(0x06);
write_com(0x01);write_com(0x80);delay(5);
write_com(0x80);
II显示模式设置,默认为0x38,不用变。
//显示功能设置0x0f为开显示,显示光标,光标闪烁;0x0c为开显示,不
II设置光标状态默认0x06,为读一个字符光标加1.〃显示清屏,将上次的内容清除,默认为0x01.
II设置初始化数据指针,是在读指令的操作里进行的
〃初始化显示时间(tabletablel中的内容)
for(num=0;num<15;num++){
write_date(table[num]);delay(5);
}write_com(0x80+0x40);for(num=0;num<15;num++)
{
write_date(table1[num]);delay(5);
}
1/
}
voidWrite1302(uchardat)II写8bit数据
{
uchari;
SCLK=0;
delay1
(2);
for(i=0;i<8;i++)
II拉低SCLK,为脉冲上升沿写入数据做好准备II稍微等待,使硬件做好准备
〃连续写8个二进制位数据
{
DATA=dat&0x01;〃取出dat的第0位数据写入1302
delay
(2);II稍微等待,使硬件做好准备
SCLK=1;〃上升沿写入数据
delay1
(2);II稍微等待,使硬件做好准备
SCLK=0;〃重新拉低SCLK,形成脉冲
dat>>=1;II将dat的各数据位右移1位,准备写入下一个数据位
}
}
voidWriteSet1302(ucharCmd,uchardat)II向cmd相应地址中写入一个字节的数据
{
RST=0;//禁止数据传递
――仅供参考
SCLK=O;//确保写数居前SCLK被拉低
RST=1;//启动数据传输
delay1
(2);//稍微等待,使硬件做好准备
Write1302(Cmd);//写入命令字
Write1302(dat);//写数据
SCLK=1;//将时钟电平置于已知状态
RST=O;〃禁止数据传递
}
ucharRead1302(void)//读8bit数据
{
uchari,dat;
delay
(2);〃稍微等待,使硬件做好准备
for(i=0;i<8;i++)//连续读8个二进制位数据
{
dat>>=1;〃将dat的各数据位右移1位,因为先读出的是字节的最低位
if(DATA==1)〃如果读出的数据是1
dat|=0x80;//将1取出,写在dat的最高位
SCLK=1;//将SCLK置于高电平,为下降沿读出
delay1
(2);//稍微等待
SCLK=0;〃拉低SCLK,形成脉冲下降沿
delay1
(2);//稍微等待
}
returndat;〃将读出的数据返回
}
ucharReadSet1302(ucharCmd)//从cmd相应地址中读一个字节的数据
//拉低RST
//确保写数居前
//启动数据传输
//写入命令字
//读出数据
//将时钟电平置于已知状态
//禁止数据传递
//将读出的数据返回
}
voidInit_DS1302(void)
{
WriteSet1302(0x8E,0x00);
WriteSet1302(0x80,((0/10)<<4|(0%10)));
WriteSet1302(0x82,((45/10)<<4|(45%10)));//
WriteSet1302(0x84,((8/10)<<4|(8%10)));
WriteSet1302(0x86,((29/10)<<4|(29%10)));//
WriteSet1302(0x88,((6/10)<<4|(6%10)));
WriteSet1302(0x8c,((12/10)<<4|(12%10)));//
WriteSet1302(0x8a,((1/10)<<4|(1%10)));
//根据写状态寄存器命令字,写入不保护指令//根据写秒寄存器命令字,写入秒的初始值
根据写分寄存器命令字,写入分的初始值
//根据写小时寄存器命令字,写入小时的初始值
根据写日寄存器命令字,写入日的初始值
〃根据写月寄存器命令字,写入月的初始值
根据写年寄存器命令字,写入年的初始值//根据写星期寄存器命令字,写入星期的初始值
}
{
uchari,j;
i=x/10;
j=x%10;
write_com(0xc7);
write_date(0x30+i);
write_date(0x30+j);
}_
voidDisplayMinute(ucharx)
{
uchari,j;
i=x/10;
j=x%10;
write_com(0xc4);
write_date(0x30+i);
write_date(0x30+j);
}_
voidDisplayHour(ucharx)
{
uchari,j;
i=x/10;
j=x%10;
write_com(0xc1);
write_date(0x30+i);
write_date(0x30+j);
}_
voidDisplayDay(ucharx)
{
uchari,j;
i=x/10;
j=x%10;
write_com(0x89);
write_date(0x30+i);
write_date(0x30+j);
}_
voidDisplayMonth(ucharx)
{
uchari,j;
i=x/10;
j=x%10;
write_com(0x86);
write_date(0x30+i);
write_date(0x30+j);
}_
〃显示分
//显示小时
//显示日期、天
〃显示日期、月
//从DS1302读取时间秒
//从DS1302读取时间分
//从DS1302读取时间小时
//从DS1302读取日期日
〃从DS1302读取日期月
//从DS1302读取日期年
{
uchari,j;
i=x/10;
j=x%10;
write_com(0x83);
write_date(0x30+i);
write_date(0x30+j);
}_
voidDisplayWeek(ucharx)//显示星期
{uchari;
x=x*3;
write_com(0x8c);
for(i=0;i<3;i++)
{
write_date(table2[x]);
x++;
}
}
voidread_date(void)
{_
ReadValue=ReadSet1302(0x81);
second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=ReadSet1302(0x83);
minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=ReadSet1302(0x85);
hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=ReadSet1302(0x87);
day=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=ReadSet1302(0x89);
month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=ReadSet1302(0x8d);
year=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=ReadSet1302(0x8b);
DisplayMinute(minute);
DisplayHour(hour);
DisplayDay(day);
DisplayMonth(month);
DisplayYear(year);
DisplayWeek(week);
}
voidturn_val(charnewval,ucharflag,ucharnewaddr,uchars1num)//刷新时间(将改变的时
间显示至厂LCD上)
{
//读取当前时间
//将bcd码转换成十进
newval=ReadSet1302(newaddr);
newval=((newval&0x70)>>4)*10+(newval&0x0f);制
if(flag)〃判断是加一还是减一
{newval++;
switch(s1num)
{case1:
if(newval>99)newval=0;DisplayYear(newval);break;
case2:
if(newval>12)newval=1;DisplayMonth(newval);break;
case3:
if(newval>31)newval=1;DisplayDay(newval);break;
case4:
if(newval>6)newval=0;
I-■.
DisplayWeek(newval);break;
case5:
if(newval>23)newval=0;DisplayHour(newval);break;
case6:
if(newval>59)newval=0;DisplayMinute(newval);break;
case7:
if(newval>59)newval=0;DisplaySecond(newval);break;
defaultbreak;
}i
}
else
{
newval--;
switch(s1num)
{case1:
if(newval==0)newval=99;DisplayYear(newval);break;
case2:
if(newval==0)newval=12;DisplayMonth(newval);break;
case3:
if(newval==0)newval=31;DisplayDay(newval);break;
case4:
if(newval<0)newval=6;
DisplayWeek(newval);
break;
case5:
if(newval<0)newval=23;
DisplayHour(newval);
break;
case6:
if(newval<0)newval=59;
DisplayMinute(newval);
break;
case7:
if(newval<0)newval=59;
DisplaySecond(newval);
break;
default:
break;
}
}
//将新数据写入
WriteSet1302((newaddr-1),((newval/10)<<4)|(newval%10));寄存器
}
voidkey_scan(void)〃键盘扫描程序
—i■■.-
{ucharmiao,s1num=0;
if(menu==0)
{
delay(5);
if(menu==0)
{
while(!
menu);
slnum++;
while
(1)
{
if(menu==0)
JI;I、\/Z\—
{delay(5);jif(menu==0)
{
while(!
menu);
slnum++;
}
}
rd=0;
miao=ReadSet1302(0x81);
second=miao;
WriteSet1302(0x80,miao|0x80);
write_com(0x0f);〃光标闪射
if(s1num==1)
{year=ReadSet1302(0x8d);
write_com(0x80+4);//年光标
if(add==0)
delay(3);
if(add==O)
{while(!
add);turn_val(year,1,0x8d,1);
}_
}
if(dec==O)
{
delay(3);if(dec==O)
{while(!
dec);turn_val(year,0,0x8d,1);
}_
}
}
if(s1num==2)
{
month=ReadSet1302(0x89);write_com(0x80+7);//月光标
if(add==0)
{
delay(3);
if(add==0)
{while(!
add);
turn_val(month,1,0x89,2);
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 51 单片机 时钟 显示 温度