本帖最后由 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 计时效果
|