实验:通过RT-Thread Studio使用NUCLEO-F413ZH的内置RTC
硬件:NUCLEO-F413ZH(注:电路上V(BAT)口已经连接到VDD)
软件:RT-Thread Studio
构建过程:基于芯片、使用4.0.2版本创建RT-Thread项目,打开的组件:finsh命令、ulog日志、libc、PM(电源管理)设备驱动程序等,勾选“rtc device”示例,在board.c中打开“#define BSP_USING_ONCHIP_RTC”,在stm32f4xx_hal_config.h中打开“#define BSP_USING_ONCHIP_RTC”。
问题现象:无论是在“rtc device”示例的rtc_sample()、rtc.c的date()、drv_rtc.c的rt_rtc_init()函数调用HAL_RTCEx_BKUPWrite()函数,都不能往RTC备份寄存器的RTC_BKP_DR1写入标志0xA5A5。
测试方法:使用msh调用“rtc_sample”或“date 2018 01 01 23 59 59”命令后,再调用“reboot”命令(USB持续供电)还会提示“I/drv.rtc: RTC hasn’t been configured, please use
疑惑:RTC驱动中是不是有个BKP时钟没有启动,类似__HAL_RCC_BKP_CLK_ENABLE(),导致调用HAL_RTCEx_BKUPWrite()函数不能往RTC备份寄存器的RTC_BKP_DR1写入标志?
//在rtc_sample.c中,粗体是在原来的基础上增加的代码
static int rtc_sample(int argc, char *argv[])
{
rt_err_t ret = RT_EOK;
time_t now;
/* 设置日期 */
ret = set_date(2020, 8, 15);
if (ret != RT_EOK)
{
rt_kprintf("set RTC date failed\n");
return ret;
}
/* 设置时间 */
ret = set_time(16, 55, 0);
if (ret != RT_EOK)
{
rt_kprintf("set RTC time failed\n");
return ret;
}
**HAL_PWR_EnableBkUpAccess();//取消备份区域写保护**
**HAL_RTCEx_BKUPWrite(&RTC_Handler,RTC_BKP_DR1,BKUP_REG_DATA);//标记已经初始化过了**
/* 延时3秒 */
rt_thread_mdelay(3000);
/* 获取时间 */
now = time(RT_NULL);
rt_kprintf("%s\n", ctime(&now));
return ret;
}
//在rtc.c中,粗体是在原来的基础上增加的代码
static void date(uint8_t argc, char **argv)
{
if (argc == 1)
{
time_t now;
/* output current time */
now = time(RT_NULL);
rt_kprintf("%.*s", 25, ctime(&now));
}
else if (argc >= 7)
{
/* set time and date */
uint16_t year;
uint8_t month, day, hour, min, sec;
year = atoi(argv[1]);
month = atoi(argv[2]);
day = atoi(argv[3]);
hour = atoi(argv[4]);
min = atoi(argv[5]);
sec = atoi(argv[6]);
if (year > 2099 || year < 2000)
{
rt_kprintf("year is out of range [2000-2099]\n");
return;
}
if (month == 0 || month > 12)
{
rt_kprintf("month is out of range [1-12]\n");
return;
}
if (day == 0 || day > 31)
{
rt_kprintf("day is out of range [1-31]\n");
return;
}
if (hour > 23)
{
rt_kprintf("hour is out of range [0-23]\n");
return;
}
if (min > 59)
{
rt_kprintf("minute is out of range [0-59]\n");
return;
}
if (sec > 59)
{
rt_kprintf("second is out of range [0-59]\n");
return;
}
set_time(hour, min, sec);
set_date(year, month, day);
**HAL_PWR_EnableBkUpAccess();//取消备份区域写保护**
**HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR1, BKUP_REG_DATA);//标记已经初始化过了**
}
else
{
rt_kprintf("please input: date [year month day hour min sec] or date\n");
rt_kprintf("e.g: date 2018 01 01 23 59 59 or date\n");
}
}
//在drv_rtc.c中,粗体是在原来的基础上增加的代码
static rt_err_t rt_rtc_config(struct rt_device *dev)
{
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
HAL_PWR_EnableBkUpAccess();
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
//#ifdef BSP_RTC_USING_LSI
//PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
//#else
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
//#endif
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
/* Enable RTC Clock */
__HAL_RCC_RTC_ENABLE();
RTC_Handler.Instance = RTC;
if (HAL_RTCEx_BKUPRead(&RTC_Handler, RTC_BKP_DR1) != BKUP_REG_DATA)
{
LOG_I("RTC hasn't been configured, please use <date> command to config.");
//#if defined(SOC_SERIES_STM32F1)
//RTC_Handler.Init.OutPut = RTC_OUTPUTSOURCE_NONE;
//RTC_Handler.Init.AsynchPrediv = RTC_AUTO_1_SECOND;
//#elif defined(SOC_SERIES_STM32F0)
/* set the frequency division */
//#ifdef BSP_RTC_USING_LSI
//RTC_Handler.Init.AsynchPrediv = 0XA0;
//RTC_Handler.Init.SynchPrediv = 0xFA;
//#else
//RTC_Handler.Init.AsynchPrediv = 0X7F;
//RTC_Handler.Init.SynchPrediv = 0x0130;
//#endif /* BSP_RTC_USING_LSI */
//RTC_Handler.Init.HourFormat = RTC_HOURFORMAT_24;
//RTC_Handler.Init.OutPut = RTC_OUTPUT_DISABLE;
//RTC_Handler.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
//RTC_Handler.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
//#elif defined(SOC_SERIES_STM32F2) || defined(SOC_SERIES_STM32F4) || defined(SOC_SERIES_STM32F7) || defined(SOC_SERIES_STM32L4) || defined(SOC_SERIES_STM32H7)
/* set the frequency division */
//#ifdef BSP_RTC_USING_LSI
//RTC_Handler.Init.AsynchPrediv = 0X7D;
//#else
RTC_Handler.Init.AsynchPrediv = 0X7F;
//#endif /* BSP_RTC_USING_LSI */
RTC_Handler.Init.SynchPrediv = 0XFF;
RTC_Handler.Init.HourFormat = RTC_HOURFORMAT_24;
RTC_Handler.Init.OutPut = RTC_OUTPUT_DISABLE;
RTC_Handler.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
RTC_Handler.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
//#endif
if (HAL_RTC_Init(&RTC_Handler) != HAL_OK)
{
return -RT_ERROR;
}
**set_time(16, 55, 0);**
**set_date(2020, 8, 15);**
**HAL_PWR_EnableBkUpAccess();//取消备份区域写保护**
**HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR1, BKUP_REG_DATA);//标记已经初始化过了**
}
return RT_EOK;
}
不用RT-Thread Studio时,通过配置cubemx的RTC和env生成工程也是出现同样的问题