基于STC15W4K58S4单片机的电子万年历(数码管显示)该压缩包包含源码TXT文件 源工程文件(Keil uVision4文件)和课程设计报告
电子时钟的设计
—单片机综合设计报告
目录
1 任务内容
2 系统框图
3 硬件电路图
4 软件流程图
5 结束语
附录1:实际效果图
附录2:源程序
参考文献
1 任务内容 设计一个基于单片机的电子万年历,能够在数码管显示时间、日期、星期、闹钟、秒表等信息。并且具备通过独立按键调整时间、日期、闹钟、自动判闰年、自动判断星期等功能。 通过采用单片机内部定时器实现基础时间单位的变化与独立按键输入; 采用C语言编写主要功能(日历程序、时间调整程序、显示程序、按键扫描程序等),再在Keil uVision4 中进行调试,确保无问题后在实验电路板上进行实物仿真调试。 2 系统框图
图2-1电子时钟总体设计框图
3 硬件电路图 图3-1电子时钟硬件总电路图 图3-2电子时钟数码管电路图 图3-3电子时钟独立按键电路图 图3-4电子时钟蜂鸣器电路图
4 软件流程图 主程序流程图: 主函数中循环等待按键与功能判断,flag1(key1)为菜单键,可选择3个功能模块分别为校准时间,秒表和设置闹钟。flag2(key2)为分屏键,按一次可循环显示年月日和星期(例如:2018-5-29 [2]),按二次为返回。主函数默认状态下为显示时分秒(例如:20-18-09),同时自动判断闹钟时间是否到点,到点则蜂鸣器发出声响,默认发出声响连续时间为1分钟,也可按下flag3(key3)强制关闭蜂鸣器。 
图4-1电子时钟主程序流程图 校准时间/闹钟设置子流程图: 校准时间功能模块中flag2(key2)为移位键,控制当前校准的日期时间单位,并且此位会已局部闪屏的方式反馈给操作者。flag3(key3)与flag4 (key4)分别为加减和减键,控制当前日期时间单位的加减操作(设置闹钟模块与之类似)。 
图4-2电子时钟校准时间/设置闹钟流程图 秒表子流程图: 秒表模块中flag2(key2)为暂停或计数键控制秒表的暂停计时和开始计时,flag3(key3)为清零键控制秒表计数的清零操作。 
图4-3电子时钟秒表流程图
中断计时流程图: 通过中断控制进行时间的计时操作,不占用CPU,通过芯片内部晶振溢出计时,能够较精准的计时。软件程序中从日期时间单位的最小单位秒开始自动逐步更新但前的时间,年月日和星期。通过软件程序与硬件的结合,较好的达到电子时钟的功能和效果。 
图4-4电子时钟中断计时流程图
5 结束语 在此次电子时钟的课程设计中,收获良多。刚拿到课题时,就比较有兴趣。大致想了一下思路,就开始着手写代码,因为这是第一次使用Keil uVision4软件编写程序,对该软件的编译环境和编码规则不太了解。初始阶段中运行程序出现了许许多多的问题,比如函数重复定义,变量重复定义,数组溢出,未定义变量,定义函数未调用等等,自己的思维不严谨写完代码总是一大堆错误和警告,通过慢慢调试,查找错误,并把自己的思维逻辑慢慢完善,最终解决了所有的错误与警告。时钟的大至此我对Keil uVision4软件也渐渐从陌生到熟悉。电子时钟的大致的框架也基本完成了,但是该电子时钟的功能比较单一,并且不太人性化。于是开始版本升级和优化代码,加入一些其他附带功能(如:闹钟,秒表,显示星期等)和比较人性化的东西(如:循环显示年月日和星期,带闪屏提示的校准时间和设置闹钟,闰年判断等)。然后,就是上试验箱调自己的电子时钟的实际效果与功能实现。第一次下载在实验箱上运行的时候。很快就发现了问题,发现时间未变化。于是我就开始调试,发现管脚分配有问题,改完之后再次下载到实验版观察现象。发现实际效果与自己所希望的效果完全一样。看着自己设计的电子时钟得以实现,还是非常开心的。 回想这一路的设计到实现的过程,我们综合那些理论知识来运用到设计和创新,同时还让我们明白了一个团队凝聚在一起时所能发挥出的巨大潜能! 在此次课程设计中我比较擅长C语言,有一定的编程能力。队友比较擅长报告文档的编写,我们相互合作,一起交流,共同进步,完成了课程设计。队友的编程能力得到了一定的提高,我的报告文档编写能力也得到了提高。此外通过查找大量资料,请教老师,以及不懈的努力,不仅培养了独立思考、 动手制作的能力,在各种其它能力上也都有了一定的提高。更重要的是,在课程设计中,我们学会了很多学习的方法,知道了理论和实践的巨大差别。而这是以后最实用的,真的是受益匪浅。要面对社会的挑战,只有不断的学习、实践,再学习、再实践。同时在与老师和同学的交流过程中,互动学习,将知识融会贯通。通过自己的努力,将自己的想要达到的效果都得以实现,做出了一个包含自己的想法的万年历,对以后的学习是一个莫大的鼓舞,激起了我的学习兴趣和开发创新思维。
附录1:实际效果图
 图1-1时-分-秒 显示效果图图1-2年-月-日 [星期] 显示效果图(循环显示) 附录2:源程序 - //********************************************************************************************
