- #include "stm32f10x.h" // Device header
- #include "Delay.h" //延时模块,主函数中未使用
- #include "OLED.h" //OLED显示模块
- #include "MyRTC.h" //RTC模块
- #include "Key.h" //按键模块
- #include "Buzzer.h" //蜂鸣器模块
- #include "Encoder.h"
- /*
- 功能: 简易时钟,可以通过按键调整日期时间和设定闹钟,通过OLED显示日期时间等相关信息
-
- 原理: RTC
-
- 接线: OLED显示屏:SCK接PB8,SDA接PB9
- 有源蜂鸣器(低电平触发):I/O接PB12
- 1~4号独立按键:分别接PB11,PB10,PB1,PB0
-
- 注意: 若出现没有现象或时间不动等情况,请查看MyRTC.c
- */
- uint16_t MyRTC_Time[] = {2024,4,11,12,0,0}; //定义全局的时间数组,数组内容分别为年、月、日、时、分、秒
- uint32_t Alarm_CNT,Alarm_Time,Alarm_Time_Rest; //闹钟相关变量,单位都是秒
- uint8_t Hour,Min,Sec; //用来调整闹钟时间的变量
- uint8_t KeyNum ; //按键键码值
- uint8_t Flag_Count; //是否在计时标志,0为不在计时
- uint8_t Flag_Change; //按键调节闹钟/日期/时间,0为调节闹钟,1为调节日期,2为调节时间
- /*按键控制函数*/
- void Key_Control(void)
- {
- KeyNum = Key_GetNum(); //读取按键键码
-
- if(Flag_Change == 0) //调节闹钟
- {
- if(KeyNum == 1) //1号按键调整小时
- {
- Hour+= Encoder_Get();
- if(Hour > 60)
- Hour = 0;
- }
- else if(KeyNum == 2) //2号按键调整分钟
- {
- Min+= Encoder_Get();
- if(Min > 60)
- Min = 0;
- }
- else if(KeyNum == 3) //3号按键调整秒
- {
- Sec+= Encoder_Get();
- if(Sec > 60)
- Sec = 0;
- }
- else if(KeyNum == 4) //4号按键
- {
- if(Buzzer_State()==0) //若蜂鸣器没响
- {
- Alarm_Time = Hour*3600 + Min*60 + Sec; //计算闹钟时长,单位是秒
-
- if(Alarm_Time > 0)
- {
- Alarm_CNT = RTC_GetCounter()+Alarm_Time-1; //设定闹钟值,需要-1
- RTC_SetAlarm(Alarm_CNT); //写入闹钟值到RTC的ALR寄存器
- Flag_Count = 1;
- }
- else //若闹钟时长为0,则转到按键调节日期
- {
- Flag_Change = 1;
- }
- }
- else //若蜂鸣器响
- {
- Buzzer_OFF(); //关闭蜂鸣器
- OLED_ShowString(4,1," "); //刷新oled第四行
- }
- }
- }
-
- else if(Flag_Change == 1) //调节日期
- {
- Delay_ms(2000);
- KeyNum = Key_GetNum();
- if(KeyNum == 1) //1号按键调整年
- {
- MyRTC_Time[0]+= Encoder_Get();
- MyRTC_SetTime();
- }
- else if(KeyNum == 2) //2号按键调整月
- {
- MyRTC_Time[1]+= Encoder_Get();
- MyRTC_SetTime();
- }
- else if(KeyNum == 3) //3号按键调整日
- {
- MyRTC_Time[2]+= Encoder_Get();
- MyRTC_SetTime();
- }
- else if(KeyNum == 4) //4号按键,改为调整时间
- {
- Flag_Change = 2;
- }
- }
-
- else if(Flag_Change == 2) //调节时间
- {
- Delay_ms(2000);
- KeyNum = Key_GetNum();
- if(KeyNum == 1) //1号按键调整小时
- {
- MyRTC_Time[3]+= Encoder_Get();
- MyRTC_SetTime();
- }
- else if(KeyNum == 2) //2号按键调整分钟
- {
- MyRTC_Time[4]+= Encoder_Get();
- MyRTC_SetTime();
- }
- else if(KeyNum == 3) //3号按键调整秒
- {
- MyRTC_Time[5]+= Encoder_Get();
- MyRTC_SetTime();
- }
- else if(KeyNum == 4) //4号按键
- {
- Flag_Change = 0; //改为调整闹钟
- OLED_ShowString(4,1," "); //刷新oled第四行
- }
- }
- }
- int main(void)
- {
- /*模块初始化*/
- OLED_Init(); //OLED初始化
- MyRTC_Init(); //RTC初始化
- Key_Init(); //按键初始化
- Buzzer_Init(); //蜂鸣器初始化
- Encoder_Init(); //旋转编码器初始化
-
- /*显示静态字符串*/
- OLED_ShowString(1, 1, "Date:XXXX-XX-XX");
- OLED_ShowString(2, 1, "Time:XX:XX:XX");
- OLED_ShowString(3, 1, "Alarm:XX:XX:XX");
- while (1)
- {
- MyRTC_ReadTime(); //RTC读取时间,最新的时间存储到MyRTC_Time数组中
- Key_Control(); //调用按键控制函数
- OLED_ShowNum(1, 6, MyRTC_Time[0], 4); //显示MyRTC_Time数组中的时间值,年
- OLED_ShowNum(1, 11, MyRTC_Time[1], 2); //月
- OLED_ShowNum(1, 14, MyRTC_Time[2], 2); //日
- OLED_ShowNum(2, 6, MyRTC_Time[3], 2); //时
- OLED_ShowNum(2, 9, MyRTC_Time[4], 2); //分
- OLED_ShowNum(2, 12, MyRTC_Time[5], 2); //秒
- OLED_ShowNum(4, 15, Key_GetNum(), 2); //秒
-
- if(Flag_Count) //正在计时,则显示闹钟响起剩余时间
- {
- Alarm_Time_Rest = Alarm_CNT-RTC_GetCounter()+1; //计算闹钟响起剩余时间
- if(Alarm_Time_Rest > Alarm_Time) //防止溢出错误
- Alarm_Time_Rest = 0;
-
- OLED_ShowNum(3,7,Alarm_Time_Rest/3600,2); //显示剩余小时
- OLED_ShowNum(3,10,(Alarm_Time_Rest%3600)/60,2); //显示剩余分钟
- OLED_ShowNum(3,13,(Alarm_Time_Rest%3600)%60,2); //显示剩余秒
-
- if(RTC_GetFlagStatus(RTC_FLAG_ALR) == 1) //闹钟时间到,检查标志位为1
- {
- RTC_ClearFlag(RTC_FLAG_ALR); //清除标志位
- Flag_Count = 0;Alarm_Time = 0; //重置相关参数
- Hour = 0;Min = 0; Sec = 0;
-
- Buzzer_ON(); //打开蜂鸣器
- OLED_ShowString(4,1,"Time Out");
- }
- else //闹钟时间未到
- {
- OLED_ShowString(4,1,"Counting"); //显示正在计时
- }
- }
- else //不在计时,则显示需要设定的闹钟时间
- {
- OLED_ShowNum(3,7,Hour,2);
- OLED_ShowNum(3,10,Min,2);
- OLED_ShowNum(3,13,Sec,2);
- }
-
- if(Flag_Change == 1) //显示“调节日期”
- {
- OLED_ShowString(4,1,"Change Date");
- }
- else if(Flag_Change == 2) //显示“调节时间”
- {
- OLED_ShowString(4,1,"Change Time");
- }
- }
- }
复制代码
原理图: 无
仿真: 无
代码:
Project.7z
(187.52 KB, 下载次数: 23)
|