单片机课程设计报告,基于51单片机的电子密码锁设计开题报告
本文选题:51系列单片机设计实例 + 单片机课程设计总结
单片机课程设计报告,基于51单片机的电子密码锁设计开题报告
时间: 2017-03-25 栏目: <mip-link href="http://mip.cuntuba520.net/xiaozhishi/list184685/">单片机课程设计小结
一 > 基于51单片机的电子密码锁设计开题报告
基于单片机的电子密码锁设计开题报告
一、毕业论文代写课题背景和意义
在日常的生活和工作中, 住宅与部门的安全防范、单位的文件档案、财务报表以及一些个人资料的保存多以加锁的办法来解决。[)若使用传统的机械式钥匙开锁,人们常需携带多把钥匙, 使用极不方便, 且钥匙丢失后安全性即大打折扣。随着科学技术的不断发展,人们对日常生活中的安全保险的要求越来越高。为满足人们对锁的使用要求,增加其安全性,用密码代替钥匙的密码锁应运而生。密码锁具有安全性高、成本低、功耗低、易操作等优点。
在安全技术防范领域,具有防盗报警功能的电子密码锁逐渐代替传统的机械式密码锁,克服了机械式密码锁密码量少、安全性能差的缺点,使密码锁无论在技术上还是在性能上都获得了大大的提高。随着大规模集成电路技术的发展,特别是单片机的问世,出现了带微处理器的智能密码锁,它除具有电子密码锁的功能外,还引入了智能化管理、专家分析系统等功能,从而使密码锁具有很高的安全性、可靠性,应用日益广泛。
随着人们对安全的重视和科技的发展,许多电子智能锁(指纹识别、IC卡辨认)已在国内外相继面世。但是这些产品的特点是针对特定的指纹和有效卡,只能适用于保密要求的箱、柜、门等。而且指纹识识别器若在公共场所使用存在容易机械损坏,IC卡还存在容易丢失、损坏等缺点,再加上其成本较高,一定程度上限制了这类产品的普及和推广。鉴于目前的技术水平与市场的接受程度,电子密码锁是这类电子防盗产品的主流。
二、毕业论文代写课题任务的主要内容
根据设定好的密码,采用4×4键盘实现密码的输入功能,当密码输入正确之后,锁就打开,如果输入的密码不正确,就锁定按键3秒钟,同时发出报警声。
(1)单片机型号可选AT89C51。
(2)6位密码的设定在程序中完成。
(3)密码的输入采用4×4键盘实现,输入6位数字后,按回车键结束。
(4)若输入的密码正确,锁打开,同时用发光二极管亮1秒作为提示。
(5)报警可采用蜂鸣器或扬声器。
三、毕业论文代写已具备条件
应用电子技术专业的毕业生已完成电子线路、数字电路基础、单片机原理、单片机应用系统设计等课程的学习,并通过实践课的教学达到相应的电路设计、软件编程等能力目标。
四、设计思路与方案
1.系统框图
2. 组成部分
电子密码锁的设计主要由三部分组成:4×4矩阵键盘接口电路、显示电路、报警电路。
(1)4×4矩阵键盘接口电路:设置6位密码,通过键盘输入密码,若密码正确,则锁就打
密码锁设计 基于51单片机的电子密码锁设计开题报告
开。(]密码可以由用户自己在程序中修改设定(只支持6位密码)。
(2)显示电路:当密码输入时,按下一个数字键, 一个“-”就显示在最右边的数码管上,同时将先前输入的所有“-”向左移动一位。
(3)报警电路:由蜂鸣器和一个发光二极管组成。当密码输入正确时,发光二极管亮1秒钟。若密码输入错误,则蜂鸣器发出报警声提示,同时键盘锁定3秒钟。
3.设计的关键问题
电子密码锁设计的关键问题是实现密码的输入、清除、确认等功能:
(1) 密码输入功能:按下一个数字键,一个“-”就显示在最右边的数码管上,同时将先前输入的所有“-”向左移动一位。
(2)清除功能:当按下清除键时,清除前面输入的所有值,并清除所有显示。
(3)确认功能:当按下确认键,系统将输入的密码与内设密码进行检查核对,如果正确,锁打开,否则不打开。
五、预期目标
完成基于单片机设计的电子密码锁的论文。
六、毕业论文代写进度安排
1.2008年11月1日——11月7日:下达毕业设计任务书。
2.2008年11月8日——11月21日:撰写开题报告。
3.2008年11月22日——11月25日:毕业设计初期检查。
4.2008年11月26日——12月31日:完成相关参考文献查阅、资料查找,设计电路原理图,购买元器件,进行硬件设计与软件设计,开始实物安装、调试。
5.2009年1月4日——1月9日:毕业设计中期检查。
6.2009年1月10日——1月15日:学习论文的撰写规范,并确定撰写方案。
7.2009年1月16日——5月15日:顶岗实习,并且完成毕业论文,毕业设计后期检查。
8.2009年5月16日——5月18日:上交毕业论文、实物、毕业顶岗材料。
二 > 51单片机电子时钟课程设计报告
<mip-img src="http://p.cuntuba520.net/cpic/3e/62/5ebaaf255ecd810c06e5732ea1d9623e.jpg">
第一部分 设计任务和要求
1.1 单片机课程设计内容
利用STC89C51单片机和LCD1602电子显示屏实现电子时钟,可由按键进行调时和12/24小时切换。()
1.2 单片机课程设计要求
1.能实现年、月、日、星期、时、分、秒的显示;
2.能实现调时功能;
3.能实现12/24小时制切换;
4.能实现8:00—22:00整点报时功能。
1.3 系统运行流程
程序首先进行初始化,在主程序的循环程序中首先调用数据处理程序,然后调用显示程序,在判断是否有按键按下。若有按键按下则转到相应的功能程序执行,没有按键按下则调用时间程序。若没到则循环执行。计时中断服务程序完成秒的计时及向分钟、小时的进位和星期、年、月、日的进位。调时闪烁中断服务程序用于被调单元的闪烁显示。调时程序用于调整分钟、小时、星期、日、月、年,主要由主函数组成通过对相关子程序的调用,如图所示。实现了对时间的设置和修改、LCD显示数值等主要功能。相关的调整是靠对功能键的判断来实现的。
第二部分 设计方案
2.1 总体设计方案说明
1.程序设计及调试
根据单片机课程设计内容和要求,完成Protues仿真电路的设计和用Keil软件编写程序,并进行仿真模拟调试。
2.硬件焊接及调试
根据仿真电路图完成电路板的焊接,并进行软、硬件的调试,只到达到预期目的。
单片机课程设计总结 51单片机电子时钟课程设计报告
单片机课程设计报告
3.后期处理
对设计过程进行总结,完成设计报告。(]
2.2 单片机系统方框图
2.2 单片机系统流程图
主流程图
键盘扫描流程图
1
单片机课程设计总结 51单片机电子时钟课程设计报告
单片机课程设计报告
时钟流程图
第三部分 主要器件及简介
3.1 主要器件
1. STC89C51单片机;
2.LCD1602液晶显示屏;
3.2 主要器件简介
1.STC89C51单片机简介
STC89C51是采用8051核的ISP(In System
Programming)在系统可编程芯片,最高工作时钟频率
为80MHz,片内含8K Bytes的可反复擦写1000次的
Flash只读程序存储器,器件兼容标准MCS-51指令系
统及80C51引脚结构,芯片内集成了通用8位中央处理器和ISP Flash存储单元,具有在系统可编程(ISP)特性,配合PC端的控制程序即可将用户的程序代码下载进单片机内部,省去了购买通用编程器,而且速度更快。[]
2.LCD1602液晶显示屏简介
2
单片机课程设计总结 51单片机电子时钟课程设计报告
单片机课程设计报告
LCD1602可以显示2行16个字符,有8位数据总线D0—D7,和RS、R/W、EN三个控制端口,工作电压为5V,并且带有字符对比度调节和背光。[)
LCD1602引脚说明如下表所示:
LCD液晶显示器各引脚功能及结构
VDD:电源正极,4.5V—5.5V,通常使用5V电压;
VL:LCD对比度调节端,电压调节范围为0—5V。接正极时对比度最弱,接地电源时对比度最高,但对比度过高会产生“鬼影”,因此通常使用一个10K的电位器来调整对比度,或者直接串接一个电阻到地;
RS:MCU写入数据或者指令选择端。MCU要写入指令时,使RS为低电平;MCU要写入数据时,使RS为高电平;
R/W:读写控制端。R/W为高电平时,读取数据;R/W为低电平时,写入数据; EN:LCD模块使能信号控制端。写数据时,需要下降沿触发模块。
D0—D7:8为数据总线,三态双向。如果MCU的I/O口资源紧张的话,该模块也可以只使用4位数据线D4—D7接口传送数据。
A:LED背光正极。需要背光时, A串接一个限流电阻接VDD, K接地。 K:LED背光地端。
3
单片机课程设计总结 51单片机电子时钟课程设计报告
单片机课程设计报告
第四部分 系统硬件设计
4.1 最小系统
复位时单片机的初始化操作,只要给RST
引脚加上两个机器周期以上的高电平信号,就
可以使STC89C51单片机复位。(]本次采用的是
12M晶振,按钮复位电路。
4.2 LCD显示电路
LCD显示屏的D0到D7与单片机P0口相连,LCD显示屏EN口与单片机P3.4口相连,RS与P3.5相连。通过滑动变阻器改变LCD显示屏的显示对比度。
4
单片机课程设计总结 51单片机电子时钟课程设计报告
单片机课程设计报告
4.3 键盘输入电路
本次设计采用独立键盘,键盘按下时,相应的I/O口电平由高变低,一次检测按键是否被按下。[]4个独立按键与单片机P3.0—P3.3口相连。
4.3 蜂鸣器和LED灯电路
蜂鸣器的作用为准点报时产生报警声,LED在秒钟为偶数时或者功能键被按下时亮。蜂鸣器与单片机P2.2口相连,LED灯与单片机P2.3口相连。
5
单片机课程设计总结 51单片机电子时钟课程设计报告
单片机课程设计报告
第五部分 仿真电路图与仿真结果
用Keil和Protues进行仿真调试,仿真结果完全达到预期目的。[]
第六部分 课程设计总结
本次单片机课程设计,在我和我的搭档陈雅琴默契配合,以及邹老师的指导和同学的帮助下顺利完成了。在设计过程中,从仿真电路的设计,源程序的书写和修改以及实物电路的焊接中都遇到了不少问题,但在我们的共同努力下解决了,并且从中学到了不少知识。我们在设计过程中还不断提出自己的疑点以及新的想法,联系实际应用,将课本上学习的东西运用到实际中,这些都令我们受益匪浅。
课程设计需要很大的耐心,尤其是遇到困难的时候,这也是对我们的考验。在设计过程中,我们遇到问题不是感到急躁,而是耐心地寻找解决的办法,与老师、同学进行交流讨论,寻求最佳的解决办法。
6
单片机课程设计总结 51单片机电子时钟课程设计报告
单片机课程设计报告
总之,在此次的课程设计中,我们不仅动手、动脑,也学会了不少东西,同时,谢谢对我们的设计带来建议、意见和帮助的老师和同学们!谢谢!
<mip-img src="http://p.cuntuba520.net/cpic/3e/62/5ebaaf255ecd810c06e5732ea1d9623e.jpg">
第七部分 参考文献
[1]张毅刚。[)单片机原理及应用(第二版)。北京:高等教育出版社。2004
[2]郭天祥。新概念51单片机C语言教程.北京:电子工业出版社。2007
[3]杨欣.电子设计从零开始.北京:清华大学出版社,2005
附录A 实物图
目的:
通过课程设计,主要达到以下目的:
1、使学生增进对单片机的感性认识,加深对单片机理论方面的理解。
2、使学生掌握单片机的内部功能模块的应用,如定时器/计数器、中断、片内外存贮器、I/O口、串行口通讯等。
3、使学生了解和掌握单片机应用系统的软硬件设计过程、方法及实现,为以后设计和实现单片机应用系统打下良好基础。
7
单片机课程设计总结 51单片机电子时钟课程设计报告
单片机课程设计报告
void init() /*初始化函数*/
{
write_cod(0x38); /*1602液晶工作状态定义*/ write_cod(0x0c);
write_cod(0x06);
write_cod(0x01);
TMOD=0x01; //定时器工作在方式1 ,16位 TH0=(65536-50000)/256; //50ms
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void write_cod(uchar num) /*1602写指令函数*/ {
E=0;
RS=0;
RW=0;
P0=num;
delay(5);
E=1;
delay(5);
E=0;
}
void write_date(uchar date) /*1602写数据函数*/ {
E=0;
RS=1;
RW=0;
P0=date;
delay(5);
E=1;
delay(5);
E=0;
}
void display(uchar add,uchar shu) /*显示模块 */ {
gao=shu/10;
di=shu%10;
write_cod(0x80+0x40+add); //0x40 第二行 +add
write_date(0x30+gao); //0x30 将数字转换为字符 write_date(0x30+di);
}
8
三 > 《单片机课程设计》报告
机械与车辆学院
《单片机课程设计》报告
(2013-2014学年第一学期)
课程设计题目: 水塔水位控制系统
姓名:
学号:
班级:
指导老师: 职称:
时间:
成绩:
《单片机课程设计》考查评分表
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063K01Y8_1.jpg">
2
目录
一、课程设计性质和目的 ................................................................ 4
二、课程设计的内容及要求 ............................................................ 4
1、硬件设计 ...................................................................................... 4
2、软件设计 ...................................................................................... 5
3、功能要求: .................................................................................. 5
三、课程设计的进度及安排 ............................................................ 5
四、设计所需设备及材料 ................................................................ 6
五、设计思路及原理分析 ................................................................ 7
六、流程图及程序编写 .................................................................... 7
(1)根据功能要求画出控制程序流程图。 .................................. 8
(2)根据控制程序流程图编写C51程序 ..................................... 8
七、调试运行 .................................................................................. 10
1、软件测试: ................................................................................ 10
2、硬件测试: ................................................................................ 11
八、结果及分析 .............................................................................. 12
九、心得体会 .................................................................................. 13
十、参考文献 .................................................................................. 14
十一、致谢 ...................................................................................... 14
十二、附录 ...................................................................................... 15
【1】整流器protel防真原理图:................................................. 15
【2】数字时钟 ................................................................................ 16
3
一、课程设计性质和目的
单片机课程设计是《单片机原理与接口技术》课程与实验结束后的一门综合性实践课。设计一种基于单片机水塔水位检测控制系统。该系统能实现水位检测、电机故障检测、处理和报警等功能,实现超高、低警戒水位报警,超高警戒水位处理。介绍电路接口原理图,给出相应的软件设计流程图和汇编程序,并用
Proteus软件仿真。所选题目《水塔水位控制》紧密结合所学的主要内容,加深巩固所学知识,同时对所学内容进行扩展,有一定的深度和广度,能充分发挥学生的能动性和想象力。通过电路设计、安装、调试等一系列环节的实施,提高学生的单片机应用系统的设计能力。
相信本次的设计一定能够给老百姓的生活带来方便,也一定会具有广阔的市场前景,一定能够使我们电子设计能力得到很好的锻炼,使我们的理论和现实生活联系起来!
二、课程设计的内容及要求
1、硬件设计
(1)用80C51设计一个单片机最小控制系统。其中P1.0接水位下限传感器,P1.1接水位上限传感器,P1.2输出经三极管和电阻后接光电耦合器,通过继电器控制水泵,P1.3输出接LED,当出现故障时LED闪烁;当出现故障时报警。
(2)用塑料尺、导线等设计一个水塔水位传感器。其中A电级置于水位10CM处,接5V电源的正极,B级置于水位15CM处,经4.7K下拉电阻接单片机的P1.0口,C电级置于水位的20CM处,经4.7K下拉电阻接单片机的P1.2口。
(3)设计一个单片机至水泵的控制电路。要求单片机与水泵之间用反相器、光电耦合器和继电器控制,计算出LED限流电阻,接好继电器的续流二极管。
4
2、软件设计
(1)根据功能要求画出控制程序流程图。 (2)根据控制程序流程图编写C51程序
3、功能要求:
(1)水塔水位下降至下限水位时,启动水泵,水塔水位上升至上限水位则关闭水泵。
(2)水塔水位在上、下限水位之间时,水泵保持原状态。 (3)供水系统出现故障时,自动报警。
表1 水塔水位信号状态表
<mip-img src="http://p.cuntuba520.net/cpic/32/08/53931148b7495ea2cd1f2a8e7f1a0832.jpg">
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063P3V14_0.jpg">
三、课程设计的进度及安排
5
四、设计所需设备及材料
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063Kc460_0.jpg">
6
<mip-img src="http://p.cuntuba520.net/cpic/04/81/05656a95254010d2eb57f50c8eb58104.jpg">
五、设计思路及原理分析
水塔水位控制原理图见图1,图中两条虚线表示正常工作情况下水位升降的上下限,在正常供水时,水位应控制在两条虚线代表的水位之间。B测量水位下限,C测量水位上限,A接+5V,B、C接地。
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063K452W_0.jpg">
图1 水塔水位检测原理图
水塔无水或水位低于下限水位时,B、C为断开,B、C两点电位为零(低电平“0” ),需要水泵供水,单片机输出低电平,控制电机工作供水。水位上升到B点,B接通,B点电位变为高电平“1”,C开关仍断开,C点仍为低电平,维持现状水泵继续供水。当水位上升到C点时,C接通。这时B、C均接通,B、C两点都为高电平,表示水塔水位已满,需水泵停止供水,单片机输出高电平,电机断电停止供水。水塔水位开始下降,水位在降到B点之前,B点电位为高、C点电位为低,单片机输出控制电平维持不变,仍为高。当水位降到B点以下,
B、C两点电平都为低时,单片机输出控制电平又变低,水泵供水。
六、流程图及程序编写
<mip-img src="http://p.cuntuba520.net/cpic/7a/37/4b252a0989b84930fba6a67b28d0377a.jpg">
7
(1)根据功能要求画出控制程序流程图。
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063J55E3_0.jpg">
(2)根据控制程序流程图编写C51程序
#include<reg51.h>
sbit P1_0=P1^0;
sbit P1_1=P1^1;
sbit P1_2=P1^2;
sbit P1_3=P1^3;
sbit P1_4=P1^4;
void delay0_2s(){
unsigned char i;
TMOD=0x01;
for(i=0;i<4;i++){
TH1=0x3C; 8
TL1=0xB0; TR1=1;
while(!TF1); TF1=0;
}
}
void delay_1s(){ unsigned char i; for(i=0;i<5;i++){ delay0_2s(); }
}
void main(){
P1=0xf0;
while(1){
P1_3=0;
if(P1_0==0)//B {
if(P1_1==0)//C {
P1_2=0; delay_1s(); }
else
{ P1_2=1;//电机 P1_3=1; delay0_2s(); P1_4=1; delay_1s(); }
}
else
{
9
} }} if(P1_1==1){//C } else delay_1s(); P1_2=1; delay_1s();
七、调试运行
1、软件测试:
运用Protul软件进行仿真检验。在元件库中找到所需要的元器件,把它们按照原理图的构想依次连接起来,反复检查线路会不会出错。待画完图,就可以开始仿真电路图了。给单片机导入预先编程好的程序“.hex”文件,点击仿真。仿真图可以运行,但是电机在B,C都为低电平的情况下没有运转。说明电路有部分地方短路或者断路了,观察仿真图中的电位情况也许可以找到问题的所在。经过多次的检查发现,各点的电位并没有像想象中的那样有什么不妥。现在就要搞清楚仿真中的元器件的所有主要参数是否和实际的参数相符合。查看资料,对于继电器,它本身的线圈电阻是在400欧左右,在查看仿真中的元器件的参数,不难发现原始数据和实际相差很大,它给的是理想线圈,也就是没有内阻。这样就如预期的那样找到电机不转的原因了。原始数据没有进行改变;查找资料,得知光电耦合器的发光二极管的压降为1.15~1.5v,最大电流为60mA,电流传输比CTR为20~70%。通过已知的条件求出每条线路上所需要的电阻大小。对各各元器件的初参数设置完毕,启动仿真,整体像想象中的那样正常工作!软件仿真结束,仿真图里的数值引用到实际电路的焊接中。
10
2、硬件测试:
焊接完整体的板件,开始测试板子电路是否能够完成所需要的功能。应为电路的原版是根据仿真电路出来的,所以不一定能够一次性就完成设计。 对于板子上的器件来说,有两个是特别容易烧掉的,PNP三极管和4N25光电耦合器。因为它们的工作电压较低和工作电流很小,所以要特别的注意。虽然已经给了足够的保护还是不能太掉以轻心要是烧了就没有其他器件可以换了。
首先,测试光电耦左边能否正常工作。把三极管的B极接于低电平,给予E极高电平,测试两管脚之间的电压降是多少。经测试三极管正常工作,可是光电耦合器的1,2管脚的电压异常偏高。断去电源,用万用表的测试端测试1,2管脚是否击穿,发现并没有完全短路,有可能是封装的时候没有装好。
其次,测试光电耦合器右端是否能正常工作。给继电器加上12v的电压, 用导线短接光电耦合器的4,5号管脚,继电器能发出啪啪声,也就是说明光电耦合器右端能够正常工作。
再次,对整块板进行调试。给光电耦合器两边电路都通上电,给三极管的B端输入一个低电平,继电器不工作。说明光电耦合器无法工作。应当更换光电耦合器;换完光电耦合器后的检测。换完光电耦合器后进行整块板子的调试,给三极
11
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063H54104_1.jpg">
管B极一个低电平继电器能够工作。插到单片机上给一个周期性的低电平,继电器能够周期性的发出啪啪声,整体调试通过
八、结果及分析
调试:
将光耦的第二引脚和第四引脚接地,PNP三极管的发射极接+5V电源。然后分别用光耦的第五引脚和+12V电源线接继电器的线圈两端,稍停片刻后,若能听到吧嗒一声,则证明光耦、继电器能够正常工作,然后进行接铜片,用开发板防真,进行水泵实验,电路能够实现表一的真值表功能。
硬件电路如下:
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063I0VI_0.jpg">
12
九、心得体会
结束为期两周的单片机课程设计,让我加深了对单片机的理解,由单片机控制系统可以应用到生活中的很多地方,解决生活中的一些简单的用电子控制的问题,使我意识到了单片机的重要性,两周以来,我们分别进行了课程设计的硬件部分的电路焊接和软件部分的电路图的设计和原理图的设计和制作,无论是硬件电路的焊接和软件的设计和仿真都需要我们认真的把每一部分的原理弄懂,并且要把他们连接起来,这个过程,要求我们要很有耐心和认真的心态。由于以前对单片机的理解不够深刻,使我在单片机课程设计的过程中遇到了很多困难,比如说protues的仿真过程中,在调试出问题后,我虚心地请教同学,也得到了同学的热心帮忙,真正让我体会到了虚心使人进步这句话的深刻含义。
13
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063I0VI_1.jpg">
十、参考文献
[1] 王静霞 主编,单片机应用技术,电子工业出版社,2009.
[2] 徐玮 主编,C51单片机高效入门,机械工业出版社,2006.
[3] 张永枫 主编,单片机应用实训教程,清华大学出版社,2008
[4] 李常庆 主编,数字电子技术第三版,机械工业出版社,2008
[5]杨素行 主编.模拟电子技术简明教程,高等教育出版社,2010年 十一、致谢
感谢我们的吴明友老师,组员在这两个星期以来对我的辅导和帮助,在我工作过程中对我的支持和配合。
14
十二、附录
【1】整流器protel
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063Ia446_1.jpg">
防真原理图:
【2】整流器protel防真波形图:
<mip-img src="http://p.cuntuba520.net/cpic/11/34/f25de83a4e8226e5038209954fd83411.jpg">
<mip-img src="http://p.cuntuba520.net/cpic/58/6d/b3a3795075bb2da959abe7aeb1266d58.jpg">
15
【2】数字时钟
#include<reg52.h>
#define uchar unsigned char //定义无字符变量
#define uint unsigned int//
uchar SMG_duan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //是数码管的段选位
uchar SMG_wei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; // 是数码管的位选位
sbit k1=P3^0; //位定义P3.0为启动按钮
sbit k2=P3^1; //位定义P3.1复位按钮
sbit k3=P3^2; //位定义P3.2停止按钮
sbit d1=P0^0; //位定义P0.0为LED灯控制端
uint i,second,minute,n,x,b,c,a,flag1,flag2;
void delay(uchar i); //延时函数
void XSSHIZHONG(); //显示数字时钟
void DingShi(); //用于定时分钟函数
void delay5ms(); //按键的消抖5ms
void ShiZhong(); //时钟控制函数控制时钟的启动,复位,停止,设定设定的操作
void main()
{
TMOD=0x12; // 定时器1工作方式1和定时器0工作方式2 TH1=(65536-50000)/256; // 定时时间为50MS 设初值
TL1=(65536-50000)%256;
TR1=0; // 开定时器1
EA=1; // 开总中断
ET1=1; // 开定时器T1允许位
EX1=1; // 开放外部中断0允许位
16
IT1=1; // 置外部中断为边沿(下降沿4)触发方式 P2=0x00; // P2口为段选
P1=0xff;
while(1)
{
}
void DingShiqing1() interrupt 3 //用定时器1 中断号为3
{
TH1=(65536-50000)/256; //定时时间为50MS
TL1=(65536-50000)%256; //
i++; // } XSSHIZHONG(); ShiZhong(); // P1口为位选 if(i==2) // 100ms到,即0.1秒,即0.1秒加1 { i=0; n++; if(n==10) { n=0; second++; if(second==60) { second=0; minute++; if(minute==60) // 60分钟到时,分钟清零 minute=0; // 60秒到时,分钟加1,秒钟清零 //1000ms时n清零 }
17
} } }
void weidu1() interrupt 2 //外部中断1 {
unsigned int z;
flag1=1;
b=second;
c=n;
a++;
if(a==60)
a=0;
for(z=0;z<40;z++)
DingShi();
}
void delay(uchar i)
{
unsigned char j,k;
for(k=0;k
22
四 > 单片机课程设计报告
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063I5DM_0.jpg">
单片机课程设计报告
万年历的设计
姓 名:学 号: 0915321028 班 级: 09自动化 指导教师:晏来成
基于51单片机的万年历
摘要:
电子万年历是一种非常广泛日常计时工具,对现代社会越来越流行。它可以对年、月、日、周日、时、分、秒进行计时,使用寿命长,误差小。对于数字电子万年历采用直观的数字显示,可以同时显示年、月、日、周日、时、分、秒和温度等信息,还具有时间校准等功能。该电路采用AT89S52单片机作为核心,功耗小,能在3V的低压工作,电压可选用3~5V电压供电。
本设计是基于51系列的单片机进行的电子万年历设计,可以显示年月日时分秒及周信息,具有可调整日期和时间功能。在设计的同时对单片机的理论基础和外围扩展知识进行了比较全面准备。万年历的设计过程在硬件与软件方面进行同步设计。硬件部分主要由AT89C52单片机,LCD显示电路,以及调时按键电路等组成。在单片机的选择上本人使用了AT89C52单片机,该单片机适合于许多较为复杂控制应用场合。显示器使用了1602液晶显示,并且使用蜂鸣器实现了整点报警的功能,温度测试的功能实现使用了DS18B20,
并实现了温度过高或过低时的温度报警。
软件方面主要包括日历程序、时间调整程序,显示程序等。程序采用C语言编写。所有程序编写完成后,在KeilC51软件中进行调试,确定没有问题后,在Proteus软件中嵌入单片机内进行仿真,并最终实现基本要求。
综上所述此万年历具有读取方便、显示直观、功能多样、电路简洁、成本低廉等诸多优点,符合电子仪器仪表的发展趋势,具有广阔的市场前景。
一、设计要求
基本要求:
1,8 个数码管上显示,显示时间的格式为(假如当前时间是19:32:20)“19-32-20”;
2,具有日历功能;
③ 时间可以通过按键调整。
发挥部分:
④ 具有闹钟功能(可以设定多个)。
二:总体设计
电路设计框图
<mip-img src="http://p.cuntuba520.net/cpic/04/d2/618ff9921ebddedff8d24c366996d204.jpg">
系统硬件概述
本电路是由AT89S52单片机为控制核心,具有在线编程功能,低功耗,能在3V超低压工作;时钟电路由单片机定时功能提供;温度的采集由DS18B20构成,它具有独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯,使用时不需要额外的外围电路。并且,其测温范围 -55℃~+125℃,固有测温分辨率0.5℃;显示部份使用1602液晶显示,可完美地显示年、月、日、周日、时、分、秒,且在整点时刻通过蜂鸣器实现响铃。还可以实现温度显示,且当判断得温度过高或过低时,通过液晶显示及LED发光二极管完成报警。
单片机主控制模块的设计
AT89S52单片机为40引脚双列直插芯片,有四个I/O口P0,P1,P2,P3, MCS-51单片机共有4个8位的I/O口(P0、P1、P2、
P3),每一条I/O线都能独立地作输出或输入。
单片机的最小系统如下图所示,18引脚和19引脚接时钟电路,XTAL1接外部晶振和微调电容的一端,在片内它是振荡器倒相放大器的输入,XTAL2接外部晶振和微调电容的另一端,在片内它是振荡器倒相放大器的输出.第9引脚为复位输入端,接上电容,电阻及开关后够上电复位电路,20引脚为接地端,40引脚为电源端.
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063H234U_1.jpg">
液晶显示模块的设计
LCD1602有16个引脚,其中VCC、VSS分别为电源正负极;VO为液晶偏压信号输入端,图中W1可调节液晶明亮度; DB0—DB7 8位数据段;BLA、BLK背光源正负极; RS数据/命令选择端;R/W读写选择端;E使能端
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063H234U_0.jpg">
温度采集模块设计
采用数字式温度传感器DS18B20,它是数字式温度传感器,具有测量精度高,电路连接简单特点,此类传感器仅需要一条数据线进行数据传输,使用P0.7与DS18B20的I/O口连接加一个上拉电阻,Vcc接电源,Vss接地。
PCB图
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063G62D2_0.jpg">
三电子时钟的软件设计
系统软件按键检测流程图
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063G62D2_1.jpg">
系统软件定时器程序流程图
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063G26032_0.jpg">
子程序的设计
DS18B20温度子程序
void write_temp(uchar add,uchar dat)//向LCD写温度数据,并指定显示位置 {
uchar gw,sw,bw;
if(dat>=0&&dat<=128)
{
gw=dat%10;//取得个位数字
sw=dat%100/10;//取得十位数字
bw=dat/100 ;//取得百位数字
}
else
{
dat=256-dat;
gw=dat%10;//取得个位数字
sw=dat%100/10;//取得十位数字
bw=-3; //0x30-3表示为负号
}
write_1602com(er+add);//er是头文件规定的值0x80+0x40
write_1602dat(0x30+bw);//数字+30得到该数字的LCD1602显示码 write_1602dat(0x30+sw);//数字+30得到该数字的LCD1602显示码 write_1602dat(0x30+gw);//数字+30得到该数字的LCD1602显示码
write_1602dat(0xdf);//显示温度的小圆圈符号,0xdf是液晶屏字符库的该符号地址码
write_1602dat(0x43); //显示"C"符号,0x43是液晶屏字符库里大写C的地址码
}
1602子程序
void write_byte(uchar dat)//写一个字节
{
ACC=dat;
RST=1;
for(a=8;a>0;a--)
{
IO=ACC0;
SCLK=0;
SCLK=1;
ACC=ACC>>1;
}
}
uchar read_byte()//读一个字节
{
RST=1;
for(a=8;a>0;a--)
{
ACC7=IO;
SCLK=1;
SCLK=0;
ACC=ACC>>1;
}
return (ACC);
}
//----------------------------------------
void write_1302(uchar add,uchar dat)//向1302芯片写函数,指定写入地址,数据 {
RST=0;
SCLK=0;
RST=1;
write_byte(add);
write_byte(dat);
SCLK=1;
RST=0;
}
uchar read_1302(uchar add)//从1302读数据函数,指定读取数据来源地址
{
uchar temp;
RST=0;
SCLK=0;
RST=1;
write_byte(add);
temp=read_byte();
SCLK=1;
RST=0;
return(temp);
}
uchar BCD_Decimal(uchar bcd)//BCD码转十进制函数,输入BCD,返回十进制 {
uchar Decimal;
Decimal=bcd>>4;
return(Decimal=Decimal*10+(bcd&=0x0F));
}
//--------------------------------------
void ds1302_init() //1302芯片初始化子函数(2010-01-07,12:00:00,week4) {
RST=0;
SCLK=0;
write_1302(0x8e,0x00); //允许写,禁止写保护
write_1302(0x80,0x00); //向DS1302内写秒寄存器80H写入初始秒数据00
write_1302(0x82,0x00);//向DS1302内写分寄存器82H写入初始分数据00
write_1302(0x84,0x12);//向DS1302内写小时寄存器84H写入初始小时数据12 write_1302(0x8a,0x01);//向DS1302内写周寄存器8aH写入初始周数据4
write_1302(0x86,0x08);//向DS1302内写日期寄存器86H写入初始日期数据07 write_1302(0x88,0x07);//向DS1302内写月份寄存器88H写入初始月份数据01 write_1302(0x8c,0x10);//向DS1302内写年份寄存器8cH写入初始年份数据10 write_1302(0x8e,0x80); //打开写保护
}
时分秒显示子函数
void write_sfm(uchar add,uchar dat)//向LCD写时分秒,有显示位置加、现示数据,两个参数
{
uchar gw,sw;
gw=dat%10;//取得个位数字
sw=dat/10;//取得十位数字
write_1602com(er+add);//er是头文件规定的值0x80+0x40
write_1602dat(0x30+sw);//数字+30得到该数字的LCD1602显示码
write_1602dat(0x30+gw);//数字+30得到该数字的LCD1602显示码
}
//-------------------------------------
//年月日显示子函数
void write_nyr(uchar add,uchar dat)//向LCD写年月日,有显示位置加数、显示数据,两个参数
{
uchar gw,sw;
gw=dat%10;//取得个位数字
sw=dat/10;//取得十位数字
write_1602com(yh+add);//设定显示位置为第一个位置+add
write_1602dat(0x30+sw);//数字+30得到该数字的LCD1602显示码
write_1602dat(0x30+gw);//数字+30得到该数字的LCD1602显示码
}
//-------------------------------------------
void write_week(uchar week)//写星期函数
{
write_1602com(yh+0x0c);//星期字符的显示位置
switch(week)
{
case 1:write_1602dat('M');//星期数为1时,显示
write_1602dat('O');
write_1602dat('N');
break;
case 2:write_1602dat('T');//星期数据为2时显示
write_1602dat('U');
write_1602dat('E');
break;
case 3:write_1602dat('W');//星期数据为3时显示
write_1602dat('E');
write_1602dat('D');
break;
case 4:write_1602dat('T');//星期数据为4是显示
write_1602dat('H');
write_1602dat('U');
break;
case 5:write_1602dat('F');//星期数据为5时显示
write_1602dat('R');
write_1602dat('I');
break;
case 6:write_1602dat('S');//星期数据为6时显示
write_1602dat('T');
write_1602dat('A');
break;
case 7:write_1602dat('S');//星期数据为7时显示
write_1602dat('U');
write_1602dat('N');
break;
定时器0初始化程序
void init() //定时器、计数器设置函数
{
TMOD=0x11; //指定定时/计数器的工作方式为1
TH0=0; //定时器T0的高四位=0
TL0=0; //定时器T0的低四位=0
EA=1; //系统允许有开放的中断
ET0=1; //允许T0中断
TR0=1; //开启中断,启动定时器
}
}
//****************键盘扫描有关函数**********************
void keyscan()
{
if(key1==0)//---------------key1为功能键(设置键)-------------------- {
delay(9);//延时,用于消抖动
if(key1==0)//延时后再次确认按键按下
{
buzzer=0;//蜂鸣器短响一次
delay(20);
buzzer=1;
while(!key1);
key1n++;
if(key1n==12) key1n=1;//设置按键共有秒、分、时、星期、日、月、年、返回,8个功能循环 switch(key1n) { case 1: TR0=0;//关闭定时器 //TR1=0; write_1602com(er+0x09);//设置按键按动一次,秒位置显示光标 write_1602com(0x0f);//设置光标为闪烁 temp=(miao)/10*16+(miao)%10;//秒数据写入DS1302 write_1302(0x8e,0x00); write_1302(0x80,0x80|temp);//miao write_1302(0x8e,0x80); break; case 2: write_1602com(er+6);//按2次fen位置显示光标 //write_1602com(0x0f); break; case 3: write_1602com(er+3);//按动3次,shi //write_1602com(0x0f); break; case 4: write_1602com(yh+0x0e);//按动4次,week //write_1602com(0x0f); break; case 5: write_1602com(yh+0x0a);//按动5次,ri //write_1602com(0x0f); break; case 6: write_1602com(yh+0x07);//按动6次,yue //write_1602com(0x0f); break; case 7: write_1602com(yh+0x04);//按动7次,nian //write_1602com(0x0f); break; case 8: write_1602com(er+1); write_1602dat(0x4d); write_1602com(er+1); break; case 9: write_1602com(er+1); write_1602dat(0x46); write_1602com(er+1); break; case 10:write_1602com(er+1); write_1602dat(0x53);
write_1602com(er+1);
break;
case 11:
write_1602com(er+1);
write_1602dat(0x20);
write_1602com(0x0c);//按动到第8次,设置光标不闪烁
TR0=1;//打开定时器
temp=(miao)/10*16+(miao)%10;
write_1302(0x8e,0x00);
write_1302(0x80,0x00|temp);//miao数据写入DS1302
write_1302(0x8e,0x80);
break;
}
}
}
//------------------------------加键key2---------------------------- if(key1n!=0)//当key1按下以下。再按以下键才有效(按键次数不等于零) {
if(key2==0) //上调键
{
delay(10);
if(key2==0)
{
buzzer=0;//蜂鸣器短响一次
delay(20);
buzzer=1;
while(!key2);
switch(key1n)
{
case 1:miao++;//设置键按动1次,调秒
if(miao==60)
miao=0;//秒超过59,再加1,就归零
write_sfm(0x08,miao);//令LCD在正确位置显示"加"设定好的秒数 temp=(miao)/10*16+(miao)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00); //允许写,禁止写保护
write_1302(0x80,temp); //向DS1302内写秒寄存器80H写入调整后的秒数据BCD码
write_1302(0x8e,0x80); //打开写保护
write_1602com(er+0x09);//因为设置液晶的模式是写入数据后,光标自动右移,所以要指定返回
//write_1602com(0x0b);
break;
case 2:fen++;
if(fen==60)
fen=0;
write_sfm(0x05,fen);//令LCD在正确位置显示"加"设定好的分数据 temp=(fen)/10*16+(fen)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x82,temp);//向DS1302内写分寄存器82H写入调整后的分数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(er+6);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置
break;
case 3:shi++;
if(shi==24)
shi=0;
write_sfm(2,shi);//令LCD在正确的位置显示"加"设定好的小时数据 temp=(shi)/10*16+(shi)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x84,temp);//向DS1302内写小时寄存器84H写入调整后的小时数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(er+3);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 4:week++;
if(week==8)
week=1;
write_1602com(yh+0x0C);//指定'加'后的周数据显示位置
write_week(week);//指定周数据显示内容
temp=(week)/10*16+(week)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x8a,temp);//向DS1302内写周寄存器8aH写入调整后的周数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+0x0e);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 5:ri++;
switch(yue)
{
case 1:case 3:case 5:case 7:case 8:case 10:case 12:
if(ri>31) ri=1;
break;
case 2:
if(nian%4==0||nian%400==0)
{
if(ri>29) ri=1;
}
else
{
if(ri>28) ri=1;
}break;
case 4:case 6:case 9:case 11:
ri++;
if(ri>30) ri=1;
break;
}
write_nyr(9,ri);//令LCD在正确的位置显示"加"设定好的日期数据 temp=(ri)/10*16+(ri)%10;//十进制转换成DS1302要求的DCB码
write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x86,temp);//向DS1302内写日期寄存器86H写入调整后的日期数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+10);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 6:yue++;
if(yue==13)
yue=1;
write_nyr(6,yue);//令LCD在正确的位置显示"加"设定好的月份数据 temp=(yue)/10*16+(yue)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x88,temp);//向DS1302内写月份寄存器88H写入调整后的月份数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+7);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 7:nian++;
if(nian==100)
nian=0;
write_nyr(3,nian);//令LCD在正确的位置显示"加"设定好的年份数据 temp=(nian)/10*16+(nian)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x8c,temp);//向DS1302内写年份寄存器8cH写入调整后的年份数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+4);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 8: write_1602com(er+9); //设置闹钟的秒定时
miao1++;
if(miao1==60)
miao1=0;
write_sfm(0x08,miao1);//令LCD在正确位置显示"加"设定好秒的数据
write_1602com(er+9);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置
break;
case 9: write_1602com(er+6); //设置闹钟的分钟定时
fen1++;
if(fen1==60)
fen1=0;
write_sfm(0x05,fen1);//令LCD在正确位置显示"加"设定好的分数据
write_1602com(er+6);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置
break;
case 10: write_1602com(er+3); //设置闹钟的小时定时
shi1++;
if(shi1==24)
shi1=0;
write_sfm(0x02,shi1);//令LCD在正确的位置显示"加"设定好的小时数据 write_1602com(er+3);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
}
}
}
//------------------减键key3,各句功能参照'加键'注释--------------- if(key3==0)
{
delay(10);//调延时,消抖动
if(key3==0)
{
buzzer=0;//蜂鸣器短响一次
delay(20);
buzzer=1;
while(!key3);
switch(key1n)
{
case 1:miao--;
if(miao==-1)
miao=59;//秒数据减到-1时自动变成59
write_sfm(0x08,miao);//在LCD的正确位置显示改变后新的秒数 temp=(miao)/10*16+(miao)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00); //允许写,禁止写保护
write_1302(0x80,temp); //向DS1302内写秒寄存器80H写入调整后的秒数据BCD码
write_1302(0x8e,0x80); //打开写保护
write_1602com(er+0x09);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置
//write_1602com(0x0b);
break;
case 2:fen--;
if(fen==-1)
fen=59;
write_sfm(5,fen);
temp=(fen)/10*16+(fen)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x82,temp);//向DS1302内写分寄存器82H写入调整后的分数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(er+6);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置
break;
case 3:shi--;
if(shi==-1)
shi=23;
write_sfm(2,shi);
temp=(shi)/10*16+(shi)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x84,temp);//向DS1302内写小时寄存器84H写入调整后的小时数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(er+3);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 4:week--;
if(week==0)
week=7;
write_1602com(yh+0x0C);//指定'加'后的周数据显示位置
write_week(week);//指定周数据显示内容
temp=(week)/10*16+(week)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x8a,temp);//向DS1302内写周寄存器8aH写入调整后的周数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+0x0e);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 5:ri--;
switch(yue)
{
case 1:case 3:case 5:case 7:case 8:case 10:case 12:
if(ri==0) ri=31;
break;
case 2: if(nian%4==0||nian%400==0)
{
if(ri==0) ri=29;
}
else
{
if(ri==0) ri=28;
}break;
case 4:case 6:case 9:case 11:
if(ri==0) ri=30;
break;
}
write_nyr(9,ri);
temp=(ri)/10*16+(ri)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x86,temp);//向DS1302内写日期寄存器86H写入调整后的日期数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+10);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 6:yue--;
if(yue==0)
yue=12;
write_nyr(6,yue);
temp=(yue)/10*16+(yue)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x88,temp);//向DS1302内写月份寄存器88H写入调整后的月份数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+7);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 7:nian--;
if(nian==-1)
nian=99;
write_nyr(3,nian);
temp=(nian)/10*16+(nian)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x8c,temp);//向DS1302内写年份寄存器8cH写入调整后的年份数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+4);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 8: write_1602com(er+9); //设置闹钟的秒定时
miao1--;
if(miao1==-1)
miao1=59;
write_sfm(0x08,miao1);//令LCD在正确位置显示"加"设定好秒的数据
write_1602com(er+9);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置
break;
case 9: write_1602com(er+6); //设置闹钟的分钟定时
fen1--;
if(fen1==-1)
fen1=59;
write_sfm(0x05,fen1);//令LCD在正确位置显示"加"设定好的分数据
write_1602com(er+6);//因为设置液晶的模式是写入数据后,指针自动加一,
在这里是写回原来的位置
break;
case 10: write_1602com(er+3); //设置闹钟的小时定时
shi1--;
if(shi1==-1)
shi1=23;
write_sfm(0x02,shi1);//令LCD在正确的位置显示"加"设定好的小时数据 write_1602com(er+3);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
}
}
}
}
}//*******************主函数**************************
//***************************************************
void main()
{
lcd_init(); //调用液晶屏初始化子函数
ds1302_init(); //调用DS1302时钟的初始化子函数
init(); //调用定时计数器的设置子函数
led=0; //打开LCD的背光电源
buzzer=0;//蜂鸣器长响一次
delay(80);
buzzer=1;
while(1) //无限循环下面的语句:
{
keyscan(); //调用键盘扫描子函数
}
}/*************通过定时中断实现定是独处并显示数据******************/
void timer0() interrupt 1 //取得并显示日历和时间
{
//Init_DS18B20();//温度传感器DS18b2初始化子函数,在头文件中
flag=ReadTemperature();//将18b2头文件运行返回的函数结果送到变量FLAG中,用于
显示
//读取秒时分周日月年七个数据(DS1302的读寄存器与写寄存器不一样):
miao = BCD_Decimal(read_1302(0x81));
fen = BCD_Decimal(read_1302(0x83));
shi = BCD_Decimal(read_1302(0x85));
ri = BCD_Decimal(read_1302(0x87));
yue = BCD_Decimal(read_1302(0x89));
nian=BCD_Decimal(read_1302(0x8d));
week=BCD_Decimal(read_1302(0x8b));
//显示温度、秒、时、分数据:
write_temp(12,flag);//显示温度,从第二行第12个字符后开始显示
write_sfm(8,miao);//秒,从第二行第8个字后开始显示(调用时分秒显示子函数) write_sfm(5,fen);//分,从第二行第5个字符后开始显示
write_sfm(2,shi);//小时,从第二行第2个字符后开始显示
//显示日、月、年数据:
write_nyr(9,ri);//日期,从第二行第9个字符后开始显示
write_nyr(6,yue);//月份,从第二行第6个字符后开始显示
write_nyr(3,nian);//年,从第二行第3个字符后开始显示
write_week(week);
/***********整点报时程序************/
if(fen==0&&miao==0)
if(shi<22&&shi>6 )
{
buzzer=0;//蜂鸣器短响一次
delay(20);
buzzer=1;
}
/**************闹钟程序: 将暂停键按下停止蜂鸣********************/
if(shi1==shi&&fen1==fen&&miao==0)
{
clock=1;
}
if(clock==1)
{
buzzer=0;//蜂鸣器短响一次
delay(20);
buzzer=1;
}
if(CLO==0) /*按下p1.3停止蜂鸣*/
clock=0;
}
四:心得体会
编程其实是一件艺术,自己在里面任意发挥,自主创新,实现自己的目的。编程的感觉是很美妙的,很能增强我们的自信心。编程又是十分重要的,生活中无处不见程序,各种自动控制都用到程序,很有用,自己把编程学好就能成为一个有技术的人,成功的人,所以要加强编程,在大学期间让自己的代码量达到一定的高度,从而产生从量变到质变的效果,对自己的以后很有帮助。把编程当成一个游戏来玩,和电脑直接对话,在千百次的调试中发现自己犯的错误,了解程序的执行过程,意外发现一些自己不知道的东西,这是很有收获的!时常编程,时常把自己想到的问题用程序来实现,在学习期间我就不会寂寞,也会不断肯定自己,不断提高自己!
本次试验使我对DS1302、DS18B20、单片机定时功能等有了更深的认识。在反复调试的过程中更是锻炼了我的耐心,以及培养了我对编程的强烈兴趣。尤其是闰年、平年二月日期的显示问题,此问题我最初根本就没有考虑到,在最后才解决。虽然编写过程中有参考其他程序,而且有些子程序(如DS1802、LCD)是直接调用的,但的的确确在理解的程度上完成了主程序。也因此觉得自己的实验是对自己负责的,并非盲目COPY完成的,也使得自己的编程能力提高了一些,只是我还是比较习惯用C语言编程,汇编能力还有待加强哦,O(∩_∩)O~!相比硬件,我想我还是更喜欢编程滴,虽然有些纠结,虽然自己现有的知识甚是缺乏,嘿嘿!所以,我今后定会更加努力的学习相关理论知识,并运用于实践中,加油!~
五 > 单片机课程设计报告
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063G26032_1.jpg">
单片机课程设计报告
万年历的设计
姓 名:学 号: 0915321028 班 级: 09自动化 指导教师:晏来成
单片机课程设计摘要 单片机课程设计报告
基于51单片机的万年历
摘要:
电子万年历是一种非常广泛日常计时工具,对现代社会越来越流行。(]它可以对年、月、日、周日、时、分、秒进行计时,使用寿命长,误差小。对于数字电子万年历采用直观的数字显示,可以同时显示年、月、日、周日、时、分、秒和温度等信息,还具有时间校准等功能。该电路采用AT89S52单片机作为核心,功耗小,能在3V的低压工作,电压可选用3~5V电压供电。
本设计是基于51系列的单片机进行的电子万年历设计,可以显示年月日时分秒及周信息,具有可调整日期和时间功能。在设计的同时对单片机的理论基础和外围扩展知识进行了比较全面准备。万年历的设计过程在硬件与软件方面进行同步设计。硬件部分主要由AT89C52单片机,LCD显示电路,以及调时按键电路等组成。在单片机的选择上本人使用了AT89C52单片机,该单片机适合于许多较为复杂控制应用场合。显示器使用了1602液晶显示,并且使用蜂鸣器实现了整点报警的功能,温度测试的功能实现使用了DS18B20,
单片机课程设计摘要 单片机课程设计报告
并实现了温度过高或过低时的温度报警。[)
软件方面主要包括日历程序、时间调整程序,显示程序等。程序采用C语言编写。所有程序编写完成后,在KeilC51软件中进行调试,确定没有问题后,在Proteus软件中嵌入单片机内进行仿真,并最终实现基本要求。
综上所述此万年历具有读取方便、显示直观、功能多样、电路简洁、成本低廉等诸多优点,符合电子仪器仪表的发展趋势,具有广阔的市场前景。
一、设计要求
基本要求:
1,8 个数码管上显示,显示时间的格式为(假如当前时间是19:32:20)“19-32-20”;
2,具有日历功能;
③ 时间可以通过按键调整。
发挥部分:
④ 具有闹钟功能(可以设定多个)。
二:总体设计
电路设计框图
单片机课程设计摘要 单片机课程设计报告
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063FG3b_1.jpg">
系统硬件概述
本电路是由AT89S52单片机为控制核心,具有在线编程功能,低功耗,能在3V超低压工作;时钟电路由单片机定时功能提供;温度的采集由DS18B20构成,它具有独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯,使用时不需要额外的外围电路。()并且,其测温范围 -55℃~+125℃,固有测温分辨率0.5℃;显示部份使用1602液晶显示,可完美地显示年、月、日、周日、时、分、秒,且在整点时刻通过蜂鸣器实现响铃。还可以实现温度显示,且当判断得温度过高或过低时,通过液晶显示及LED发光二极管完成报警。
单片机主控制模块的设计
AT89S52单片机为40引脚双列直插芯片,有四个I/O口P0,P1,P2,P3, MCS-51单片机共有4个8位的I/O口(P0、P1、P2、
单片机课程设计摘要 单片机课程设计报告
P3),每一条I/O线都能独立地作输出或输入。()
单片机的最小系统如下图所示,18引脚和19引脚接时钟电路,XTAL1接外部晶振和微调电容的一端,在片内它是振荡器倒相放大器的输入,XTAL2接外部晶振和微调电容的另一端,在片内它是振荡器倒相放大器的输出.第9引脚为复位输入端,接上电容,电阻及开关后够上电复位电路,20引脚为接地端,40引脚为电源端.
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063F33346_1.jpg">
液晶显示模块的设计
LCD1602有16个引脚,其中VCC、VSS分别为电源正负极;VO为液晶偏压信号输入端,图中W1可调节液晶明亮度; DB0—DB7 8位数据段;BLA、BLK背光源正负极; RS数据/命令选择端;R/W读写选择端;E使能端
单片机课程设计摘要 单片机课程设计报告
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063FG3b_0.jpg">
温度采集模块设计
采用数字式温度传感器DS18B20,它是数字式温度传感器,具有测量精度高,电路连接简单特点,,此类传感器仅需要一条数据线进行数据传输,使用P0.7与DS18B20的I/O口连接加一个上拉电阻,Vcc接电源,Vss接地。()
PCB图
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063A91L8_1.jpg">
三电子时钟的软件设计
系统软件按键检测流程图
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063F33346_0.jpg">
单片机课程设计摘要 单片机课程设计报告
系统软件定时器程序流程图
<mip-img src="http://www.bigengculture.com/uploads/allimg/180511/063A91L8_0.jpg">
单片机课程设计摘要 单片机课程设计报告
子程序的设计
DS18B20温度子程序
void write_temp(uchar add,uchar dat)//向LCD写温度数据,并指定显示位置 {
uchar gw,sw,bw;
if(dat>=0&&dat<=128)
{
gw=dat%10;//取得个位数字
sw=dat%100/10;//取得十位数字
bw=dat/100 ;//取得百位数字
}
else
{
dat=256-dat;
gw=dat%10;//取得个位数字
sw=dat%100/10;//取得十位数字
bw=-3; //0x30-3表示为负号
}
write_1602com(er+add);//er是头文件规定的值0x80+0x40
write_1602dat(0x30+bw);//数字+30得到该数字的LCD1602显示码 write_1602dat(0x30+sw);//数字+30得到该数字的LCD1602显示码 write_1602dat(0x30+gw);//数字+30得到该数字的LCD1602显示码
单片机课程设计摘要 单片机课程设计报告
write_1602dat(0xdf);//显示温度的小圆圈符号,0xdf是液晶屏字符库的该符号地址码
write_1602dat(0x43); //显示"C"符号,0x43是液晶屏字符库里大写C的地址码
}
1602子程序
void write_byte(uchar dat)//写一个字节
{
ACC=dat;
RST=1;
for(a=8;a>0;a--)
{
IO=ACC0;
SCLK=0;
SCLK=1;
ACC=ACC>>1;
}
}
uchar read_byte()//读一个字节
{
RST=1;
for(a=8;a>0;a--)
{
ACC7=IO;
SCLK=1;
SCLK=0;
ACC=ACC>>1;
}
return (ACC);
}
//----------------------------------------
void write_1302(uchar add,uchar dat)//向1302芯片写函数,指定写入地址,数据 {
RST=0;
SCLK=0;
RST=1;
write_byte(add);
write_byte(dat);
SCLK=1;
RST=0;
}
单片机课程设计摘要 单片机课程设计报告
uchar read_1302(uchar add)//从1302读数据函数,指定读取数据来源地址
{
uchar temp;
RST=0;
SCLK=0;
RST=1;
write_byte(add);
temp=read_byte();
SCLK=1;
RST=0;
return(temp);
}
uchar BCD_Decimal(uchar bcd)//BCD码转十进制函数,输入BCD,返回十进制 {
uchar Decimal;
Decimal=bcd>>4;
return(Decimal=Decimal*10+(bcd&=0x0F));
}
//--------------------------------------
void ds1302_init() //1302芯片初始化子函数(2010-01-07,12:00:00,week4) {
RST=0;
SCLK=0;
write_1302(0x8e,0x00); //允许写,禁止写保护
write_1302(0x80,0x00); //向DS1302内写秒寄存器80H写入初始秒数据00
write_1302(0x82,0x00);//向DS1302内写分寄存器82H写入初始分数据00
write_1302(0x84,0x12);//向DS1302内写小时寄存器84H写入初始小时数据12 write_1302(0x8a,0x01);//向DS1302内写周寄存器8aH写入初始周数据4
write_1302(0x86,0x08);//向DS1302内写日期寄存器86H写入初始日期数据07 write_1302(0x88,0x07);//向DS1302内写月份寄存器88H写入初始月份数据01 write_1302(0x8c,0x10);//向DS1302内写年份寄存器8cH写入初始年份数据10 write_1302(0x8e,0x80); //打开写保护
}
时分秒显示子函数
void write_sfm(uchar add,uchar dat)//向LCD写时分秒,有显示位置加、现示数据,两个参数
{
uchar gw,sw;
gw=dat%10;//取得个位数字
sw=dat/10;//取得十位数字
单片机课程设计摘要 单片机课程设计报告
write_1602com(er+add);//er是头文件规定的值0x80+0x40
write_1602dat(0x30+sw);//数字+30得到该数字的LCD1602显示码
write_1602dat(0x30+gw);//数字+30得到该数字的LCD1602显示码
}
//-------------------------------------
//年月日显示子函数
void write_nyr(uchar add,uchar dat)//向LCD写年月日,有显示位置加数、显示数据,两个参数
{
uchar gw,sw;
gw=dat%10;//取得个位数字
sw=dat/10;//取得十位数字
write_1602com(yh+add);//设定显示位置为第一个位置+add
write_1602dat(0x30+sw);//数字+30得到该数字的LCD1602显示码
write_1602dat(0x30+gw);//数字+30得到该数字的LCD1602显示码
}
//-------------------------------------------
void write_week(uchar week)//写星期函数
{
write_1602com(yh+0x0c);//星期字符的显示位置
switch(week)
{
case 1:write_1602dat('M');//星期数为1时,显示
write_1602dat('O');
write_1602dat('N');
break;
case 2:write_1602dat('T');//星期数据为2时显示
write_1602dat('U');
write_1602dat('E');
break;
case 3:write_1602dat('W');//星期数据为3时显示
write_1602dat('E');
write_1602dat('D');
break;
case 4:write_1602dat('T');//星期数据为4是显示
write_1602dat('H');
单片机课程设计摘要 单片机课程设计报告
write_1602dat('U');
break;
case 5:write_1602dat('F');//星期数据为5时显示
write_1602dat('R');
write_1602dat('I');
break;
case 6:write_1602dat('S');//星期数据为6时显示
write_1602dat('T');
write_1602dat('A');
break;
case 7:write_1602dat('S');//星期数据为7时显示
write_1602dat('U');
write_1602dat('N');
break;
定时器0初始化程序
void init() //定时器、计数器设置函数
{
TMOD=0x11; //指定定时/计数器的工作方式为1
TH0=0; //定时器T0的高四位=0
TL0=0; //定时器T0的低四位=0
EA=1; //系统允许有开放的中断
ET0=1; //允许T0中断
TR0=1; //开启中断,启动定时器
}
}
//****************键盘扫描有关函数**********************
void keyscan()
{
if(key1==0)//---------------key1为功能键(设置键)-------------------- {
delay(9);//延时,用于消抖动
if(key1==0)//延时后再次确认按键按下
{
buzzer=0;//蜂鸣器短响一次
delay(20);
buzzer=1;
while(!key1);
key1n++;
单片机课程设计摘要 单片机课程设计报告
if(key1n==12) key1n=1;//设置按键共有秒、分、时、星期、日、月、年、返回,8个功能循环 switch(key1n) { case 1: TR0=0;//关闭定时器 //TR1=0; write_1602com(er+0x09);//设置按键按动一次,秒位置显示光标 write_1602com(0x0f);//设置光标为闪烁 temp=(miao)/10*16+(miao)%10;//秒数据写入DS1302 write_1302(0x8e,0x00); write_1302(0x80,0x80|temp);//miao write_1302(0x8e,0x80); break; case 2: write_1602com(er+6);//按2次fen位置显示光标 //write_1602com(0x0f); break; case 3: write_1602com(er+3);//按动3次,shi //write_1602com(0x0f); break; case 4: write_1602com(yh+0x0e);//按动4次,week //write_1602com(0x0f); break; case 5: write_1602com(yh+0x0a);//按动5次,ri //write_1602com(0x0f); break; case 6: write_1602com(yh+0x07);//按动6次,yue //write_1602com(0x0f); break; case 7: write_1602com(yh+0x04);//按动7次,nian //write_1602com(0x0f); break; case 8: write_1602com(er+1); write_1602dat(0x4d); write_1602com(er+1); break; case 9: write_1602com(er+1); write_1602dat(0x46); write_1602com(er+1); break; case 10:write_1602com(er+1); write_1602dat(0x53);
单片机课程设计摘要 单片机课程设计报告
write_1602com(er+1);
break;
case 11:
write_1602com(er+1);
write_1602dat(0x20);
write_1602com(0x0c);//按动到第8次,设置光标不闪烁
TR0=1;//打开定时器
temp=(miao)/10*16+(miao)%10;
write_1302(0x8e,0x00);
write_1302(0x80,0x00|temp);//miao数据写入DS1302
write_1302(0x8e,0x80);
break;
}
}
}
//------------------------------加键key2---------------------------- if(key1n!=0)//当key1按下以下。[)再按以下键才有效(按键次数不等于零) {
if(key2==0) //上调键
{
delay(10);
if(key2==0)
{
buzzer=0;//蜂鸣器短响一次
delay(20);
buzzer=1;
while(!key2);
switch(key1n)
{
case 1:miao++;//设置键按动1次,调秒
if(miao==60)
miao=0;//秒超过59,再加1,就归零
write_sfm(0x08,miao);//令LCD在正确位置显示"加"设定好的秒数 temp=(miao)/10*16+(miao)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00); //允许写,禁止写保护
write_1302(0x80,temp); //向DS1302内写秒寄存器80H写入调整后的秒数据BCD码
write_1302(0x8e,0x80); //打开写保护
单片机课程设计摘要 单片机课程设计报告
write_1602com(er+0x09);//因为设置液晶的模式是写入数据后,光标自动右移,所以要指定返回
//write_1602com(0x0b);
break;
case 2:fen++;
if(fen==60)
fen=0;
write_sfm(0x05,fen);//令LCD在正确位置显示"加"设定好的分数据 temp=(fen)/10*16+(fen)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x82,temp);//向DS1302内写分寄存器82H写入调整后的分数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(er+6);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置
break;
case 3:shi++;
if(shi==24)
shi=0;
write_sfm(2,shi);//令LCD在正确的位置显示"加"设定好的小时数据 temp=(shi)/10*16+(shi)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x84,temp);//向DS1302内写小时寄存器84H写入调整后的小时数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(er+3);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 4:week++;
if(week==8)
week=1;
write_1602com(yh+0x0C);//指定'加'后的周数据显示位置
write_week(week);//指定周数据显示内容
temp=(week)/10*16+(week)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x8a,temp);//向DS1302内写周寄存器8aH写入调整后的周数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+0x0e);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 5:ri++;
switch(yue)
{
单片机课程设计摘要 单片机课程设计报告
case 1:case 3:case 5:case 7:case 8:case 10:case 12:
if(ri>31) ri=1;
break;
case 2:
if(nian%4==0||nian%400==0)
{
if(ri>29) ri=1;
}
else
{
if(ri>28) ri=1;
}break;
case 4:case 6:case 9:case 11:
ri++;
if(ri>30) ri=1;
break;
}
write_nyr(9,ri);//令LCD在正确的位置显示"加"设定好的日期数据 temp=(ri)/10*16+(ri)%10;//十进制转换成DS1302要求的DCB码
write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x86,temp);//向DS1302内写日期寄存器86H写入调整后的日期数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+10);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 6:yue++;
if(yue==13)
yue=1;
write_nyr(6,yue);//令LCD在正确的位置显示"加"设定好的月份数据 temp=(yue)/10*16+(yue)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x88,temp);//向DS1302内写月份寄存器88H写入调整后的月份数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+7);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 7:nian++;
if(nian==100)
单片机课程设计摘要 单片机课程设计报告
nian=0;
write_nyr(3,nian);//令LCD在正确的位置显示"加"设定好的年份数据 temp=(nian)/10*16+(nian)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x8c,temp);//向DS1302内写年份寄存器8cH写入调整后的年份数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+4);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 8: write_1602com(er+9); //设置闹钟的秒定时
miao1++;
if(miao1==60)
miao1=0;
write_sfm(0x08,miao1);//令LCD在正确位置显示"加"设定好秒的数据
write_1602com(er+9);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置
break;
case 9: write_1602com(er+6); //设置闹钟的分钟定时
fen1++;
if(fen1==60)
fen1=0;
write_sfm(0x05,fen1);//令LCD在正确位置显示"加"设定好的分数据
write_1602com(er+6);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置
break;
case 10: write_1602com(er+3); //设置闹钟的小时定时
shi1++;
if(shi1==24)
shi1=0;
write_sfm(0x02,shi1);//令LCD在正确的位置显示"加"设定好的小时数据 write_1602com(er+3);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
}
}
}
//------------------减键key3,各句功能参照'加键'注释--------------- if(key3==0)
{
单片机课程设计摘要 单片机课程设计报告
delay(10);//调延时,消抖动
if(key3==0)
{
buzzer=0;//蜂鸣器短响一次
delay(20);
buzzer=1;
while(!key3);
switch(key1n)
{
case 1:miao--;
if(miao==-1)
miao=59;//秒数据减到-1时自动变成59
write_sfm(0x08,miao);//在LCD的正确位置显示改变后新的秒数 temp=(miao)/10*16+(miao)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00); //允许写,禁止写保护
write_1302(0x80,temp); //向DS1302内写秒寄存器80H写入调整后的秒数据BCD码
write_1302(0x8e,0x80); //打开写保护
write_1602com(er+0x09);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置
//write_1602com(0x0b);
break;
case 2:fen--;
if(fen==-1)
fen=59;
write_sfm(5,fen);
temp=(fen)/10*16+(fen)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x82,temp);//向DS1302内写分寄存器82H写入调整后的分数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(er+6);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置
break;
case 3:shi--;
if(shi==-1)
shi=23;
write_sfm(2,shi);
temp=(shi)/10*16+(shi)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x84,temp);//向DS1302内写小时寄存器84H写入调整后的小时数据BCD码
write_1302(0x8e,0x80);//打开写保护
单片机课程设计摘要 单片机课程设计报告
write_1602com(er+3);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 4:week--;
if(week==0)
week=7;
write_1602com(yh+0x0C);//指定'加'后的周数据显示位置
write_week(week);//指定周数据显示内容
temp=(week)/10*16+(week)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x8a,temp);//向DS1302内写周寄存器8aH写入调整后的周数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+0x0e);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 5:ri--;
switch(yue)
{
case 1:case 3:case 5:case 7:case 8:case 10:case 12:
if(ri==0) ri=31;
break;
case 2: if(nian%4==0||nian%400==0)
{
if(ri==0) ri=29;
}
else
{
if(ri==0) ri=28;
}break;
case 4:case 6:case 9:case 11:
if(ri==0) ri=30;
break;
}
write_nyr(9,ri);
temp=(ri)/10*16+(ri)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
单片机课程设计摘要 单片机课程设计报告
write_1302(0x86,temp);//向DS1302内写日期寄存器86H写入调整后的日期数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+10);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 6:yue--;
if(yue==0)
yue=12;
write_nyr(6,yue);
temp=(yue)/10*16+(yue)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x88,temp);//向DS1302内写月份寄存器88H写入调整后的月份数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+7);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 7:nian--;
if(nian==-1)
nian=99;
write_nyr(3,nian);
temp=(nian)/10*16+(nian)%10;//十进制转换成DS1302要求的DCB码 write_1302(0x8e,0x00);//允许写,禁止写保护
write_1302(0x8c,temp);//向DS1302内写年份寄存器8cH写入调整后的年份数据BCD码
write_1302(0x8e,0x80);//打开写保护
write_1602com(yh+4);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
case 8: write_1602com(er+9); //设置闹钟的秒定时
miao1--;
if(miao1==-1)
miao1=59;
write_sfm(0x08,miao1);//令LCD在正确位置显示"加"设定好秒的数据
write_1602com(er+9);//因为设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置
break;
case 9: write_1602com(er+6); //设置闹钟的分钟定时
fen1--;
if(fen1==-1)
fen1=59;
write_sfm(0x05,fen1);//令LCD在正确位置显示"加"设定好的分数据
write_1602com(er+6);//因为设置液晶的模式是写入数据后,指针自动加一,
单片机课程设计摘要 单片机课程设计报告
在这里是写回原来的位置
break;
case 10: write_1602com(er+3); //设置闹钟的小时定时
shi1--;
if(shi1==-1)
shi1=23;
write_sfm(0x02,shi1);//令LCD在正确的位置显示"加"设定好的小时数据 write_1602com(er+3);//因为设置液晶的模式是写入数据后,指针自动加一,所以需要光标回位
break;
}
}
}
}
}//*******************主函数**************************
//***************************************************
void main()
{
lcd_init(); //调用液晶屏初始化子函数
ds1302_init(); //调用DS1302时钟的初始化子函数
init(); //调用定时计数器的设置子函数
led=0; //打开LCD的背光电源
buzzer=0;//蜂鸣器长响一次
delay(80);
buzzer=1;
while(1) //无限循环下面的语句:
{
keyscan(); //调用键盘扫描子函数
}
}/*************通过定时中断实现定是独处并显示数据******************/
void timer0() interrupt 1 //取得并显示日历和时间
{
//Init_DS18B20();//温度传感器DS18b2初始化子函数,在头文件中
flag=ReadTemperature();//将18b2头文件运行返回的函数结果送到变量FLAG中,用于
单片机课程设计摘要 单片机课程设计报告
显示
//读取秒时分周日月年七个数据(DS1302的读寄存器与写寄存器不一样):
miao = BCD_Decimal(read_1302(0x81));
fen = BCD_Decimal(read_1302(0x83));
shi = BCD_Decimal(read_1302(0x85));
ri = BCD_Decimal(read_1302(0x87));
yue = BCD_Decimal(read_1302(0x89));
nian=BCD_Decimal(read_1302(0x8d));
week=BCD_Decimal(read_1302(0x8b));
//显示温度、秒、时、分数据:
write_temp(12,flag);//显示温度,从第二行第12个字符后开始显示
write_sfm(8,miao);//秒,从第二行第8个字后开始显示(调用时分秒显示子函数) write_sfm(5,fen);//分,从第二行第5个字符后开始显示
write_sfm(2,shi);//小时,从第二行第2个字符后开始显示
//显示日、月、年数据:
write_nyr(9,ri);//日期,从第二行第9个字符后开始显示
write_nyr(6,yue);//月份,从第二行第6个字符后开始显示
write_nyr(3,nian);//年,从第二行第3个字符后开始显示
write_week(week);
/***********整点报时程序************/
if(fen==0&&miao==0)
if(shi<22&&shi>6 )
{
buzzer=0;//蜂鸣器短响一次
delay(20);
buzzer=1;
}
/**************闹钟程序: 将暂停键按下停止蜂鸣********************/
if(shi1==shi&&fen1==fen&&miao==0)
{
clock=1;
}
if(clock==1)
{
buzzer=0;//蜂鸣器短响一次
delay(20);
buzzer=1;
单片机课程设计摘要 单片机课程设计报告
}
if(CLO==0) /*按下p1.3停止蜂鸣*/
clock=0;
}
四:心得体会
编程其实是一件艺术,自己在里面任意发挥,自主创新,实现自己的目的。[]编程的感觉是很美妙的,很能增强我们的自信心。编程又是十分重要的,生活中无处不见程序,各种自动控制都用到程序,很有用,自己把编程学好就能成为一个有技术的人,成功的人,所以要加强编程,在大学期间让自己的代码量达到一定的高度,从而产生从量变到质变的效果,对自己的以后很有帮助。把编程当成一个游戏来玩,和电脑直接对话,在千百次的调试中发现自己犯的错误,了解程序的执行过程,意外发现一些自己不知道的东西,这是很有收获的!时常编程,时常把自己想到的问题用程序来实现,在学习期间我就不会寂寞,也会不断肯定自己,不断提高自己!
本次试验使我对DS1302、DS18B20、单片机定时功能等有了更深的认识。在反复调试的过程中更是锻炼了我的耐心,以及培养了我对编程的强烈兴趣。尤其是闰年、平年二月日期的显示问题,此问题我最初根本就没有考虑到,在最后才解决。虽然编写过程中有参考其他程序,而且有些子程序(如DS1802、LCD)是直接调用的,但的的确确在理解的程度上完成了主程序。也因此觉得自己的实验是对自己负责的,并非盲目COPY完成的,也使得自己的编程能力提高了一些,只是我还是比较习惯用C语言编程,汇编能力还有待加强哦,O(∩_∩)O~!相比硬件,我想我还是更喜欢编程滴,虽然有些纠结,虽然自己现有的知识甚是缺乏,嘿嘿!所以,我今后定会更加努力的学习相关理论知识,并运用于实践中,加油!~
单片机课程设计摘要 单片机课程设计报告
[)
本文编号:1872826
本文链接:https://www.wllwen.com/wenshubaike/mfmb/1872826.html