Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
alarm
apt-pi
RTC
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
发布于 2021-01-20 09:25:53 浏览:9936
订阅该版
[tocm] [RT-Thread 入门学习笔记 - 目录](https://club.rt-thread.org/ask/article/3420.html) [【ART-PI】STM32H750XBH6 - 入手篇](https://club.rt-thread.org/ask/article/2462.html) [【ART-PI】STM32H750XBH6 - RT-Thread 最小系统移植](https://club.rt-thread.org/ask/article/2469.html) [【ART-PI】RT-Thread Freemodbus RS485 RTU 从机](https://club.rt-thread.org/ask/article/2477.html) [【ART-PI】RT-Thread 开启RTC 与 Alarm组件](https://club.rt-thread.org/ask/article/2501.html) [【ART-PI】STM32H750XBH6 RT-Thread 点亮LCD](https://club.rt-thread.org/ask/article/2676.html) ## 背景 * 【ART-PI】默认没有开启Alarm组件,尝试适配并开启 * 有部分工程师想使用RT-Thread 基于STM32H7系列的RTC 与 Alarm(闹钟功能) ## 验证平台 * Keil MDK5(使用RT-Thread Studio 可以作为参考) * 【ART-PI】STM32H750XBH6,使用Pandoro STM32L4系列MCU,同样验证通过 ## 移植方法 * 只前做过一次基于Apollo3平台的Alarm组件的移植,适配部分与STM32有些不同,直接Copy过去编译,发现编译不过,很正常!! * 这次基于STM32H7、STM32L4平台,如果也编译不过去,只需要微调! ![2021-01-20_084804.png](https://oss-club.rt-thread.org/uploads/20210120/1c5f2aae4f8a2b3c5500a3fd5e215282.png) ![2021-01-20_085113.png](https://oss-club.rt-thread.org/uploads/20210120/3228ad17d6ff047c4424fa9310370d6d.png) ![2021-01-20_085442.png](https://oss-club.rt-thread.org/uploads/20210120/42d7da4d09c55fb432e5a3e98cc39a9a.png) ![2021-01-20_085529.png](https://oss-club.rt-thread.org/uploads/20210120/baad70c29f5405a32e8e744202808afc.png) ![2021-01-20_085724.png](https://oss-club.rt-thread.org/uploads/20210120/4803719e9a47dca3a577e94654a726d2.png) ![2021-01-20_085814.png](https://oss-club.rt-thread.org/uploads/20210120/eeed2268e4337fb78000b4cf47f12f2c.png) ## 功能验证 ![2021-01-20_090458.png](https://oss-club.rt-thread.org/uploads/20210120/762f7e19e752893c1c91156e53e4870a.png) ![2021-01-20_090528.png](https://oss-club.rt-thread.org/uploads/20210120/b50f0694fbcdf829344b76b0db2359f4.png) ![2021-01-20_090900.png](https://oss-club.rt-thread.org/uploads/20210120/3e6ef8cbc7695bd3d758abdb4e913cdb.png) ## drv_rtc.c 代码,供参考 ``` #include "board.h" #include
#include
#ifdef BSP_USING_ONCHIP_RTC struct rt_rtc_device { struct rt_device device; #ifdef RT_USING_ALARM struct rt_rtc_wkalarm wkalarm; #endif }; #define DBG_ENABLE #define DBG_SECTION_NAME "drv_rtc" #define DBG_LEVEL DBG_INFO #include
static struct rt_rtc_device rtc_device; #ifdef RT_USING_ALARM static rt_err_t rtc_alarm_time_set(struct rt_rtc_device* p_dev); static int rt_rtc_alarm_init(void); static RTC_AlarmTypeDef salarmstructure; #endif #ifndef RTC_BKP_DR1 #define RTC_BKP_DR1 RT_NULL #endif #define BKUP_REG_DATA 0xA5A5 static RTC_HandleTypeDef RTC_Handler; RT_WEAK uint32_t HAL_RTCEx_BKUPRead(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister) { return (~BKUP_REG_DATA); } RT_WEAK void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister, uint32_t Data) { return; } static time_t get_rtc_timestamp(void) { RTC_TimeTypeDef RTC_TimeStruct = {0}; RTC_DateTypeDef RTC_DateStruct = {0}; struct tm tm_new = {0}; HAL_RTC_GetTime(&RTC_Handler, &RTC_TimeStruct, RTC_FORMAT_BIN); HAL_RTC_GetDate(&RTC_Handler, &RTC_DateStruct, RTC_FORMAT_BIN); tm_new.tm_sec = RTC_TimeStruct.Seconds; tm_new.tm_min = RTC_TimeStruct.Minutes; tm_new.tm_hour = RTC_TimeStruct.Hours; tm_new.tm_mday = RTC_DateStruct.Date; tm_new.tm_mon = RTC_DateStruct.Month - 1; tm_new.tm_year = RTC_DateStruct.Year + 100; return mktime(&tm_new); } static rt_err_t set_rtc_time_stamp(time_t time_stamp) { RTC_TimeTypeDef RTC_TimeStruct = {0}; RTC_DateTypeDef RTC_DateStruct = {0}; struct tm *p_tm; p_tm = localtime(&time_stamp); if (p_tm->tm_year < 100) { return -RT_ERROR; } RTC_TimeStruct.Seconds = p_tm->tm_sec ; RTC_TimeStruct.Minutes = p_tm->tm_min ; RTC_TimeStruct.Hours = p_tm->tm_hour; RTC_DateStruct.Date = p_tm->tm_mday; RTC_DateStruct.Month = p_tm->tm_mon + 1 ; RTC_DateStruct.Year = p_tm->tm_year - 100; RTC_DateStruct.WeekDay = p_tm->tm_wday + 1; if (HAL_RTC_SetTime(&RTC_Handler, &RTC_TimeStruct, RTC_FORMAT_BIN) != HAL_OK) { return -RT_ERROR; } if (HAL_RTC_SetDate(&RTC_Handler, &RTC_DateStruct, RTC_FORMAT_BIN) != HAL_OK) { return -RT_ERROR; } LOG_D("set rtc time."); HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR1, BKUP_REG_DATA); #ifdef SOC_SERIES_STM32F1 /* F1 series does't save year/month/date datas. so keep those datas to bkp reg */ HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR2, RTC_DateStruct.Year); HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR3, RTC_DateStruct.Month); HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR4, RTC_DateStruct.Date); HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR5, RTC_DateStruct.WeekDay); #endif return RT_EOK; } static void rt_rtc_init(void) { #if !defined(SOC_SERIES_STM32H7) && !defined(SOC_SERIES_STM32WB) __HAL_RCC_PWR_CLK_ENABLE(); #endif RCC_OscInitTypeDef RCC_OscInitStruct = {0}; #ifdef BSP_RTC_USING_LSI #ifdef SOC_SERIES_STM32WB RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI1; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; RCC_OscInitStruct.LSEState = RCC_LSE_OFF; RCC_OscInitStruct.LSIState = RCC_LSI_ON; #else RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; RCC_OscInitStruct.LSEState = RCC_LSE_OFF; RCC_OscInitStruct.LSIState = RCC_LSI_ON; #endif #else RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; RCC_OscInitStruct.LSEState = RCC_LSE_ON; RCC_OscInitStruct.LSIState = RCC_LSI_OFF; #endif HAL_RCC_OscConfig(&RCC_OscInitStruct); } #ifdef SOC_SERIES_STM32F1 /* update RTC_BKP_DRx*/ static void rt_rtc_f1_bkp_update(void) { RTC_DateTypeDef RTC_DateStruct = {0}; HAL_PWR_EnableBkUpAccess(); __HAL_RCC_BKP_CLK_ENABLE(); RTC_DateStruct.Year = HAL_RTCEx_BKUPRead(&RTC_Handler, RTC_BKP_DR2); RTC_DateStruct.Month = HAL_RTCEx_BKUPRead(&RTC_Handler, RTC_BKP_DR3); RTC_DateStruct.Date = HAL_RTCEx_BKUPRead(&RTC_Handler, RTC_BKP_DR4); RTC_DateStruct.WeekDay = HAL_RTCEx_BKUPRead(&RTC_Handler, RTC_BKP_DR5); if (HAL_RTC_SetDate(&RTC_Handler, &RTC_DateStruct, RTC_FORMAT_BIN) != HAL_OK) { Error_Handler(); } HAL_RTC_GetDate(&RTC_Handler, &RTC_DateStruct, RTC_FORMAT_BIN); if (HAL_RTCEx_BKUPRead(&RTC_Handler, RTC_BKP_DR4) != RTC_DateStruct.Date) { HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR1, BKUP_REG_DATA); HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR2, RTC_DateStruct.Year); HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR3, RTC_DateStruct.Month); HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR4, RTC_DateStruct.Date); HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR5, RTC_DateStruct.WeekDay); } } #endif 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
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) || defined (SOC_SERIES_STM32WB) /* 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; } } #ifdef SOC_SERIES_STM32F1 else { /* F1 series need update by bkp reg datas */ rt_rtc_f1_bkp_update(); } #endif return RT_EOK; } static rt_err_t rt_rtc_control(rt_device_t dev, int cmd, void *args) { rt_err_t result = RT_EOK; #ifdef RT_USING_ALARM struct rt_rtc_wkalarm *p_wkalarm = RT_NULL; #endif RT_ASSERT(dev != RT_NULL); switch (cmd) { case RT_DEVICE_CTRL_RTC_GET_TIME: *(rt_uint32_t *)args = get_rtc_timestamp(); LOG_D("RTC: get rtc_time %x\n", *(rt_uint32_t *)args); break; case RT_DEVICE_CTRL_RTC_SET_TIME: if (set_rtc_time_stamp(*(rt_uint32_t *)args)) { result = -RT_ERROR; } #ifdef RT_USING_ALARM rt_alarm_update(&rtc_device.device, 1); #endif LOG_D("RTC: set rtc_time %x\n", *(rt_uint32_t *)args); break; #ifdef RT_USING_ALARM case RT_DEVICE_CTRL_RTC_GET_ALARM: args = &rtc_device.wkalarm; LOG_D("GET_ALARM %d:%d:%d",rtc_device.wkalarm.tm_hour, rtc_device.wkalarm.tm_min,rtc_device.wkalarm.tm_sec); break; case RT_DEVICE_CTRL_RTC_SET_ALARM: LOG_D("RT_DEVICE_CTRL_RTC_SET_ALARM"); p_wkalarm = (struct rt_rtc_wkalarm *)args; if (p_wkalarm != RT_NULL) { rtc_device.wkalarm.enable = p_wkalarm->enable; rtc_device.wkalarm.tm_hour = p_wkalarm->tm_hour; rtc_device.wkalarm.tm_min = p_wkalarm->tm_min; rtc_device.wkalarm.tm_sec = p_wkalarm->tm_sec; rtc_alarm_time_set(&rtc_device); } else { result = -RT_ERROR; LOG_E("RT_DEVICE_CTRL_RTC_SET_ALARM error!!"); } LOG_D("SET_ALARM %d:%d:%d",p_wkalarm->tm_hour, p_wkalarm->tm_min,p_wkalarm->tm_sec); break; #endif } return result; } #ifdef RT_USING_DEVICE_OPS const static struct rt_device_ops rtc_ops = { RT_NULL, RT_NULL, RT_NULL, RT_NULL, RT_NULL, rt_rtc_control }; #endif static rt_err_t rt_hw_rtc_register(rt_device_t device, const char *name, rt_uint32_t flag) { RT_ASSERT(device != RT_NULL); rt_rtc_init(); if (rt_rtc_config(device) != RT_EOK) { return -RT_ERROR; } #ifdef RT_USING_DEVICE_OPS device->ops = &rtc_ops; #else device->init = RT_NULL; device->open = RT_NULL; device->close = RT_NULL; device->read = RT_NULL; device->write = RT_NULL; device->control = rt_rtc_control; #endif device->type = RT_Device_Class_RTC; device->rx_indicate = RT_NULL; device->tx_complete = RT_NULL; device->user_data = RT_NULL; /* register a character device */ return rt_device_register(device, name, flag); } int rt_hw_rtc_init(void) { rt_err_t result; result = rt_hw_rtc_register(&rtc_device.device, "rtc", RT_DEVICE_FLAG_RDWR); if (result != RT_EOK) { LOG_E("rtc register err code: %d\n", result); return result; } #ifdef RT_USING_ALARM rt_rtc_alarm_init(); #endif LOG_D("rtc init success\n"); return RT_EOK; } #ifdef RT_USING_ALARM void rt_rtc_alarm_enable(void) { HAL_RTC_SetAlarm_IT(&RTC_Handler,&salarmstructure,RTC_FORMAT_BIN); HAL_RTC_GetAlarm(&RTC_Handler,&salarmstructure,RTC_ALARM_A,RTC_FORMAT_BIN); LOG_D("alarm read:%d:%d:%d", salarmstructure.AlarmTime.Hours, salarmstructure.AlarmTime.Minutes, salarmstructure.AlarmTime.Seconds); HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 0x02, 0); HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn); } void rt_rtc_alarm_disable(void) { HAL_RTC_DeactivateAlarm(&RTC_Handler, RTC_ALARM_A); HAL_NVIC_DisableIRQ(RTC_Alarm_IRQn); } static int rt_rtc_alarm_init(void) { return RT_EOK; } static rt_err_t rtc_alarm_time_set(struct rt_rtc_device* p_dev) { if (p_dev->wkalarm.enable) { salarmstructure.Alarm = RTC_ALARM_A; salarmstructure.AlarmDateWeekDay = RTC_WEEKDAY_MONDAY; salarmstructure.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_WEEKDAY; salarmstructure.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY; salarmstructure.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_NONE; salarmstructure.AlarmTime.TimeFormat = RTC_HOURFORMAT12_AM; salarmstructure.AlarmTime.Hours = p_dev->wkalarm.tm_hour; salarmstructure.AlarmTime.Minutes = p_dev->wkalarm.tm_min; salarmstructure.AlarmTime.Seconds = p_dev->wkalarm.tm_sec; LOG_D("alarm set:%d:%d:%d", salarmstructure.AlarmTime.Hours, salarmstructure.AlarmTime.Minutes, salarmstructure.AlarmTime.Seconds); rt_rtc_alarm_enable(); } return RT_EOK; } void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) { //LOG_D("rtc alarm isr.\n"); rt_alarm_update(&rtc_device.device, 1); } void RTC_Alarm_IRQHandler(void) { HAL_RTC_AlarmIRQHandler(&RTC_Handler); } #endif INIT_DEVICE_EXPORT(rt_hw_rtc_init); #endif /* BSP_USING_ONCHIP_RTC */ ``` ## RTC_Alarm 测试代码,供参考 ``` #include
#include "board.h" #include
#include
#define RTC_DEBUG #define DBG_ENABLE #define DBG_SECTION_NAME "rtc.test" #define DBG_LEVEL DBG_LOG #include
#ifdef RTC_DEBUG static struct rt_alarm * p_alarm_sec = RT_NULL; static struct rt_alarm * p_alarm_min = RT_NULL; static struct rt_alarm * p_alarm_hour = RT_NULL; static struct rt_alarm * p_alarm_time = RT_NULL; static rt_err_t rtc_set_time(time_t timestamp) { /* converts the local time in time to calendar time. */ rt_device_t rtc_device; rt_err_t ret = -RT_ERROR; rtc_device = rt_device_find("rtc"); if (rtc_device == RT_NULL) { return -RT_ERROR; } /* update to RTC device. */ ret = rt_device_control(rtc_device, RT_DEVICE_CTRL_RTC_SET_TIME, ×tamp); return ret; } static time_t rtc_gettime(void) { static time_t now; static struct tm tm; now = time(NULL); #ifdef _WIN32 _gmtime32_s(&tm, &now); #else gmtime_r(&now, &tm); #endif LOG_D("BJ time:%04d-%02d-%02d %02d:%02d:%02d.%03d\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour + 8, tm.tm_min, tm.tm_sec, rt_tick_get() % 1000); return now; } static void alarm_time_cb(rt_alarm_t alarm, time_t timestamp) { LOG_D("alarm_time_cb ok!\n"); } static void alarm_hour_cb(rt_alarm_t alarm, time_t timestamp) { LOG_D("alarm_hour_cb ok!\n"); } static void alarm_minute_cb(rt_alarm_t alarm, time_t timestamp) { LOG_D("alarm_minute_cb ok!\n"); } static void alarm_second_cb(rt_alarm_t alarm, time_t timestamp) { LOG_D("alarm_second_cb ok!\n"); } static struct rt_alarm * rtc_alarm_test_create(rt_alarm_callback_t callback, rt_uint32_t flag, struct tm *p_tm) { struct rt_alarm_setup alarm_setup_test; alarm_setup_test.flag = flag; alarm_setup_test.wktime.tm_year = p_tm->tm_year; alarm_setup_test.wktime.tm_mon = p_tm->tm_mon; alarm_setup_test.wktime.tm_mday = p_tm->tm_mday; alarm_setup_test.wktime.tm_wday = p_tm->tm_wday; alarm_setup_test.wktime.tm_hour = p_tm->tm_hour; alarm_setup_test.wktime.tm_min = p_tm->tm_min; alarm_setup_test.wktime.tm_sec = p_tm->tm_sec; return rt_alarm_create(callback, &alarm_setup_test); } static void rtc_alarm_time_create(void) { static time_t now; static struct tm tm; if (p_alarm_time != RT_NULL) return; now = time(NULL) + 65; #ifdef _WIN32 _gmtime32_s(&tm, &now); #else gmtime_r(&now, &tm); #endif p_alarm_time = rtc_alarm_test_create(alarm_time_cb, RT_ALARM_DAILY, &tm); } static void rtc_alarm_time_start(void) { if (p_alarm_time != RT_NULL) rt_alarm_start(p_alarm_time); } static void rtc_alarm_time_stop(void) { if (p_alarm_time != RT_NULL) rt_alarm_stop(p_alarm_time); } static void rtc_alarm_time_delete(void) { if (p_alarm_time != RT_NULL) { if (rt_alarm_delete(p_alarm_time) == RT_EOK) p_alarm_time = RT_NULL; } } static void rtc_alarm_second_create(void) { static time_t now; static struct tm tm; if (p_alarm_sec != RT_NULL) return; now = time(NULL) + 1; #ifdef _WIN32 _gmtime32_s(&tm, &now); #else gmtime_r(&now, &tm); #endif p_alarm_sec = rtc_alarm_test_create(alarm_second_cb, RT_ALARM_SECOND, &tm); } static void rtc_alarm_second_start(void) { if (p_alarm_sec != RT_NULL) rt_alarm_start(p_alarm_sec); } static void rtc_alarm_second_stop(void) { if (p_alarm_sec != RT_NULL) rt_alarm_stop(p_alarm_sec); } static void rtc_alarm_second_delete(void) { if (p_alarm_sec != RT_NULL) { if (rt_alarm_delete(p_alarm_sec) == RT_EOK) p_alarm_sec = RT_NULL; } } static void rtc_alarm_minute_create(void) { static time_t now; static struct tm tm; if (p_alarm_min != RT_NULL) return; now = time(NULL) + 60; #ifdef _WIN32 _gmtime32_s(&tm, &now); #else gmtime_r(&now, &tm); #endif p_alarm_min = rtc_alarm_test_create(alarm_minute_cb, RT_ALARM_MINUTE, &tm); } static void rtc_alarm_minute_start(void) { if (p_alarm_min != RT_NULL) rt_alarm_start(p_alarm_min); } static void rtc_alarm_minute_stop(void) { if (p_alarm_min != RT_NULL) rt_alarm_stop(p_alarm_min); } static void rtc_alarm_minute_delete(void) { if (p_alarm_min != RT_NULL) { if (rt_alarm_delete(p_alarm_min) == RT_EOK) p_alarm_min = RT_NULL; } } static void rtc_alarm_hour_create(void) { static time_t now; static struct tm tm; if (p_alarm_hour != RT_NULL) return; now = time(NULL) + 3600; #ifdef _WIN32 _gmtime32_s(&tm, &now); #else gmtime_r(&now, &tm); #endif p_alarm_hour = rtc_alarm_test_create(alarm_hour_cb, RT_ALARM_HOUR, &tm); } static void rtc_alarm_hour_start(void) { if (p_alarm_hour != RT_NULL) rt_alarm_start(p_alarm_hour); } static void rtc_alarm_hour_stop(void) { if (p_alarm_hour != RT_NULL) rt_alarm_stop(p_alarm_hour); } static void rtc_alarm_hour_delete(void) { if (p_alarm_hour != RT_NULL) { if (rt_alarm_delete(p_alarm_hour) == RT_EOK) p_alarm_hour = RT_NULL; } } void rtc_alarm_start(int argc, char **argv) { int index = 0; if (argc >= 2) { index = atoi(argv[1]); } switch(index) { case 0: rtc_alarm_hour_start(); break; case 1: rtc_alarm_minute_start(); break; case 2: rtc_alarm_second_start(); break; case 3: rtc_alarm_time_start(); break; default: break; } } void rtc_alarm_stop(int argc, char **argv) { int index = 0; if (argc >= 2) { index = atoi(argv[1]); } switch(index) { case 0: rtc_alarm_hour_stop(); break; case 1: rtc_alarm_minute_stop(); break; case 2: rtc_alarm_second_stop(); break; case 3: rtc_alarm_time_stop(); break; default: break; } } void rtc_alarm_create(int argc, char **argv) { int index = 0; if (argc >= 2) { index = atoi(argv[1]); } switch(index) { case 0: rtc_alarm_hour_create(); break; case 1: rtc_alarm_minute_create(); break; case 2: rtc_alarm_second_create(); break; case 3: rtc_alarm_time_create(); break; default: break; } } void rtc_alarm_delete(int argc, char **argv) { int index = 0; if (argc >= 2) { index = atoi(argv[1]); } switch(index) { case 0: rtc_alarm_hour_delete(); break; case 1: rtc_alarm_minute_delete(); break; case 2: rtc_alarm_second_delete(); break; case 3: rtc_alarm_time_delete(); break; default: break; } } MSH_CMD_EXPORT(rtc_gettime, rtc get time); MSH_CMD_EXPORT(rtc_alarm_create, rtc alarm_create); MSH_CMD_EXPORT(rtc_alarm_delete, rtc alarm_delete); MSH_CMD_EXPORT(rtc_alarm_start, rtc alarm_start); MSH_CMD_EXPORT(rtc_alarm_stop, rtc alarm_stop); #endif ``` ## 总结 * RT-Thread RTC alarm组件,配置起来,稍微有点麻烦。 * Alarm闹钟功能,使能组件后,还是需要创建闹钟、开启闹钟、停止闹钟、删除闹钟业务代码的配合。 * 多使用,多总结。 ## 调试记录 ``` msh />rtc rtc_gettime rtc_alarm_create rtc_alarm_delete rtc_alarm_start rtc_alarm_stop msh />rtc_al rtc_alarm_create rtc_alarm_delete rtc_alarm_start rtc_alarm_stop msh />rtc_alarm_c rtc_alarm_create msh />rtc_alarm_create 0 msh />rtc rtc_gettime rtc_alarm_create rtc_alarm_delete rtc_alarm_start rtc_alarm_stop msh />rtc_al rtc_alarm_create rtc_alarm_delete rtc_alarm_start rtc_alarm_stop msh />rtc_alarm_c rtc_alarm_create msh />rtc_alarm_create 1 msh />al alarm_dump msh />alarm_dump | id | YYYY-MM-DD hh:mm:ss | week | flag | en | +----+---------------------+------+------+----+ | 0 | 2000-01-01 08:13:12 | 6 | M | 0 | | 1 | 2000-01-01 09:12:07 | 6 | H | 0 | | 2 | 2000-01-01 08:12:13 | 6 | S | 1 | +----+---------------------+------+------+----+ msh />rt rtc_gettime rtc_alarm_create rtc_alarm_delete rtc_alarm_start rtc_alarm_stop msh />rtc_al rtc_alarm_create rtc_alarm_delete rtc_alarm_start rtc_alarm_stop msh />rtc_alarm_st rtc_alarm_start rtc_alarm_stop msh />rtc_alarm_sta rtc_alarm_start msh />rtc_alarm_start 0 msh />rtc rtc_gettime rtc_alarm_create rtc_alarm_delete rtc_alarm_start rtc_alarm_stop msh />rtc_al rtc_alarm_create rtc_alarm_delete rtc_alarm_start rtc_alarm_stop msh />rtc_alarm_st rtc_alarm_start rtc_alarm_stop msh />rtc_alarm_sta rtc_alarm_start msh />rtc_alarm_start 1 msh />al alarm_dump msh />alarm_dump | id | YYYY-MM-DD hh:mm:ss | week | flag | en | +----+---------------------+------+------+----+ | 0 | 2000-01-01 08:13:12 | 6 | M | 1 | | 1 | 2000-01-01 09:12:07 | 6 | H | 1 | | 2 | 2000-01-01 08:12:29 | 6 | S | 1 | +----+---------------------+------+------+----+ msh /> msh />rtc_al rtc_alarm_create rtc_alarm_delete rtc_alarm_start rtc_alarm_stop msh />rtc_alarm_crw msh />rtc_alarm_cr rtc_alarm_create msh />rtc_alarm_create 2 msh />rtc rtc_gettime rtc_alarm_create rtc_alarm_delete rtc_alarm_start rtc_alarm_stop msh />rtc_al rtc_alarm_create rtc_alarm_delete rtc_alarm_start rtc_alarm_stop msh />rtc_alarm_star rtc_alarm_start msh />rtc_alarm_start 2 msh />[D/rtc.test] alarm_second_cb ok! [D/rtc.test] alarm_second_cb ok! [D/rtc.test] alarm_second_cb ok! [D/rtc.test] alarm_second_cb ok! rtc rtc_gettime rtc_alarm_create rtc_alarm_delete rtc_alarm_start rtc_alarm_stop msh />rtc_[D/rtc.test] alarm_second_cb ok! a-[D/rtc.test] alarm_second_cb ok! msh />rtc_a-[D/rtc.test] alarm_second_cb ok! rtc_alarm_create rtc_alarm_delete rtc_alarm_start rtc_alarm_stop msh />rtc_alarm_[D/rtc.test] alarm_second_cb ok! s[D/rtc.test] alarm_second_cb ok! rtc_alarm_start rtc_alarm_stop msh />rtc_alarm_st rtc_alarm_start rtc_alarm_stop msh />rtc_alarm_sto rtc_alarm_stop msh />rtc_alarm_stop[D/rtc.test] alarm_second_cb ok! rtc_alarm_stop msh />rtc_alarm_stop rtc_alarm_stop msh />rtc_alarm_stop 2 msh />al alarm_dump msh />alarm_dump | id | YYYY-MM-DD hh:mm:ss | week | flag | en | +----+---------------------+------+------+----+ | 0 | 2000-01-01 08:13:05 | 6 | S | 0 | | 1 | 2000-01-01 08:13:12 | 6 | M | 1 | | 2 | 2000-01-01 09:12:07 | 6 | H | 1 | | 3 | 2000-01-01 08:13:11 | 6 | S | 1 | +----+---------------------+------+------+----+ msh />[D/rtc.test] alarm_minute_cb ok! ```
32
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
张世争
学以致用
文章
131
回答
801
被采纳
173
关注TA
发私信
相关文章
1
RTC驱动框架几点建议
2
求助:RTT在STM32F407上使用内置的RTC设置日期需重启生效,设置时间即时生效,有遇到同样问题的吗?
3
[新人试水] LPC1768 Nano3_9 添加RTC
4
STM32 关于RTC的问题
5
stm32f4xx-HAL BSP的RTC设置不对
6
关于STM32的RTC设置年份不正确的问题
7
RTT的RTC驱动调试
8
rtc驱动中的bkp模块起不到防止时间的重新设置
9
rtc时钟跑十几个小时后,比实际时间快几秒怎么解决
10
stm32如何断电之后开发板rtc时间继续往前跑
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
ota在线升级
UART
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
at_device
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
张世争
8
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
KunYi
6
个答案
1
次被采纳
本月文章贡献
程序员阿伟
5
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部