本帖最后由 jinglixixi 于 2023-7-19 19:37 编辑
#申请原创#
AC7802x内置了RTC计数器,但它却是一个准RTC,即只有RTC计时功能,却没配置日期时间的计时处理功能。 为此,要以RTC来实现电子时钟功能,需要靠软件来自行补充日期与时间的计时处理功能。 要制作一个简单的电子时钟,在硬件方面就是为它配置一个显示器件,这里是选用I2C接口的OLED屏,见图1所示。 图1 硬件构成
在软件方面,就是利用RTC的秒计时功能,并添加相应的时间累计进制处理。 为了便于功能扩展,这里定义了一个数据结构来对时间进行处理,其定义为: typedef struct { uint8_t sec; uint8_t min; uint8_t hour; } RTC_TimeTypeDef;
实现时间累计处理与显示的主程序为: - int main(void)
- {
- char ss,mm,hh;
- RTC_TimeTypeDef time_s;
- InitDelay();
- InitDebug();
- GPIO_LedInit();
- RTC_Timeout1s();
- GPIO_OLEDInit();
- OLED_Init();
- OLED_Clear();
- OLED_ShowString(10,0,"AC7802x",16);
- OLED_ShowString(10,2,"RTC Test",16);
- OLED_ShowString(10,4," : :",16);
- OLED_ShowString(0,6,"jinglixixi",16);
- time_s.hour=8;
- time_s.min=30;
- time_s.sec=0;
- hh=time_s.hour;
- mm=time_s.min;
- ss=time_s.sec;
- while (1)
- {
- if(g_timeoutFlag)
- {
- g_timeoutFlag = 0;
- ss=ss+1;
- if(ss==60)
- {
- ss=0;
- mm=mm+1;
- }
- OLED_ShowNum(58,4,ss,2,16);
- if(mm==60)
- {
- mm=0;
- hh=hh+1;
- }
- OLED_ShowNum(34,4,mm,2,16);
- if(hh==24)
- {
- hh=0;
- }
- OLED_ShowNum(10,4,hh,2,16);
- }
- }
- }
经程序的编译与下载,其执行效果如图2所示。 图2 计时效果
以此为基础,还可以为其添加日期的累计处理。 更新后的RTC时间结构定义为: typedef struct { uint8_t mday; uint8_t mon; uint8_t year; uint8_t weekday; uint8_t sec; uint8_t min; uint8_t hour; }RTC_Date_TimeTypeDef;
相应的起始时间设置函数为: - void Rtc_SetDateTime(void)
- {
- dt.year = 23;
- dt.mon = 7;
- dt.mday = 20;
- dt.hour = 8;
- dt.min = 30;
- dt.sec = 0;
- }
实现日期与时间显示的主程序为: - int main(void)
- {
- char v;
- InitDelay();
- InitDebug();
- GPIO_LedInit();
- RTC_Timeout1s();
- GPIO_OLEDInit();
- OLED_Init();
- OLED_Clear();
- OLED_ShowString(20,0,"RTC Test",16);
- OLED_ShowString(20,4," : :",16);
- OLED_ShowString(20,6," - -",16);
- Rtc_SetDateTime();
- while (1)
- {
- if(g_timeoutFlag)
- {
- g_timeoutFlag = 0;
- dt.sec=dt.sec+1;
- if(dt.sec==60)
- {
- dt.sec=0;
- dt.min=dt.min+1;
- }
- OLED_ShowNum(68,4,dt.sec,2,16);
- if(dt.min==60)
- {
- dt.min=0;
- dt.hour=dt.hour+1;
- }
- OLED_ShowNum(44,4,dt.min,2,16);
- if(dt.hour==24)
- {
- dt.hour=0;
- dt.mday=dt.mday+1;
- }
- OLED_ShowNum(20,4,dt.hour,2,16);
- if(dt.mon==2)
- {
- v=(Rtc_IsLeapYear(dt.year) == 1) ? (29U) : (28U);
- }
- else
- {
- v=month_day_num[dt.mon];
- }
- if(dt.mday>v)
- {
- dt.mday=1;
- dt.mon=dt.mon+1;
- }
- if(dt.mon>12)
- {
- dt.mon=1;
- dt.year=dt.year+1;
- }
- OLED_ShowNum(20,6,dt.year,2,16);
- OLED_ShowNum(44,6,dt.mon,2,16);
- OLED_ShowNum(68,6,dt.mday,2,16);
- OLED_ShowString(20,2,week[Rtc_Week()],16);
- }
- }
- }
经程序的编译与下载,其执行效果如图3所示。 图3 计时效果
|