[开发板] 【CW32L031CxTx StartKit评估板测评】8.RTC的使用

[复制链接]
 楼主| yuyy1989 发表于 2023-10-3 10:05 | 显示全部楼层 |阅读模式
#申请原创# @21小跑堂  
实时时钟(RTC)是一个专用的计数器 / 定时器,可提供日历信息,包括小时、分钟、秒、日、月份、年份以及星期
CW32L031的RTC日历使用BCD码,这个码下23年10月1日分别会被表示为0x23 0x10 0x01,在写入时会自动进行合法性检查,任何非法的时间或日期值将不能被写入,另外支持自动闰年修正,CW32L031 内置经独立校准的 32kHz 频率的 RC 时钟源,为 RTC 提供驱动时钟,RTC 可在深度休眠模式下运行
接下来编程测试,用LCD屏显示RTC日期和时间,在闹钟触发后LCD显示ALARMA
  1. void rtc_init()
  2. {
  3.     RTC_InitTypeDef RTC_InitStruct = {0};
  4.     RTC_AlarmTypeDef RTC_AlarmStruct = {0};
  5.     GPIO_InitTypeDef GPIO_InitStructure = {0};
  6.     RCC_LSE_Enable(RCC_LSE_MODE_OSC, RCC_LSE_AMP_NORMAL, RCC_LSE_DRIVER_NORMAL);
  7.     __RCC_RTC_CLK_ENABLE();
  8.    
  9.     RTC_InitStruct.DateStruct.Day = 0x02;
  10.     RTC_InitStruct.DateStruct.Month = 0x10;
  11.     RTC_InitStruct.DateStruct.Week = 0x01;
  12.     RTC_InitStruct.DateStruct.Year = 0x23;
  13.     RTC_InitStruct.TimeStruct.Hour = 0x11;   
  14.     RTC_InitStruct.TimeStruct.Minute = 0x58;
  15.     RTC_InitStruct.TimeStruct.Second = 0x59;
  16.     RTC_InitStruct.TimeStruct.AMPM = 0;
  17.     RTC_InitStruct.TimeStruct.H24 = 1;
  18.     RTC_InitStruct.RTC_ClockSource = RTC_RTCCLK_FROM_LSE;
  19.     RTC_Init(&RTC_InitStruct);
  20.    
  21.     RTC_AlarmStruct.RTC_AlarmMask = RTC_AlarmMask_WeekMON | RTC_AlarmMask_WeekTUE |
  22.                                     RTC_AlarmMask_WeekWED | RTC_AlarmMask_WeekTHU |
  23.                                     RTC_AlarmMask_WeekFRI | RTC_AlarmMask_WeekSAT | RTC_AlarmMask_WeekSun;
  24.     RTC_AlarmStruct.RTC_AlarmTime.Hour = 0x12;
  25.     RTC_AlarmStruct.RTC_AlarmTime.Minute = 0x00;
  26.     RTC_AlarmStruct.RTC_AlarmTime.Second = 0x00;
  27.     RTC_SetAlarm(RTC_Alarm_A, &RTC_AlarmStruct);
  28.     RTC_AlarmCmd(RTC_Alarm_A, ENABLE);
  29.    
  30.     RTC_SetInterval(RTC_INTERVAL_EVERY_1S);
  31.     RTC_ITConfig(RTC_IT_ALARMA | RTC_IT_INTERVAL, ENABLE);
  32.     NVIC_EnableIRQ(RTC_IRQn);
  33. }
  34. uint8_t *WeekdayStr[7]= {"SUN","MON","TUE","WED","THU","FRI","SAT"};
  35. void lcd_showrtctime()
  36. {
  37.     char out[20];
  38.     RTC_TimeTypeDef RTC_TimeStruct = {0};
  39.     RTC_DateTypeDef RTC_DateStruct = {0};
  40.     RTC_GetDate(&RTC_DateStruct);
  41.     RTC_GetTime(&RTC_TimeStruct);
  42.     sprintf(out,"20%02X-%02X-%02X %s",RTC_DateStruct.Year,RTC_DateStruct.Month,RTC_DateStruct.Day,WeekdayStr[RTC_DateStruct.Week]);
  43.     yuyy_hs12864g18b_display_string_8x16(&hs12864_dev,0,2,0,(uint8_t *)out);
  44.     sprintf(out,"%02X:%02X:%02X",RTC_TimeStruct.Hour,RTC_TimeStruct.Minute,RTC_TimeStruct.Second);
  45.     yuyy_hs12864g18b_display_string_8x16(&hs12864_dev,0,4,0,(uint8_t *)out);
  46. }

  47. void RTC_IRQHandler(void)
  48. {
  49.     if (RTC_GetITState(RTC_IT_ALARMA))
  50.     {
  51.         RTC_ClearITPendingBit(RTC_IT_ALARMA);
  52.         yuyy_hs12864g18b_display_string_8x16(&hs12864_dev,0,4,68,(uint8_t *)"ALARMA");
  53.     }
  54.     if (RTC_GetITState(RTC_IT_INTERVAL))
  55.     {
  56.         RTC_ClearITPendingBit(RTC_IT_INTERVAL);
  57.         lcd_showrtctime();
  58.     }
  59. }
