drv_rtc.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. /*
  2. * File : drv_rtc.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2009-2013 RT-Thread Develop Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2017-04-05 lizhen9880 the first version for STM32F429
  13. */
  14. /* Includes ------------------------------------------------------------------*/
  15. #include "board.h"
  16. #include "drv_rtc.h"
  17. #include <rtdevice.h>
  18. #if defined(RT_USING_RTC)
  19. /* Private typedef -----------------------------------------------------------*/
  20. /* Private define ------------------------------------------------------------*/
  21. /* Private macro -------------------------------------------------------------*/
  22. #ifdef RT_RTC_DEBUG
  23. #define rtc_debug(format,args...) rt_kprintf(format, ##args)
  24. #else
  25. #define rtc_debug(format,args...)
  26. #endif
  27. /* Private variables ---------------------------------------------------------*/
  28. static struct rt_device rtc;
  29. RTC_HandleTypeDef RTC_Handler; //RTC句柄
  30. //RTC初始化
  31. //返回值:0,初始化成功;
  32. // 2,进入初始化模式失败;
  33. rt_uint8_t RTC_Init(void)
  34. {
  35. RTC_Handler.Instance=RTC;
  36. RTC_Handler.Init.HourFormat=RTC_HOURFORMAT_24;//RTC设置为24小时格式
  37. RTC_Handler.Init.AsynchPrediv=0X7F; //RTC异步分频系数(1~0X7F)
  38. RTC_Handler.Init.SynchPrediv=0XFF; //RTC同步分频系数(0~7FFF)
  39. RTC_Handler.Init.OutPut=RTC_OUTPUT_DISABLE;
  40. RTC_Handler.Init.OutPutPolarity=RTC_OUTPUT_POLARITY_HIGH;
  41. RTC_Handler.Init.OutPutType=RTC_OUTPUT_TYPE_OPENDRAIN;
  42. if(HAL_RTC_Init(&RTC_Handler)!=HAL_OK) return 2;
  43. if(HAL_RTCEx_BKUPRead(&RTC_Handler,RTC_BKP_DR0)!=0X5050)//是否第一次配置
  44. {
  45. // RTC_Set_Time(23,59,56,RTC_HOURFORMAT12_PM); //设置时间 ,根据实际时间修改
  46. // RTC_Set_Date(15,12,27,7); //设置日期
  47. HAL_RTCEx_BKUPWrite(&RTC_Handler,RTC_BKP_DR0,0X5050);//标记已经初始化过了
  48. }
  49. return 0;
  50. }
  51. //RTC底层驱动,时钟配置
  52. //此函数会被HAL_RTC_Init()调用
  53. //hrtc:RTC句柄
  54. void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
  55. {
  56. RCC_OscInitTypeDef RCC_OscInitStruct;
  57. RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
  58. __HAL_RCC_PWR_CLK_ENABLE();//使能电源时钟PWR
  59. HAL_PWR_EnableBkUpAccess();//取消备份区域写保护
  60. RCC_OscInitStruct.OscillatorType=RCC_OSCILLATORTYPE_LSE;//LSE配置
  61. RCC_OscInitStruct.PLL.PLLState=RCC_PLL_NONE;
  62. RCC_OscInitStruct.LSEState=RCC_LSE_ON; //RTC使用LSE
  63. HAL_RCC_OscConfig(&RCC_OscInitStruct);
  64. PeriphClkInitStruct.PeriphClockSelection=RCC_PERIPHCLK_RTC;//外设为RTC
  65. PeriphClkInitStruct.RTCClockSelection=RCC_RTCCLKSOURCE_LSE;//RTC时钟源为LSE
  66. HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
  67. __HAL_RCC_RTC_ENABLE();//RTC时钟使能
  68. }
  69. //设置闹钟时间(按星期闹铃,24小时制)
  70. //week:星期几(1~7) @ref RTC_WeekDay_Definitions
  71. //hour,min,sec:小时,分钟,秒钟
  72. void RTC_Set_AlarmA(rt_uint8_t week,rt_uint8_t hour,rt_uint8_t min,rt_uint8_t sec)
  73. {
  74. RTC_AlarmTypeDef RTC_AlarmSturuct;
  75. RTC_AlarmSturuct.AlarmTime.Hours=hour; //小时
  76. RTC_AlarmSturuct.AlarmTime.Minutes=min; //分钟
  77. RTC_AlarmSturuct.AlarmTime.Seconds=sec; //秒
  78. RTC_AlarmSturuct.AlarmTime.SubSeconds=0;
  79. RTC_AlarmSturuct.AlarmTime.TimeFormat=RTC_HOURFORMAT12_AM;
  80. RTC_AlarmSturuct.AlarmMask=RTC_ALARMMASK_NONE;//精确匹配星期,时分秒
  81. RTC_AlarmSturuct.AlarmSubSecondMask=RTC_ALARMSUBSECONDMASK_NONE;
  82. RTC_AlarmSturuct.AlarmDateWeekDaySel=RTC_ALARMDATEWEEKDAYSEL_WEEKDAY;//按星期
  83. RTC_AlarmSturuct.AlarmDateWeekDay=week; //星期
  84. RTC_AlarmSturuct.Alarm=RTC_ALARM_A; //闹钟A
  85. HAL_RTC_SetAlarm_IT(&RTC_Handler,&RTC_AlarmSturuct,RTC_FORMAT_BIN);
  86. HAL_NVIC_SetPriority(RTC_Alarm_IRQn,0x01,0x02); //抢占优先级1,子优先级2
  87. HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
  88. }
  89. //周期性唤醒定时器设置
  90. /*wksel: @ref RTCEx_Wakeup_Timer_Definitions
  91. #define RTC_WAKEUPCLOCK_RTCCLK_DIV16 ((uint32_t)0x00000000)
  92. #define RTC_WAKEUPCLOCK_RTCCLK_DIV8 ((uint32_t)0x00000001)
  93. #define RTC_WAKEUPCLOCK_RTCCLK_DIV4 ((uint32_t)0x00000002)
  94. #define RTC_WAKEUPCLOCK_RTCCLK_DIV2 ((uint32_t)0x00000003)
  95. #define RTC_WAKEUPCLOCK_CK_SPRE_16BITS ((uint32_t)0x00000004)
  96. #define RTC_WAKEUPCLOCK_CK_SPRE_17BITS ((uint32_t)0x00000006)
  97. */
  98. //cnt:自动重装载值.减到0,产生中断.
  99. void RTC_Set_WakeUp(rt_uint32_t wksel,rt_uint16_t cnt)
  100. {
  101. __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&RTC_Handler, RTC_FLAG_WUTF);//清除RTC WAKE UP的标志
  102. HAL_RTCEx_SetWakeUpTimer_IT(&RTC_Handler,cnt,wksel); //设置重装载值和时钟
  103. HAL_NVIC_SetPriority(RTC_WKUP_IRQn,0x02,0x02); //抢占优先级1,子优先级2
  104. HAL_NVIC_EnableIRQ(RTC_WKUP_IRQn);
  105. }
  106. //RTC闹钟中断服务函数
  107. void RTC_Alarm_IRQHandler(void)
  108. {
  109. HAL_RTC_AlarmIRQHandler(&RTC_Handler);
  110. }
  111. //RTC闹钟A中断处理回调函数
  112. void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
  113. {
  114. rt_kprintf("ALARM A!\r\n");
  115. }
  116. //RTC WAKE UP中断服务函数
  117. void RTC_WKUP_IRQHandler(void)
  118. {
  119. HAL_RTCEx_WakeUpTimerIRQHandler(&RTC_Handler);
  120. }
  121. time_t GetRTCTimeStamp(void)
  122. {
  123. RTC_TimeTypeDef RTC_TimeStruct;
  124. RTC_DateTypeDef RTC_DateStruct;
  125. struct tm tm_new;
  126. HAL_RTC_GetTime(&RTC_Handler,&RTC_TimeStruct,RTC_FORMAT_BIN);
  127. HAL_RTC_GetDate(&RTC_Handler,&RTC_DateStruct,RTC_FORMAT_BIN);
  128. tm_new.tm_sec = RTC_TimeStruct.Seconds;
  129. tm_new.tm_min = RTC_TimeStruct.Minutes;
  130. tm_new.tm_hour = RTC_TimeStruct.Hours;
  131. tm_new.tm_mday = RTC_DateStruct.Date;
  132. tm_new.tm_mon = RTC_DateStruct.Month-1;
  133. tm_new.tm_year = RTC_DateStruct.Year+100;
  134. return mktime(&tm_new);
  135. }
  136. rt_err_t SetRTCTimeStamp(time_t time_stamp)
  137. {
  138. RTC_TimeTypeDef RTC_TimeStruct;
  139. RTC_DateTypeDef RTC_DateStruct;
  140. struct tm *p_tm;
  141. p_tm = localtime(&time_stamp);
  142. if(p_tm->tm_year<100)
  143. {
  144. return RT_ERROR;
  145. }
  146. RTC_TimeStruct.Seconds = p_tm->tm_sec ;
  147. RTC_TimeStruct.Minutes = p_tm->tm_min ;
  148. RTC_TimeStruct.Hours = p_tm->tm_hour;
  149. RTC_DateStruct.Date = p_tm->tm_mday;
  150. RTC_DateStruct.Month = p_tm->tm_mon+1 ;
  151. RTC_DateStruct.Year = p_tm->tm_year-100;
  152. RTC_DateStruct.WeekDay = p_tm->tm_wday+1;
  153. HAL_RTC_SetTime(&RTC_Handler,&RTC_TimeStruct,RTC_FORMAT_BIN);
  154. HAL_RTC_SetDate(&RTC_Handler,&RTC_DateStruct,RTC_FORMAT_BIN);
  155. return RT_EOK;
  156. }
  157. /* Private function prototypes -----------------------------------------------*/
  158. /* Private functions ---------------------------------------------------------*/
  159. static rt_err_t rt_rtc_open(rt_device_t dev, rt_uint16_t oflag)
  160. {
  161. if (dev->rx_indicate != RT_NULL)
  162. {
  163. /* Open Interrupt */
  164. }
  165. return RT_EOK;
  166. }
  167. static rt_size_t rt_rtc_read(
  168. rt_device_t dev,
  169. rt_off_t pos,
  170. void* buffer,
  171. rt_size_t size)
  172. {
  173. return 0;
  174. }
  175. /***************************************************************************//**
  176. * @brief
  177. * Configure RTC device
  178. *
  179. * @details
  180. *
  181. * @note
  182. *
  183. * @param[in] dev
  184. * Pointer to device descriptor
  185. *
  186. * @param[in] cmd
  187. * RTC control command
  188. *
  189. * @param[in] args
  190. * Arguments
  191. *
  192. * @return
  193. * Error code
  194. ******************************************************************************/
  195. static rt_err_t rt_rtc_control(rt_device_t dev, int cmd, void *args)
  196. {
  197. rt_err_t result;
  198. RT_ASSERT(dev != RT_NULL);
  199. switch (cmd)
  200. {
  201. case RT_DEVICE_CTRL_RTC_GET_TIME:
  202. *(rt_uint32_t *)args = GetRTCTimeStamp();
  203. rtc_debug("RTC: get rtc_time %x\n", *(rt_uint32_t *)args());
  204. break;
  205. case RT_DEVICE_CTRL_RTC_SET_TIME:
  206. {
  207. result = SetRTCTimeStamp(*(rt_uint32_t *)args);
  208. rtc_debug("RTC: set rtc_time %x\n", *(rt_uint32_t *)args);
  209. /* Reset counter */
  210. }
  211. break;
  212. }
  213. return result;
  214. }
  215. /***************************************************************************//**
  216. * @brief
  217. * Register RTC device
  218. *
  219. * @details
  220. *
  221. * @note
  222. *
  223. * @param[in] device
  224. * Pointer to device descriptor
  225. *
  226. * @param[in] name
  227. * Device name
  228. *
  229. * @param[in] flag
  230. * Configuration flags
  231. *
  232. * @return
  233. * Error code
  234. ******************************************************************************/
  235. rt_err_t rt_hw_rtc_register(
  236. rt_device_t device,
  237. const char *name,
  238. rt_uint32_t flag)
  239. {
  240. RT_ASSERT(device != RT_NULL);
  241. device->type = RT_Device_Class_RTC;
  242. device->rx_indicate = RT_NULL;
  243. device->tx_complete = RT_NULL;
  244. device->init = RT_NULL;
  245. device->open = rt_rtc_open;
  246. device->close = RT_NULL;
  247. device->read = rt_rtc_read;
  248. device->write = RT_NULL;
  249. device->control = rt_rtc_control;
  250. device->user_data = RT_NULL; /* no private */
  251. /* register a character device */
  252. return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR | flag);
  253. }
  254. /***************************************************************************//**
  255. * @brief
  256. * Initialize all RTC module related hardware and register RTC device to kernel
  257. *
  258. * @details
  259. *
  260. * @note
  261. ******************************************************************************/
  262. int rt_hw_rtc_init(void)
  263. {
  264. RTC_Init();
  265. /* register rtc device */
  266. rt_hw_rtc_register(&rtc, RT_RTC_NAME, 0);
  267. return RT_EOK;
  268. }
  269. INIT_BOARD_EXPORT(rt_hw_rtc_init);
  270. #endif
  271. /***************************************************************************//**
  272. * @}
  273. ******************************************************************************/