当前位置:   article > 正文

可调时钟的闹钟模式(接上篇)_uln2003d驱动蜂鸣器

uln2003d驱动蜂鸣器

写在前面:

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

一、实现思路 

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

二、蜂鸣器

1、工作原理

普中的板子上的是无源蜂鸣器,BZ连接在了步进电机OUT5,ULN2003D逻辑框图如下

 对于蜂鸣器驱动需要输入振荡脉冲,ULN2003D作用为继电器驱动,在这里我们只需要考虑输入取反输出即可,因此蜂鸣器连接对应51寄存器地址为P2_5(图和板子不一样)

sbit Buzzer = P2^5;  //类型声明蜂鸣器地址

 2、蜂鸣器响任意时间函数

循环体内使Buzzer每隔250us取反,一个周期为0.5ms,即2000HZ,循环执行次数决定持续时间,期间接收按键键码,只要键码不为0,即有任意独立按键按下,跳出循环,声音停止

  1. #include <REGX52.H>
  2. #include"Delay.h"
  3. #include"Key.h"
  4. sbit Buzzer = P2^5; //类型声明蜂鸣器地址
  5. unsigned int i; //计数
  6. /**
  7. * @brief 蜂鸣器以2000HZ的时间响x250us
  8. * @param xms 蜂鸣器响的时间
  9. * @retval 无
  10. */
  11. void Buzzer_Time(unsigned int x250us)
  12. {
  13. unsigned KeyNumber;
  14. for(i=0;i<x250us;i++)
  15. {
  16. KeyNumber = Key();
  17. Buzzer = !Buzzer; //振荡输入
  18. Delay10us(25); //高低电平维持时间为250us,一个周期就是0.5ms
  19. if(KeyNumber)break;
  20. }
  21. }

 封装好之后可以用于按键提示音和闹钟

三、代码设计和修改

1、预备工作

 定义Clock_Sel为闹钟设置模式下的时间位索引,定义数组存放设置闹钟的时分秒

  1. //存放设置的脑钟时间
  2. char Clock[] = {0,0,0};
  3. //定义键码、设置时间位索引、设置时间闪烁标志、模式(显示时间/设置时间),闹钟设置时间位索引
  4. unsigned char KeyNum, TimeSet_Sel, TimeSetFlag, Mode, Clock_Sel;

2、增加模式

按下1键让Mode在0、1、2之间循环,为了保持原有设置时间功能(从设置时间模式切换到模式0时写入修改后的时间),将模式2作为设置时间模式,模式1为新增的设置闹钟时间。每次切换到闹钟模式时,闹钟时间位索引清0,固定从时开始设置,并且将LCD清空第一行显示“Clock:”

  1. if(KeyNum == 1)
  2. {
  3. Buzzer_Time(100); //蜂鸣器按键提示音
  4. if(Mode == 0)
  5. {
  6. Mode = 1; //切换至设置闹钟模式
  7. LCD_Init();
  8. Delay(100);
  9. Clock_Sel = 0; //每次切换到设置闹钟索引清0
  10. }
  11. else if(Mode == 1 )
  12. {
  13. Mode = 2; //切换至设置时间模式
  14. TimeSet_Sel = 0; //每次切换到设置时间模式索引清0,固定从“年”开始闪烁
  15. }
  16. else if(Mode == 2)
  17. {
  18. Mode = 0; //切换回显示时间模式
  19. DS1302_SetTime(); //将已修改的时间数据写入芯片
  20. }
  21. }
  22. switch(Mode) //显示当前工作模式
  23. {
  24. case 0: LCD_ShowString(2,12,"Show ");break;
  25. case 1: LCD_ShowString(2,12,"Clock ");break;
  26. case 2: LCD_ShowString(2,12,"Set ");break;
  27. }

当Mode == 1时,执行设置闹钟模式代码 

3、设置闹钟函数SetClock()

