写在前面:

上篇文末提到可以优化的地方包括加入闹钟,了解无源蜂鸣器的工作原理后,就着手扩展闹钟设置功能了,同时按键按下加入蜂鸣器的提示音。由于上篇的篇幅过长了,所以决定单独写一篇这个闹钟模块。

一、实现思路

  1. 保持原有功能情况下加入第三个模式
  2. 当前模式下执行功能,设置时分秒,同样是选中位闪烁,增大减小,越界判断等可以直接照搬前面的
  3. 设置的时分秒存在一个数组,当当前时间的时分秒都与之对应相等调用蜂鸣器
  4. 按下任意独立按键可以终止闹钟

二、蜂鸣器

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单片机的可调时钟的闹钟设置和效果演示

最后,整个电子时钟的设计就结束了,完整的文件资源已上传

可调时钟的闹钟模式(接上篇)相关推荐

  1. 51单片机可调时钟/闹钟(源程序+原理图+PCB+详细报告)

    51单片机可调时钟/闹钟 经过实验验证,切实可行!!配备详细代码注释!!! 功能介绍 时钟设置显示功能  这个仿真提供年份日期星期24小时格式时间显示,初始化后可以设置时间,选择模式一后可设置,通过对 ...

  2. 基于51单片机的可调时钟闹钟全套设计资料

    编号:0003 仿真软件:Proteus8.9程序编译软件:keil5编写语言:C语言 功能介绍 时钟设置显示功能 1.这个仿真提供年份日期星期24小时格式时间显示,初始化后可以设置时间,选择模式一后 ...

  3. 基于stm32单片机多功能可调时钟闹钟万年历计时器闹铃提醒Proteus仿真(源码+仿真+原理图+PCB)

     资料编号:148 视频讲解: 148-基于stm32单片机多功能可调时钟闹钟万年历计时器闹铃提醒Proteus仿真(源码+仿真+原理图+PCB) 本设计采用stm32单片机作为主控,LCD1602显 ...

  4. 基于STM32的esp8266WIFI自动校时+语音报时可调时钟(附源代码)

    基于STM32WIFI自动校时+语音报时可调时钟(附源代码) 概述 STM32f103C8T6最小系统 共阴数码管 74HC595芯片 JQ5600语音模块 ESP8266-01SWIFI模块 ds1 ...

  5. 51单片机进阶案例(1)——基于MATLAB GUI的单片机串口与PC的通信实现实时时钟和双向可调时钟功能(利用DS1302时钟芯片和LCD1602液晶屏)

    目录 一.案例描述 二.实现功能 三.51单片机部分实现 3.1 实时时钟的实现 3.2 串口通信的实现 3.2.1 接收数据 3.2.2 发送数据 四.MATLAB部分实现 4.1 GUI界面 4. ...

  6. 关于用51单片机内部定时器实现时钟和闹钟功能的概述

    关于用51单片机内部定时器实现时钟和闹钟功能的概述 仅个人观点,欢迎大家相互学习和讨论 STC89C52单片机,内部配置了三个定时器,T0\T1\T2,其中T2定时器我们几乎不用,或者说很少用到.我们 ...

  7. 51单片机——DS1302可调时钟

    目录 一.功能介绍 二.主要模块介绍 2.1 DS1302模块 2.1.1 DS1302芯片介绍 2.1.2  DS1302的使用 三.程序汇总 3.1测试文件test.c 3.2 LCD1602模块 ...

  8. 单片机入门(三)----DS1302时钟芯片 可调时钟

    DS1302实现可调时钟 本代码以DS1302.定时器.独立按键.LCD1602实现了可调时钟. 原理图上的DS1302 按键在上一讲讲过了 LCD1602的代码以后再写 下面展示一些 内联代码片. ...

  9. 瑞萨e2studio(19)----RTC时钟日历闹钟周期性中断

    瑞萨e2studio.19--RTC时钟日历&闹钟&周期性中断 概述 视频教学 csdn课程 样品申请 完整代码下载 硬件准备 新建工程 工程模板 保存工程路径 芯片配置 工程模板选择 ...

最新文章

  1. CSS层叠上下文、层叠顺序和层叠等级
  2. python not in range1002无标题_17个新手常见Python运行时错误
  3. 查询2021高考成绩位次,云南一分一段表查询2021-云南高考位次查询(文科、理科)...
  4. 【java】java JUC 同步器框架 AQS AbstractQueuedSynchronizer源码图文分析
  5. FaceDetector(人脸识别)
  6. Windows Server 部署WEB API时内部错误
  7. php 获取图片、swf的尺寸大小
  8. 推荐一款串口调试助手(win10,无广告,功能齐全,操作简单)
  9. Composer Class Fxp\Composer\AssetPlugin\Repository\NpmRepository does not exist
  10. SWUSTOJ82编写一个函数,求从n 个不同的数中取r 个数的所有选择的个数。
  11. 计算机仿真初审多长时间,普刊初审时间多久有回复
  12. photoshop ps 瘦身方法 液化工具
  13. 使用图像扫描控件ScanOnWeb实现在线图像扫描
  14. 进程、线程、程序的区别
  15. hexo博客如何绑定个人域名
  16. android sqlite 存储对象,SQLite存储对象
  17. 蒟蒻的两年程序竞赛经验
  18. 从键盘中输入姓名和电话号码,以#号结束,编程实现输入姓名可查询电话号码的功能。
  19. Mac地址修改器:WiFiSpoof Mac版
  20. WINDOWS图像编程

热门文章

  1. int转string的多种方式
  2. 工作中常用到的Linux命令操作
  3. 阿里巴巴中国站获得1688商品类目 API
  4. Github Pages 启用 HTTPS
  5. 八卦Google 的前端开发方式及流程
  6. 有些事情,我们需要坚持到底
  7. keil中快速注释一段代码
  8. PPT文档管理控件Aspose.Slides v19.5上线发布!开始评估PDF转换的时间花费!
  9. 02_sample远控
  10. 四年后看微软第二代超融合系统:Azure Stack HCI