【CW32饭盒派开发板试用体验】1. 开箱啦
【CW32饭盒派开发板试用体验】2. 使用扩展板串口UART3以及scanf重定向到串口
【CW32饭盒派开发板试用体验】3. 使用BTIM实现任务调度器
【CW32饭盒派开发板试用体验】4. ADC采样摇杆模块X轴和Y轴输出
【CW32饭盒派开发板试用体验】5. 极简方式移植FreeRTOS成功
【CW32饭盒派开发板试用体验】6.硬件I2C之连接HS300X读取温湿度数据
1 RTC介绍
RTC是MCU内置的实时时钟模块,可以提供时间,日期,星期的自动累计,无需MCU参与,减轻MCU负担并且提高了计时精度。
本文将使用CW32F030的内置RTC完成实时时钟的测试。
本文使用官方提供的例程,在此基础上做了修改实现了每一秒打印一次当前实时时钟记录的时间。
2 RTC操作流程
打开用户手册12. 实时时钟(RTC)章节可以了解实时时钟的相关原理以及操作说明。
更多操作说明参考12.3功能描述章节。
3 软件编写
3.1 RTC初始化
下面的代码完成了如下工作:
- 使用了LSE时钟
- 使能了RTC中断,并设置了间隔1s触发一次
- 设置RTC初始日期为2023/6/7,星期三(必须设置星期,不然星期会不正确)
- 设置RTC时间为2点58分59秒,使用了24小时制
- 最后启动RTC
注:不知道CW32f030怎么设计的,我设置了时间不断电重启是无效的,还是会按照之前的时间累计运行,断上电之后才会按照设定的新时间运行。
void Rtc_Init(void)
{
RTC_InitTypeDef RTC_InitStruct;
RCC_LSI_Enable();
RCC_LSE_Enable(RCC_LSE_MODE_OSC, RCC_LSE_AMP_NORMAL, RCC_LSE_DRIVER_NORMAL);
RCC_APBPeriphClk_Enable1(RCC_APB1_PERIPH_RTC, ENABLE);
__disable_irq();
NVIC_EnableIRQ(RTC_IRQn);
__enable_irq();
printf("RTC Init...\r\n");
RTC_InitStruct.DateStruct.Year = 0x23;
RTC_InitStruct.DateStruct.Month = RTC_Month_June;
RTC_InitStruct.DateStruct.Day = 0x07;
RTC_InitStruct.DateStruct.Week = RTC_Weekday_Wednesday;
printf("-------Set Date as 20%x/%x/%x\r\n", RTC_InitStruct.DateStruct.Year,RTC_InitStruct.DateStruct.Month,RTC_InitStruct.DateStruct.Day);
RTC_InitStruct.TimeStruct.Hour = 0x2;
RTC_InitStruct.TimeStruct.Minute = 0x58;
RTC_InitStruct.TimeStruct.Second = 0x59;
RTC_InitStruct.TimeStruct.H24 = 1;
printf("-------Set Time as %02x:%02x:%02x\r\n", RTC_InitStruct.TimeStruct.Hour,RTC_InitStruct.TimeStruct.Minute,RTC_InitStruct.TimeStruct.Second);
RTC_InitStruct.RTC_ClockSource = RTC_RTCCLK_FROM_LSE;
RTC_Init(&RTC_InitStruct);
printf("=====Set interval period as 1s...\r\n");
RTC_SetInterval(RTC_INTERVAL_EVERY_1S);
RTC_ITConfig(RTC_IT_INTERVAL, ENABLE);
}
3.2 打印时间
下面是打印时间的函数,使用printf,关于使用方式可以参考我之前的帖子。
逻辑为从RTC中读出当前日期时间并打印出来
void ShowTime(void)
{
RTC_TimeTypeDef RTC_TimeStruct;
RTC_DateTypeDef RTC_DateStruct;
static char *WeekdayStr[7]={"SUN","MON","TUE","WED","THU","FRI","SAT"};
RTC_GetDate(&RTC_DateStruct);
RTC_GetTime(&RTC_TimeStruct);
printf(".Date is 20%02x/%02x/%02x(%s).Time is %02x:%02x:%02x\r\n", RTC_DateStruct.Year,
RTC_DateStruct.Month,
RTC_DateStruct.Day,
WeekdayStr[RTC_DateStruct.Week],
RTC_TimeStruct.Hour,
RTC_TimeStruct.Minute,
RTC_TimeStruct.Second);
}
3.3 中断处理函数
中断处理函数中只使用了间隔中断,初始化的时候设置了间隔时间为1s,则每一秒会进入一次中断,在中断中调用ShowTime()打印当前时间。
注:中断程序需要放置到 interrupts_cw32f030.c
中的函数 RTC_IRQHandler
下面才会生效
void RTC_IRQHandlerCallBack(void)
{
if (RTC_GetITState(RTC_IT_INTERVAL))
{
RTC_ClearITPendingBit(RTC_IT_INTERVAL);
ShowTime();
}
}
3.4 主函数
主函数中只需要调用Rtc初始化原函数即可。
Rtc_Init();
试验结果
如下图,串口打印出了日期和时间信息,包括了星期。
注意事项
CW32F030的RTC和我之前使用过的其他MCU的RTC有些许区别,CW32F030的RTC显得不是那么智能(PS:有可能是我使用上的问题,若有错误,欢迎指针,谢谢),有以下两点在使用的时候需要注意:
- 如果代码在初始化的时候更新了时间,则需要将板子的电源断开再重新上电运行,不然时间不会更新,还是会在之前的时间上进行累加,只有板子断电重启之后才会从新写入初始化日期时间处开始计时(直接按复位键不会生效)
- 必须设置星期,不然星期会显示不正确。之前用过其他公司的MCU会自动计算星期,只需要设置年月日即可。