思路可以说是完全照搬了上一篇的设置时间函数,都是按2键索引++,3键当前时间位++,4键当前时间位--,越界判断和校正从之前的函数里截取了时分秒的部分,闪烁设置也是一样的,按键提示音在整个程序所有地方都加上了,没什么好说的直接贴代码

  1. void SetClock(void)
  2. {
  3. LCD_ShowString(1,1,"Clock:");
  4. LCD_ShowNum(1,13,Clock_Sel,2);
  5. if(KeyNum == 2) //2号按键选择设置的时间位
  6. {
  7. Buzzer_Time(100); //蜂鸣器按键提示音
  8. Clock_Sel++;
  9. Clock_Sel %= 3; //索引在0~1
  10. }
  11. if(KeyNum == 3) //3号按键使当前时间位+1
  12. {
  13. Buzzer_Time(100); //蜂鸣器按键提示音
  14. Clock[Clock_Sel]++;
  15. if(Clock[0]>23)Clock[0] = 0; //小时越界判断
  16. if(Clock[1]>59)Clock[1] = 0; //分越界判断
  17. if(Clock[2]>59)Clock[2] = 0; //秒越界判断
  18. }
  19. if(KeyNum == 4) //4号键使当前时间位-1
  20. {
  21. Buzzer_Time(100); //蜂鸣器按键提示音
  22. Clock[Clock_Sel]--;
  23. if(Clock[0]<0)Clock[0] = 23; //小时越界判断
  24. if(Clock[1]<0)Clock[1] = 59; //分越界判断
  25. if(Clock[2]<0)Clock[2] = 59; //秒越界判断
  26. }
  27. LCD_ShowChar(2,3,':');
  28. LCD_ShowChar(2,6,':');
  29. if(Clock_Sel == 0 && TimeSetFlag ==1)
  30. LCD_ShowString(2,1," ");
  31. else
  32. LCD_ShowNum(2,1,Clock[0],2); //显示时
  33. if(Clock_Sel == 1 && TimeSetFlag ==1)
  34. LCD_ShowString(2,4," ");
  35. else
  36. LCD_ShowNum(2,4,Clock[1],2); //显示分
  37. if(Clock_Sel == 2 && TimeSetFlag ==1)
  38. LCD_ShowString(2,7," ");
  39. else
  40. LCD_ShowNum(2,7,Clock[2],2); //显示秒
  41. }

4、闹钟响的条件

为了防止闹钟响个不停,所以设置闹钟的时间位要设计到秒才行,或者默认为0,并且只在模式0,也就是正常显示实时时间的模式下才会响,就不会出现,在设置闹钟的时候数字1位1位的加,“路过”闹钟时间结果响个几秒的尴尬

  1. if(Mode == 0) //模式0,显示时间
  2. {
  3. DS1302_ReadTime();
  4. TranserShowStr_Day(DS1302_Time[6]); //将数字转化为对应字符串显示
  5. ShowTime(); //显示年月日时分秒
  6. if(DS1302_Time[3] == Clock[0]&&DS1302_Time[4] == Clock[1]&&DS1302_Time[5] == Clock[2]) //到时间蜂鸣器响5s
  7. Buzzer_Time(24000);
  8. }

5、遇到的问题

其实遇到的问题挺多的,但很多已经没什么印象了说明不怎么重要

1、关于进入闹钟模式清空屏幕,因为残留的显示数据不会消失,所以必须手动先清空,一开始我把LCD初始化函数写在了Clock_Set函数里,结果闪个不停,并且,时间位闪烁完全看不出来,后来意识到在while循环里只要Mode还等于1,就会不停的清空屏幕,因此闪个不停。但是其实一开始我并没有把模式切换写的那么详细,更喜欢之前的风格,Mode++,然后对3取余反复循环,这样写还要在写一步由模式0切换到1的判断,很麻烦,于是换了

2、由于很多代码都是用的前面的,,中间出了不少差错,还是不够细心..

四、效果演示

基于51单片机的可调时钟的闹钟设置和效果演示

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/675847
推荐阅读
相关标签
  

闽ICP备14008679号