- //主函数 main.c
- //********************************************************************************************
- #include "LED_595DISP.h"
- #include "keyboard.h"
- #include "timer.h"
- #include <intrins.h>
- sbit sound=P1^3;//蜂鸣器(LED灯代替)
- unsigned char xdata tem[20] ;//显示中间转换
- unsigned int xdata dy[6][2]={{0,0},{5,6},{8,9},{11,12},{14,15},{17,18}};//校准 设置闹钟 转换
- unsigned int xdata LZX[6];//闹钟
- unsigned char i,j,bj;
- unsigned char wz;// 校准/设置 位置
- void Date_XS(void); //日期显示
- void time_XS(void); //时间显示
- void Delay500ms(void);//循环显示延时
- void Delay21ms();//秒表延时
- void fuz(void); //附值函数 用于校准/设置
- void Date_LZ(void); //闹钟函数
- void Date_JZ(void); //校准函数
- int fmq(void);// 蜂鸣器启动判断
- void mbtemr(); //秒表计时
- void miaobiao(void);
- void main(void)
- {
- Timer0Init();
- while(1) //任务主循环
- { Key_scan(); //按键识别
- //实时显示
- if(flag1) //菜单键
- {
- if(flag1==1)Date_JZ(); //功能1 校对时间
- if(flag1==2) miaobiao(); //功能2 秒表
- if(flag1==3)Date_LZ(); //功能3 设置闹钟
- }
- else if(flag2)Date_XS(); //查看日期 星期
- else time_XS(); //查看时间
- //蜂鸣器启动判断
- if(fmq())bj=150;
- if(flag3||flag4)bj=0; // 蜂鸣器启器强制关闭
- if(bj){sound=0,bj--; } //或响应时间结束
- else sound=1;
-
- LED_Display();
- }
- }
- void time_XS(void)//时间显示
- {
- tem[0]=Date[3]/10;
- tem[1]=Date[3]%10;
- tem[2]=17;
- tem[3]=Date[4]/10;
- tem[4]=Date[4]%10;
- tem[5]=17;
- tem[6]=Date[5]/10;
- tem[7]=Date[5]%10;
- for(i=0;i<8;i++)
- Dis_buf[i]=tem[i];
- Key_scan(); //按键识别
- LED_Display(); //实时显示
- }
- void Date_XS(void) //日期 星期显示
- {
- tem[0]=Date[0]/1000; //年
- tem[1]=Date[0]%1000/100;
- tem[2]=Date[0]%100/10;
- tem[3]=Date[0]%10;
- tem[4]=17;
- tem[5]=Date[1]/10; //月
- tem[6]=Date[1]%10;
- tem[7]=17;
- tem[8]=Date[2]/10; //日
- tem[9]=Date[2]%10;
- tem[10]=16;
- tem[11]=12;
- getxq();
- tem[12]=xq+1; //星期
- tem[13]=13;
- tem[14]=16;
- j=0;
- while(flag2)
- {
- for(i=0;i<8;i++)
- Dis_buf[i]=tem[(i+j)%15];
- LED_Display();
- Delay500ms();
- j=(j+1)%15;
- }
- }
- void Date_JZ(void)
- { unsigned char count1=0;fuz();wz=0;
- while(1)
- {
- Key_scan();
- if(flag1!=1){flag2=flag3=flag4=0;break;} //功能键(返回键)
- if(flag2){wz=(wz+1)%6;flag2=0;} //移位键
- if(flag3){Date[wz]++;flag3=0;} //加键
- if(flag4){Date[wz]--;flag4=0;} //减键
- //对更改数据进行 存储更新
- if(wz==1){if(Date[wz]<0)Date[wz]=12;if(Date[wz]>12)Date[wz]=1;}
- if(wz==2)Date_gx();
- if(wz==3){if(Date[wz]<0)Date[wz]=23;if(Date[wz]>=24)Date[wz] =0;}
- if(wz==4||wz==5){if(Date[wz]<0)Date[wz]=59;if(Date[wz]>=60)Date[wz]=0;}
- //对更改数据进行 显示更新
- if(wz==0) //更新 年
- {
- tem[0]=Date[0]/1000;
- tem[1]=Date[0]%1000/100;
- tem[2]=Date[0]%100/10;
- tem[3]=Date[0]%10;
- }
- else //更新其他
- {tem[dy[wz][0]]=Date[wz]/10;
- tem[dy[wz][1]]=Date[wz]%10;
- }
- //循环初始化
- if(wz==2)j=2;
- else if(wz>=3&&wz<=5)j=11;
- else j=0;
- //循环 带闪 显示
- for(i=0;i<8;i++)
- if(count1<5&&wz==0&&(i+j)%20==0)Dis_buf[i]=Dis_buf[i+1]=Dis_buf[i+2]=Dis_buf[i+3]=16,i=3;
- else if(count1<5&&dy[wz][0]==(i+j)%20)Dis_buf[i]=Dis_buf[i+1]=16,i++;
- else Dis_buf[i]=tem[(j+i)%20];
- if(count1==40)count1=0;//每40 显示 5 单位时间
- count1++;
- LED_Display(); //实时显示
-
- }
- }
复制代码 篇幅有限 子函数与完整程序在压缩包中
全部资料51hei下载地址:
单片机电子万年历设计.rar
(6.19 MB, 下载次数: 161)
|