运行效果
WeChat_20231003083634 00_00_00-00_00_30.gif
CW32L031的RTC还有几个专用的引脚
QQ截图20231001203458.png QQ截图20231001203651.png
RTCOUT 可以输出的内容如下,可以作为闹钟输出使用
QQ截图20231001203839.png
RTC1HZ可以输出经过补偿或未经补偿的 1Hz信号
RTC_TAMP是个输入引脚,引脚触发后,将当前时间和日期分别保存到时间戳日期寄存器 RTC_TAMPDATE和时间戳时间寄存器 RTC_TAMPTIM,同时可产生时间戳中断
接下来编程测试RTCOUT和RTC1HZ输出,PB14 和PB15分别外接LED
  1. void rtc_ioinit()
  2. {
  3.     GPIO_InitTypeDef GPIO_InitStructure = {0};
  4.     __RCC_GPIOB_CLK_ENABLE();
  5.     PB14_AFx_RTCOUT();
  6.     PB15_AFx_RTC1Hz();
  7.     GPIO_InitStructure.Pins = GPIO_PIN_14 | GPIO_PIN_15;
  8.     GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  9.     GPIO_Init(CW_GPIOB, &GPIO_InitStructure);
  10.     RTC_RTCOUT_ALARM_A();
  11.     CW_RTC->CR0_f.RTC1HZ = 0x03;
  12.     //RTC_RTC1HZ_LSE();
  13.     CW_RTC->CR1_f.SOURCE = 0;
  14. }


这里芯源提供的库里RTC_RTC1HZ_PCLK()和RTC_RTC1HZ_LSE()是不能正常使用的,两个宏定义的取值是错误的
QQ截图20231003085813.png QQ截图20231003085836.png QQ截图20231003085900.png
另外要注意RTCOUT输出闹钟时引脚输出状态和闹钟中断标志是有关系的在中断中清除闹钟中断RTCOUT输出也会变为0
运行效果
WeChat_20231003095703 00_00_00-00_00_30.gif
接下来编程测试时间戳记录功能,PA01对应开发板上的按键KEY2按下后记录时间戳,KEY1按下后显示之前记录的时间戳,松开恢复时间显示
  1. void rtc_tampinit()
  2. {
  3.     GPIO_InitTypeDef GPIO_InitStructure = {0};
  4.     __RCC_GPIOA_CLK_ENABLE();
  5.     PA01_AFx_RTCTAMP();
  6.     GPIO_InitStructure.Pins = GPIO_PIN_1|GPIO_PIN_2;
  7.     GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
  8.     GPIO_Init(CW_GPIOA, &GPIO_InitStructure);
  9.     RTC_TAMPEDGE_FALL();
  10.     RTC_TAMP_ENABLE();
  11.     RTC_IE_TAMP_CLEAR();
  12. }
  13. void lcd_showrtctime()
  14. {
  15.     char out[20];
  16.     RTC_TimeTypeDef RTC_TimeStruct = {0};
  17.     RTC_DateTypeDef RTC_DateStruct = {0};
  18.     if(GPIO_ReadPin(CW_GPIOA,GPIO_PIN_2) == GPIO_Pin_RESET)
  19.     {
  20.         RTC_GetTamperDate(&RTC_DateStruct);
  21.         RTC_GetTamperTime(&RTC_TimeStruct);
  22.         yuyy_hs12864g18b_display_string_8x16(&hs12864_dev,0,4,68,(uint8_t *)"TAMP");
  23.         RTC_IE_TAMP_CLEAR();
  24.     }
  25.     else
  26.     {
  27.         RTC_GetDate(&RTC_DateStruct);
  28.         RTC_GetTime(&RTC_TimeStruct);
  29.         yuyy_hs12864g18b_display_string_8x16(&hs12864_dev,0,4,68,(uint8_t *)"      ");
  30.     }
  31.     sprintf(out,"20%02X-%02X-%02X %s",RTC_DateStruct.Year,RTC_DateStruct.Month,RTC_DateStruct.Day,WeekdayStr[RTC_DateStruct.Week]);
  32.     yuyy_hs12864g18b_display_string_8x16(&hs12864_dev,0,2,0,(uint8_t *)out);
  33.     sprintf(out,"%02X:%02X:%02X",RTC_TimeStruct.Hour,RTC_TimeStruct.Minute,RTC_TimeStruct.Second);
  34.     yuyy_hs12864g18b_display_string_8x16(&hs12864_dev,0,4,0,(uint8_t *)out);
  35. }
运行效果,不知为什么年和时和秒没被时间戳记录下来
WeChat_20231003095712 00_00_00-00_00_30.gif

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

本版积分规则

认证:同飞软件研发工程师
简介:制冷系统单片机软件开发,使用PID控制温度

161

主题

815

帖子

10

粉丝
快速回复 在线客服 返回列表 返回顶部
认证:同飞软件研发工程师
简介:制冷系统单片机软件开发,使用PID控制温度

161

主题

815

帖子

10

粉丝
快速回复 在线客服 返回列表 返回顶部