可调时钟的闹钟模式(接上篇)
写在前面:
上篇文末提到可以优化的地方包括加入闹钟,了解无源蜂鸣器的工作原理后,就着手扩展闹钟设置功能了,同时按键按下加入蜂鸣器的提示音。由于上篇的篇幅过长了,所以决定单独写一篇这个闹钟模块。
一、实现思路
- 保持原有功能情况下加入第三个模式
- 当前模式下执行功能,设置时分秒,同样是选中位闪烁,增大减小,越界判断等可以直接照搬前面的
- 设置的时分秒存在一个数组,当当前时间的时分秒都与之对应相等调用蜂鸣器
- 按下任意独立按键可以终止闹钟
二、蜂鸣器
1、工作原理
普中的板子上的是无源蜂鸣器,BZ连接在了步进电机OUT5,ULN2003D逻辑框图如下
对于蜂鸣器驱动需要输入振荡脉冲,ULN2003D作用为继电器驱动,在这里我们只需要考虑输入取反输出即可,因此蜂鸣器连接对应51寄存器地址为P2_5(图和板子不一样)
sbit Buzzer = P2^5; //类型声明蜂鸣器地址
2、蜂鸣器响任意时间函数
循环体内使Buzzer每隔250us取反,一个周期为0.5ms,即2000HZ,循环执行次数决定持续时间,期间接收按键键码,只要键码不为0,即有任意独立按键按下,跳出循环,声音停止
#include <REGX52.H>
#include"Delay.h"
#include"Key.h"sbit Buzzer = P2^5; //类型声明蜂鸣器地址
unsigned int i; //计数/*** @brief 蜂鸣器以2000HZ的时间响x250us* @param xms 蜂鸣器响的时间* @retval 无*/
void Buzzer_Time(unsigned int x250us)
{unsigned KeyNumber;for(i=0;i<x250us;i++){KeyNumber = Key();Buzzer = !Buzzer; //振荡输入Delay10us(25); //高低电平维持时间为250us,一个周期就是0.5msif(KeyNumber)break;} }
封装好之后可以用于按键提示音和闹钟
三、代码设计和修改
1、预备工作
定义Clock_Sel为闹钟设置模式下的时间位索引,定义数组存放设置闹钟的时分秒
//存放设置的脑钟时间
char Clock[] = {0,0,0};
//定义键码、设置时间位索引、设置时间闪烁标志、模式(显示时间/设置时间),闹钟设置时间位索引
unsigned char KeyNum, TimeSet_Sel, TimeSetFlag, Mode, Clock_Sel;
2、增加模式
按下1键让Mode在0、1、2之间循环,为了保持原有设置时间功能(从设置时间模式切换到模式0时写入修改后的时间),将模式2作为设置时间模式,模式1为新增的设置闹钟时间。每次切换到闹钟模式时,闹钟时间位索引清0,固定从时开始设置,并且将LCD清空第一行显示“Clock:”
if(KeyNum == 1){Buzzer_Time(100); //蜂鸣器按键提示音if(Mode == 0){Mode = 1; //切换至设置闹钟模式LCD_Init();Delay(100);Clock_Sel = 0; //每次切换到设置闹钟索引清0}else if(Mode == 1 ){Mode = 2; //切换至设置时间模式TimeSet_Sel = 0; //每次切换到设置时间模式索引清0,固定从“年”开始闪烁}else if(Mode == 2){Mode = 0; //切换回显示时间模式DS1302_SetTime(); //将已修改的时间数据写入芯片 }}switch(Mode) //显示当前工作模式{case 0: LCD_ShowString(2,12,"Show ");break;case 1: LCD_ShowString(2,12,"Clock ");break;case 2: LCD_ShowString(2,12,"Set ");break;}
当Mode == 1时,执行设置闹钟模式代码
3、设置闹钟函数SetClock()
思路可以说是完全照搬了上一篇的设置时间函数,都是按2键索引++,3键当前时间位++,4键当前时间位--,越界判断和校正从之前的函数里截取了时分秒的部分,闪烁设置也是一样的,按键提示音在整个程序所有地方都加上了,没什么好说的直接贴代码
void SetClock(void)
{LCD_ShowString(1,1,"Clock:");LCD_ShowNum(1,13,Clock_Sel,2);if(KeyNum == 2) //2号按键选择设置的时间位{Buzzer_Time(100); //蜂鸣器按键提示音Clock_Sel++;Clock_Sel %= 3; //索引在0~1}if(KeyNum == 3) //3号按键使当前时间位+1{Buzzer_Time(100); //蜂鸣器按键提示音 Clock[Clock_Sel]++;if(Clock[0]>23)Clock[0] = 0; //小时越界判断 if(Clock[1]>59)Clock[1] = 0; //分越界判断if(Clock[2]>59)Clock[2] = 0; //秒越界判断}if(KeyNum == 4) //4号键使当前时间位-1{Buzzer_Time(100); //蜂鸣器按键提示音Clock[Clock_Sel]--;if(Clock[0]<0)Clock[0] = 23; //小时越界判断 if(Clock[1]<0)Clock[1] = 59; //分越界判断if(Clock[2]<0)Clock[2] = 59; //秒越界判断 } LCD_ShowChar(2,3,':'); LCD_ShowChar(2,6,':');if(Clock_Sel == 0 && TimeSetFlag ==1)LCD_ShowString(2,1," ");elseLCD_ShowNum(2,1,Clock[0],2); //显示时 if(Clock_Sel == 1 && TimeSetFlag ==1)LCD_ShowString(2,4," ");elseLCD_ShowNum(2,4,Clock[1],2); //显示分if(Clock_Sel == 2 && TimeSetFlag ==1)LCD_ShowString(2,7," ");elseLCD_ShowNum(2,7,Clock[2],2); //显示秒
}
4、闹钟响的条件
为了防止闹钟响个不停,所以设置闹钟的时间位要设计到秒才行,或者默认为0,并且只在模式0,也就是正常显示实时时间的模式下才会响,就不会出现,在设置闹钟的时候数字1位1位的加,“路过”闹钟时间结果响个几秒的尴尬
if(Mode == 0) //模式0,显示时间{DS1302_ReadTime();TranserShowStr_Day(DS1302_Time[6]); //将数字转化为对应字符串显示ShowTime(); //显示年月日时分秒if(DS1302_Time[3] == Clock[0]&&DS1302_Time[4] == Clock[1]&&DS1302_Time[5] == Clock[2]) //到时间蜂鸣器响5sBuzzer_Time(24000); }
5、遇到的问题
其实遇到的问题挺多的,但很多已经没什么印象了说明不怎么重要
1、关于进入闹钟模式清空屏幕,因为残留的显示数据不会消失,所以必须手动先清空,一开始我把LCD初始化函数写在了Clock_Set函数里,结果闪个不停,并且,时间位闪烁完全看不出来,后来意识到在while循环里只要Mode还等于1,就会不停的清空屏幕,因此闪个不停。但是其实一开始我并没有把模式切换写的那么详细,更喜欢之前的风格,Mode++,然后对3取余反复循环,这样写还要在写一步由模式0切换到1的判断,很麻烦,于是换了
2、由于很多代码都是用的前面的,,中间出了不少差错,还是不够细心..
四、效果演示
基于51单片机的可调时钟的闹钟设置和效果演示
最后,整个电子时钟的设计就结束了,完整的文件资源已上传
可调时钟的闹钟模式(接上篇)相关推荐
- 51单片机可调时钟/闹钟(源程序+原理图+PCB+详细报告)
51单片机可调时钟/闹钟 经过实验验证,切实可行!!配备详细代码注释!!! 功能介绍 时钟设置显示功能 这个仿真提供年份日期星期24小时格式时间显示,初始化后可以设置时间,选择模式一后可设置,通过对 ...
- 基于51单片机的可调时钟闹钟全套设计资料
编号:0003 仿真软件:Proteus8.9程序编译软件:keil5编写语言:C语言 功能介绍 时钟设置显示功能 1.这个仿真提供年份日期星期24小时格式时间显示,初始化后可以设置时间,选择模式一后 ...
- 基于stm32单片机多功能可调时钟闹钟万年历计时器闹铃提醒Proteus仿真(源码+仿真+原理图+PCB)
资料编号:148 视频讲解: 148-基于stm32单片机多功能可调时钟闹钟万年历计时器闹铃提醒Proteus仿真(源码+仿真+原理图+PCB) 本设计采用stm32单片机作为主控,LCD1602显 ...
- 基于STM32的esp8266WIFI自动校时+语音报时可调时钟(附源代码)
基于STM32WIFI自动校时+语音报时可调时钟(附源代码) 概述 STM32f103C8T6最小系统 共阴数码管 74HC595芯片 JQ5600语音模块 ESP8266-01SWIFI模块 ds1 ...
- 51单片机进阶案例(1)——基于MATLAB GUI的单片机串口与PC的通信实现实时时钟和双向可调时钟功能(利用DS1302时钟芯片和LCD1602液晶屏)
目录 一.案例描述 二.实现功能 三.51单片机部分实现 3.1 实时时钟的实现 3.2 串口通信的实现 3.2.1 接收数据 3.2.2 发送数据 四.MATLAB部分实现 4.1 GUI界面 4. ...
- 关于用51单片机内部定时器实现时钟和闹钟功能的概述
关于用51单片机内部定时器实现时钟和闹钟功能的概述 仅个人观点,欢迎大家相互学习和讨论 STC89C52单片机,内部配置了三个定时器,T0\T1\T2,其中T2定时器我们几乎不用,或者说很少用到.我们 ...
- 51单片机——DS1302可调时钟
目录 一.功能介绍 二.主要模块介绍 2.1 DS1302模块 2.1.1 DS1302芯片介绍 2.1.2 DS1302的使用 三.程序汇总 3.1测试文件test.c 3.2 LCD1602模块 ...
- 单片机入门(三)----DS1302时钟芯片 可调时钟
DS1302实现可调时钟 本代码以DS1302.定时器.独立按键.LCD1602实现了可调时钟. 原理图上的DS1302 按键在上一讲讲过了 LCD1602的代码以后再写 下面展示一些 内联代码片. ...
- 瑞萨e2studio(19)----RTC时钟日历闹钟周期性中断
瑞萨e2studio.19--RTC时钟日历&闹钟&周期性中断 概述 视频教学 csdn课程 样品申请 完整代码下载 硬件准备 新建工程 工程模板 保存工程路径 芯片配置 工程模板选择 ...
最新文章
- CSS层叠上下文、层叠顺序和层叠等级
- python not in range1002无标题_17个新手常见Python运行时错误
- 查询2021高考成绩位次,云南一分一段表查询2021-云南高考位次查询(文科、理科)...
- 【java】java JUC 同步器框架 AQS AbstractQueuedSynchronizer源码图文分析
- FaceDetector(人脸识别)
- Windows Server 部署WEB API时内部错误
- php 获取图片、swf的尺寸大小
- 推荐一款串口调试助手(win10,无广告,功能齐全,操作简单)
- Composer Class Fxp\Composer\AssetPlugin\Repository\NpmRepository does not exist
- SWUSTOJ82编写一个函数,求从n 个不同的数中取r 个数的所有选择的个数。
- 计算机仿真初审多长时间,普刊初审时间多久有回复
- photoshop ps 瘦身方法 液化工具
- 使用图像扫描控件ScanOnWeb实现在线图像扫描
- 进程、线程、程序的区别
- hexo博客如何绑定个人域名
- android sqlite 存储对象,SQLite存储对象
- 蒟蒻的两年程序竞赛经验
- 从键盘中输入姓名和电话号码,以#号结束,编程实现输入姓名可查询电话号码的功能。
- Mac地址修改器:WiFiSpoof Mac版
- WINDOWS图像编程