找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 783|回复: 1
收起左侧

STM32单片机rtc闹钟,旋钮,按键调节时间日期代码

[复制链接]
ID:1127127 发表于 2024-7-4 22:41 | 显示全部楼层 |阅读模式
  1. #include "stm32f10x.h"                  // Device header
  2. #include "Delay.h"                                                //延时模块,主函数中未使用
  3. #include "OLED.h"                                                //OLED显示模块
  4. #include "MyRTC.h"                                                //RTC模块
  5. #include "Key.h"                                                //按键模块
  6. #include "Buzzer.h"                                                //蜂鸣器模块
  7. #include "Encoder.h"

  8. /*
  9.         功能:        简易时钟,可以通过按键调整日期时间和设定闹钟,通过OLED显示日期时间等相关信息
  10.        
  11.         原理:        RTC
  12.        
  13.         接线:        OLED显示屏:SCK接PB8,SDA接PB9
  14.                         有源蜂鸣器(低电平触发):I/O接PB12
  15.                         1~4号独立按键:分别接PB11,PB10,PB1,PB0
  16.        
  17.         注意:        若出现没有现象或时间不动等情况,请查看MyRTC.c
  18. */

  19. uint16_t MyRTC_Time[] = {2024,4,11,12,0,0};                //定义全局的时间数组,数组内容分别为年、月、日、时、分、秒
  20. uint32_t Alarm_CNT,Alarm_Time,Alarm_Time_Rest;        //闹钟相关变量,单位都是秒
  21. uint8_t Hour,Min,Sec;                                                        //用来调整闹钟时间的变量
  22. uint8_t KeyNum ;                                                                //按键键码值
  23. uint8_t Flag_Count;                                                                //是否在计时标志,0为不在计时
  24. uint8_t Flag_Change;                                                        //按键调节闹钟/日期/时间,0为调节闹钟,1为调节日期,2为调节时间


  25. /*按键控制函数*/
  26. void Key_Control(void)
  27. {
  28.         KeyNum = Key_GetNum();        //读取按键键码
  29.        
  30.         if(Flag_Change == 0)        //调节闹钟
  31.         {
  32.                 if(KeyNum == 1)                //1号按键调整小时
  33.                 {
  34.                         Hour+= Encoder_Get();
  35.                         if(Hour > 60)
  36.                                 Hour = 0;
  37.                 }
  38.                 else if(KeyNum == 2)        //2号按键调整分钟
  39.                 {
  40.                         Min+= Encoder_Get();
  41.                         if(Min > 60)
  42.                                 Min = 0;
  43.                 }
  44.                 else if(KeyNum == 3)        //3号按键调整秒
  45.                 {
  46.                         Sec+= Encoder_Get();
  47.                         if(Sec > 60)
  48.                                 Sec = 0;
  49.                 }

  50.                 else if(KeyNum == 4)        //4号按键
  51.                 {
  52.                         if(Buzzer_State()==0)                //若蜂鸣器没响
  53.                         {
  54.                                 Alarm_Time = Hour*3600 + Min*60 + Sec;                        //计算闹钟时长,单位是秒
  55.                                
  56.                                 if(Alarm_Time > 0)
  57.                                 {
  58.                                         Alarm_CNT = RTC_GetCounter()+Alarm_Time-1;                        //设定闹钟值,需要-1
  59.                                         RTC_SetAlarm(Alarm_CNT);                                                        //写入闹钟值到RTC的ALR寄存器
  60.                                         Flag_Count = 1;
  61.                                 }
  62.                                 else        //若闹钟时长为0,则转到按键调节日期
  63.                                 {
  64.                                         Flag_Change = 1;       
  65.                                 }
  66.                         }
  67.                         else        //若蜂鸣器响
  68.                         {
  69.                                 Buzzer_OFF();                //关闭蜂鸣器
  70.                                 OLED_ShowString(4,1,"        ");        //刷新oled第四行       
  71.                         }
  72.                 }
  73.         }
  74.        
  75.         else if(Flag_Change == 1)                //调节日期
  76.         {
  77.                 Delay_ms(2000);
  78.                 KeyNum = Key_GetNum();
  79.                 if(KeyNum == 1)                        //1号按键调整年
  80.                 {
  81.                         MyRTC_Time[0]+= Encoder_Get();
  82.                         MyRTC_SetTime();
  83.                 }
  84.                 else if(KeyNum == 2)        //2号按键调整月
  85.                 {
  86.                         MyRTC_Time[1]+= Encoder_Get();
  87.                         MyRTC_SetTime();
  88.                 }
  89.                 else if(KeyNum == 3)        //3号按键调整日
  90.                 {
  91.                         MyRTC_Time[2]+= Encoder_Get();
  92.                         MyRTC_SetTime();
  93.                 }
  94.                 else if(KeyNum == 4)        //4号按键,改为调整时间
  95.                 {
  96.                         Flag_Change = 2;
  97.                 }                       
  98.         }
  99.        
  100.         else if(Flag_Change == 2)                //调节时间
  101.         {
  102.                 Delay_ms(2000);
  103.                 KeyNum = Key_GetNum();
  104.                 if(KeyNum == 1)                        //1号按键调整小时
  105.                 {
  106.                         MyRTC_Time[3]+= Encoder_Get();
  107.                         MyRTC_SetTime();
  108.                 }
  109.                 else if(KeyNum == 2)        //2号按键调整分钟
  110.                 {
  111.                         MyRTC_Time[4]+= Encoder_Get();
  112.                         MyRTC_SetTime();
  113.                 }
  114.                 else if(KeyNum == 3)        //3号按键调整秒
  115.                 {
  116.                         MyRTC_Time[5]+= Encoder_Get();
  117.                         MyRTC_SetTime();
  118.                 }
  119.                 else if(KeyNum == 4)        //4号按键
  120.                 {
  121.                         Flag_Change = 0;        //改为调整闹钟
  122.                         OLED_ShowString(4,1,"            ");        //刷新oled第四行
  123.                 }                       
  124.         }

  125. }

  126. int main(void)
  127. {
  128.         /*模块初始化*/
  129.         OLED_Init();                //OLED初始化
  130.         MyRTC_Init();                //RTC初始化
  131.         Key_Init();                        //按键初始化
  132.         Buzzer_Init();                //蜂鸣器初始化
  133.         Encoder_Init();                //旋转编码器初始化
  134.                
  135.         /*显示静态字符串*/
  136.         OLED_ShowString(1, 1, "Date:XXXX-XX-XX");
  137.         OLED_ShowString(2, 1, "Time:XX:XX:XX");
  138.         OLED_ShowString(3, 1, "Alarm:XX:XX:XX");

  139.         while (1)
  140.         {
  141.                 MyRTC_ReadTime();                                                        //RTC读取时间,最新的时间存储到MyRTC_Time数组中
  142.                 Key_Control();                                                                //调用按键控制函数

  143.                 OLED_ShowNum(1, 6, MyRTC_Time[0], 4);                //显示MyRTC_Time数组中的时间值,年
  144.                 OLED_ShowNum(1, 11, MyRTC_Time[1], 2);                //月
  145.                 OLED_ShowNum(1, 14, MyRTC_Time[2], 2);                //日
  146.                 OLED_ShowNum(2, 6, MyRTC_Time[3], 2);                //时
  147.                 OLED_ShowNum(2, 9, MyRTC_Time[4], 2);                //分
  148.                 OLED_ShowNum(2, 12, MyRTC_Time[5], 2);                //秒
  149.                 OLED_ShowNum(4, 15, Key_GetNum(), 2);                //秒

  150.                
  151.                 if(Flag_Count)                                                                                //正在计时,则显示闹钟响起剩余时间
  152.                 {
  153.                         Alarm_Time_Rest = Alarm_CNT-RTC_GetCounter()+1;        //计算闹钟响起剩余时间
  154.                         if(Alarm_Time_Rest > Alarm_Time)                                //防止溢出错误
  155.                                 Alarm_Time_Rest = 0;
  156.                        
  157.                         OLED_ShowNum(3,7,Alarm_Time_Rest/3600,2);                //显示剩余小时
  158.                         OLED_ShowNum(3,10,(Alarm_Time_Rest%3600)/60,2);        //显示剩余分钟
  159.                         OLED_ShowNum(3,13,(Alarm_Time_Rest%3600)%60,2);        //显示剩余秒
  160.                        
  161.                         if(RTC_GetFlagStatus(RTC_FLAG_ALR) == 1)                //闹钟时间到,检查标志位为1
  162.                         {
  163.                                 RTC_ClearFlag(RTC_FLAG_ALR);                                //清除标志位
  164.                                 Flag_Count = 0;Alarm_Time = 0;                                //重置相关参数
  165.                                 Hour = 0;Min = 0; Sec = 0;
  166.                                
  167.                                 Buzzer_ON();                                                                //打开蜂鸣器
  168.                                 OLED_ShowString(4,1,"Time Out");
  169.                         }
  170.                         else                                                                                        //闹钟时间未到
  171.                         {
  172.                                 OLED_ShowString(4,1,"Counting");                        //显示正在计时
  173.                         }
  174.                 }
  175.                 else                                                                                                //不在计时,则显示需要设定的闹钟时间
  176.                 {
  177.                         OLED_ShowNum(3,7,Hour,2);
  178.                         OLED_ShowNum(3,10,Min,2);
  179.                         OLED_ShowNum(3,13,Sec,2);
  180.                 }
  181.                
  182.                 if(Flag_Change == 1)                //显示“调节日期”
  183.                 {
  184.                         OLED_ShowString(4,1,"Change Date");
  185.                 }
  186.                 else if(Flag_Change == 2)        //显示“调节时间”
  187.                 {
  188.                         OLED_ShowString(4,1,"Change Time");
  189.                 }
  190.         }
  191. }

复制代码

原理图: 无
仿真: 无
代码: Project.7z (187.52 KB, 下载次数: 23)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:229641 发表于 2024-7-9 23:54 来自手机 | 显示全部楼层
精度怎么样?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表