SWM320_rtc.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. /******************************************************************************************************************************************
  2. * 文件名称: SWM320_rtc.c
  3. * 功能说明: SWM320单片机的RTC驱动库
  4. * 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
  5. * 注意事项:
  6. * 版本日期: V1.1.0 2017年10月25日
  7. * 升级记录:
  8. *
  9. *
  10. *******************************************************************************************************************************************
  11. * @attention
  12. *
  13. * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
  14. * REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
  15. * FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
  16. * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
  17. * -ECTION WITH THEIR PRODUCTS.
  18. *
  19. * COPYRIGHT 2012 Synwit Technology
  20. *******************************************************************************************************************************************/
  21. #include "SWM320.h"
  22. #include "SWM320_rtc.h"
  23. static uint32_t calcWeekDay(uint32_t year, uint32_t month, uint32_t date);
  24. /******************************************************************************************************************************************
  25. * 函数名称: RTC_Init()
  26. * 功能说明: RTC初始化
  27. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,有效值包括RTC
  28. * RTC_InitStructure * initStruct 包含RTC相关设定值的结构体
  29. * 输 出: 无
  30. * 注意事项: 无
  31. ******************************************************************************************************************************************/
  32. void RTC_Init(RTC_TypeDef *RTCx, RTC_InitStructure *initStruct)
  33. {
  34. SYS->CLKEN |= (1 << SYS_CLKEN_RTCBKP_Pos);
  35. SYS->LRCCR &= ~(1 << SYS_LRCCR_OFF_Pos); //RTC使用32KHz RC时钟
  36. SYS->CLKEN |= (1 << SYS_CLKEN_RTC_Pos) |
  37. ((uint32_t)1 << SYS_CLKEN_ALIVE_Pos);
  38. RTC_Stop(RTCx);
  39. while (RTCx->CFGABLE == 0)
  40. ;
  41. RTCx->MINSEC = (initStruct->Second << RTC_MINSEC_SEC_Pos) |
  42. (initStruct->Minute << RTC_MINSEC_MIN_Pos);
  43. RTCx->DATHUR = (initStruct->Hour << RTC_DATHUR_HOUR_Pos) |
  44. (initStruct->Date << RTC_DATHUR_DATE_Pos);
  45. RTCx->MONDAY = (calcWeekDay(initStruct->Year, initStruct->Month, initStruct->Date) << RTC_MONDAY_DAY_Pos) |
  46. (initStruct->Month << RTC_MONDAY_MON_Pos);
  47. RTCx->YEAR = initStruct->Year;
  48. RTCx->LOAD = 1 << RTC_LOAD_TIME_Pos;
  49. RTCx->IF = 0x1F;
  50. RTCx->IE = (initStruct->SecondIEn << RTC_IE_SEC_Pos) |
  51. (initStruct->MinuteIEn << RTC_IE_MIN_Pos);
  52. if (initStruct->SecondIEn | initStruct->MinuteIEn)
  53. {
  54. NVIC_EnableIRQ(RTC_IRQn);
  55. }
  56. else
  57. {
  58. NVIC_DisableIRQ(RTC_IRQn);
  59. }
  60. }
  61. /******************************************************************************************************************************************
  62. * 函数名称: RTC_Start()
  63. * 功能说明: 启动RTC
  64. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  65. * 输 出: 无
  66. * 注意事项: 无
  67. ******************************************************************************************************************************************/
  68. void RTC_Start(RTC_TypeDef *RTCx)
  69. {
  70. RTCx->EN = 1;
  71. }
  72. /******************************************************************************************************************************************
  73. * 函数名称: RTC_Stop()
  74. * 功能说明: 停止RTC
  75. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  76. * 输 出: 无
  77. * 注意事项: 无
  78. ******************************************************************************************************************************************/
  79. void RTC_Stop(RTC_TypeDef *RTCx)
  80. {
  81. RTCx->EN = 0;
  82. }
  83. /******************************************************************************************************************************************
  84. * 函数名称: RTC_GetDateTime()
  85. * 功能说明: 获取当前的时间和日期
  86. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,有效值包括RTC
  87. * RTC_DateTime * dateTime 获取到的时间、日期值存入此指针指向的结构体
  88. * 输 出: 无
  89. * 注意事项: 无
  90. ******************************************************************************************************************************************/
  91. void RTC_GetDateTime(RTC_TypeDef *RTCx, RTC_DateTime *dateTime)
  92. {
  93. dateTime->Year = RTCx->YEAR;
  94. dateTime->Month = (RTCx->MONDAY & RTC_MONDAY_MON_Msk) >> RTC_MONDAY_MON_Pos;
  95. dateTime->Date = (RTCx->DATHUR & RTC_DATHUR_DATE_Msk) >> RTC_DATHUR_DATE_Pos;
  96. dateTime->Day = 1 << ((RTCx->MONDAY & RTC_MONDAY_DAY_Msk) >> RTC_MONDAY_DAY_Pos);
  97. dateTime->Hour = (RTCx->DATHUR & RTC_DATHUR_HOUR_Msk) >> RTC_DATHUR_HOUR_Pos;
  98. dateTime->Minute = (RTCx->MINSEC & RTC_MINSEC_MIN_Msk) >> RTC_MINSEC_MIN_Pos;
  99. dateTime->Second = (RTCx->MINSEC & RTC_MINSEC_SEC_Msk) >> RTC_MINSEC_SEC_Pos;
  100. }
  101. /******************************************************************************************************************************************
  102. * 函数名称: RTC_AlarmSetup()
  103. * 功能说明: RTC闹钟设定
  104. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,有效值包括RTC
  105. * RTC_AlarmStructure * alarmStruct 包含RTC闹钟设定值的结构体
  106. * 输 出: 无
  107. * 注意事项: 无
  108. ******************************************************************************************************************************************/
  109. void RTC_AlarmSetup(RTC_TypeDef *RTCx, RTC_AlarmStructure *alarmStruct)
  110. {
  111. while (RTCx->CFGABLE == 0)
  112. ;
  113. RTCx->MINSECAL = (alarmStruct->Second << RTC_MINSECAL_SEC_Pos) |
  114. (alarmStruct->Minute << RTC_MINSECAL_MIN_Pos);
  115. RTCx->DAYHURAL = (alarmStruct->Hour << RTC_DAYHURAL_HOUR_Pos) |
  116. (alarmStruct->Days << RTC_DAYHURAL_SUN_Pos);
  117. RTCx->LOAD = 1 << RTC_LOAD_ALARM_Pos;
  118. while (RTCx->LOAD & RTC_LOAD_ALARM_Msk)
  119. ;
  120. RTCx->IF = (1 << RTC_IF_ALARM_Pos);
  121. RTCx->IE &= ~RTC_IE_ALARM_Msk;
  122. RTCx->IE |= (alarmStruct->AlarmIEn << RTC_IE_ALARM_Pos);
  123. if (alarmStruct->AlarmIEn)
  124. NVIC_EnableIRQ(RTC_IRQn);
  125. }
  126. /******************************************************************************************************************************************
  127. * 函数名称: calcWeekDay()
  128. * 功能说明: 计算指定年、月、日是星期几
  129. * 输 入: uint32_t year 年
  130. * uint32_t month 月
  131. * uint32_t date 日
  132. * 输 出: uint32_t 0 星期日 1 星期一 ... ... 6 星期六
  133. * 注意事项: 无
  134. ******************************************************************************************************************************************/
  135. static uint32_t calcWeekDay(uint32_t year, uint32_t month, uint32_t date)
  136. {
  137. uint32_t i, cnt = 0;
  138. const uint32_t daysOfMonth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  139. for (i = 1; i < month; i++)
  140. cnt += daysOfMonth[i];
  141. cnt += date;
  142. if ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)) && (month >= 3))
  143. cnt += 1;
  144. cnt += (year - 1901) * 365;
  145. for (i = 1901; i < year; i++)
  146. {
  147. if ((i % 4 == 0) && ((i % 100 != 0) || (i % 400 == 0)))
  148. cnt += 1;
  149. }
  150. return (cnt + 1) % 7;
  151. }
  152. /******************************************************************************************************************************************
  153. * 函数名称: RTC_IntSecondEn()
  154. * 功能说明: 秒中断使能
  155. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  156. * 输 出: 无
  157. * 注意事项: 无
  158. ******************************************************************************************************************************************/
  159. void RTC_IntSecondEn(RTC_TypeDef *RTCx)
  160. {
  161. RTCx->IE |= (1 << RTC_IE_SEC_Pos);
  162. }
  163. /******************************************************************************************************************************************
  164. * 函数名称: RTC_IntSecondDis()
  165. * 功能说明: 秒中断禁止
  166. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  167. * 输 出: 无
  168. * 注意事项: 无
  169. ******************************************************************************************************************************************/
  170. void RTC_IntSecondDis(RTC_TypeDef *RTCx)
  171. {
  172. RTCx->IE &= ~(1 << RTC_IE_SEC_Pos);
  173. }
  174. /******************************************************************************************************************************************
  175. * 函数名称: RTC_IntSecondClr()
  176. * 功能说明: 秒中断标志清除
  177. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  178. * 输 出: 无
  179. * 注意事项: 无
  180. ******************************************************************************************************************************************/
  181. void RTC_IntSecondClr(RTC_TypeDef *RTCx)
  182. {
  183. RTCx->IF = (1 << RTC_IF_SEC_Pos);
  184. }
  185. /******************************************************************************************************************************************
  186. * 函数名称: RTC_IntSecondStat()
  187. * 功能说明: 秒中断状态
  188. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  189. * 输 出: uint32_t 1 秒中断发生 0 秒中断未发生
  190. * 注意事项: 无
  191. ******************************************************************************************************************************************/
  192. uint32_t RTC_IntSecondStat(RTC_TypeDef *RTCx)
  193. {
  194. return (RTCx->IF & RTC_IF_SEC_Msk) ? 1 : 0;
  195. }
  196. /******************************************************************************************************************************************
  197. * 函数名称: RTC_IntMinuteEn()
  198. * 功能说明: 分中断使能
  199. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  200. * 输 出: 无
  201. * 注意事项: 无
  202. ******************************************************************************************************************************************/
  203. void RTC_IntMinuteEn(RTC_TypeDef *RTCx)
  204. {
  205. RTCx->IE |= (1 << RTC_IE_MIN_Pos);
  206. }
  207. /******************************************************************************************************************************************
  208. * 函数名称: RTC_IntMinuteDis()
  209. * 功能说明: 分中断禁止
  210. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  211. * 输 出: 无
  212. * 注意事项: 无
  213. ******************************************************************************************************************************************/
  214. void RTC_IntMinuteDis(RTC_TypeDef *RTCx)
  215. {
  216. RTCx->IE &= ~(1 << RTC_IE_MIN_Pos);
  217. }
  218. /******************************************************************************************************************************************
  219. * 函数名称: RTC_IntMinuteClr()
  220. * 功能说明: 分中断标志清除
  221. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  222. * 输 出: 无
  223. * 注意事项: 无
  224. ******************************************************************************************************************************************/
  225. void RTC_IntMinuteClr(RTC_TypeDef *RTCx)
  226. {
  227. RTCx->IF = (1 << RTC_IF_MIN_Pos);
  228. }
  229. /******************************************************************************************************************************************
  230. * 函数名称: RTC_IntMinuteStat()
  231. * 功能说明: 分中断状态
  232. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  233. * 输 出: uint32_t 1 分中断发生 0 分中断未发生
  234. * 注意事项: 无
  235. ******************************************************************************************************************************************/
  236. uint32_t RTC_IntMinuteStat(RTC_TypeDef *RTCx)
  237. {
  238. return (RTCx->IF & RTC_IF_MIN_Msk) ? 1 : 0;
  239. }
  240. /******************************************************************************************************************************************
  241. * 函数名称: RTC_IntHourEn()
  242. * 功能说明: 时中断使能
  243. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  244. * 输 出: 无
  245. * 注意事项: 无
  246. ******************************************************************************************************************************************/
  247. void RTC_IntHourEn(RTC_TypeDef *RTCx)
  248. {
  249. RTCx->IE |= (1 << RTC_IE_HOUR_Pos);
  250. }
  251. /******************************************************************************************************************************************
  252. * 函数名称: RTC_IntHourDis()
  253. * 功能说明: 时中断禁止
  254. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  255. * 输 出: 无
  256. * 注意事项: 无
  257. ******************************************************************************************************************************************/
  258. void RTC_IntHourDis(RTC_TypeDef *RTCx)
  259. {
  260. RTCx->IE &= ~(1 << RTC_IE_HOUR_Pos);
  261. }
  262. /******************************************************************************************************************************************
  263. * 函数名称: RTC_IntHourClr()
  264. * 功能说明: 时中断标志清除
  265. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  266. * 输 出: 无
  267. * 注意事项: 无
  268. ******************************************************************************************************************************************/
  269. void RTC_IntHourClr(RTC_TypeDef *RTCx)
  270. {
  271. RTCx->IF = (1 << RTC_IF_HOUR_Pos);
  272. }
  273. /******************************************************************************************************************************************
  274. * 函数名称: RTC_IntHourStat()
  275. * 功能说明: 时中断状态
  276. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  277. * 输 出: uint32_t 1 时中断发生 0 时中断未发生
  278. * 注意事项: 无
  279. ******************************************************************************************************************************************/
  280. uint32_t RTC_IntHourStat(RTC_TypeDef *RTCx)
  281. {
  282. return (RTCx->IF & RTC_IF_HOUR_Msk) ? 1 : 0;
  283. }
  284. /******************************************************************************************************************************************
  285. * 函数名称: RTC_IntDateEn()
  286. * 功能说明: 日中断使能
  287. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  288. * 输 出: 无
  289. * 注意事项: 无
  290. ******************************************************************************************************************************************/
  291. void RTC_IntDateEn(RTC_TypeDef *RTCx)
  292. {
  293. RTCx->IE |= (1 << RTC_IE_DATE_Pos);
  294. }
  295. /******************************************************************************************************************************************
  296. * 函数名称: RTC_IntDateDis()
  297. * 功能说明: 日中断禁止
  298. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  299. * 输 出: 无
  300. * 注意事项: 无
  301. ******************************************************************************************************************************************/
  302. void RTC_IntDateDis(RTC_TypeDef *RTCx)
  303. {
  304. RTCx->IE &= ~(1 << RTC_IE_DATE_Pos);
  305. }
  306. /******************************************************************************************************************************************
  307. * 函数名称: RTC_IntDateClr()
  308. * 功能说明: 日中断标志清除
  309. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  310. * 输 出: 无
  311. * 注意事项: 无
  312. ******************************************************************************************************************************************/
  313. void RTC_IntDateClr(RTC_TypeDef *RTCx)
  314. {
  315. RTCx->IF = (1 << RTC_IF_DATE_Pos);
  316. }
  317. /******************************************************************************************************************************************
  318. * 函数名称: RTC_IntDateStat()
  319. * 功能说明: 日中断状态
  320. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  321. * 输 出: uint32_t 1 日中断发生 0 日中断未发生
  322. * 注意事项: 无
  323. ******************************************************************************************************************************************/
  324. uint32_t RTC_IntDateStat(RTC_TypeDef *RTCx)
  325. {
  326. return (RTCx->IF & RTC_IF_DATE_Msk) ? 1 : 0;
  327. }
  328. /******************************************************************************************************************************************
  329. * 函数名称: RTC_IntAlarmEn()
  330. * 功能说明: 闹钟中断使能
  331. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  332. * 输 出: 无
  333. * 注意事项: 无
  334. ******************************************************************************************************************************************/
  335. void RTC_IntAlarmEn(RTC_TypeDef *RTCx)
  336. {
  337. RTCx->IE |= (1 << RTC_IE_ALARM_Pos);
  338. }
  339. /******************************************************************************************************************************************
  340. * 函数名称: RTC_IntAlarmDis()
  341. * 功能说明: 闹钟中断禁止
  342. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  343. * 输 出: 无
  344. * 注意事项: 无
  345. ******************************************************************************************************************************************/
  346. void RTC_IntAlarmDis(RTC_TypeDef *RTCx)
  347. {
  348. RTCx->IE &= ~(1 << RTC_IE_ALARM_Pos);
  349. }
  350. /******************************************************************************************************************************************
  351. * 函数名称: RTC_IntAlarmClr()
  352. * 功能说明: 闹钟中断标志清除
  353. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  354. * 输 出: 无
  355. * 注意事项: 无
  356. ******************************************************************************************************************************************/
  357. void RTC_IntAlarmClr(RTC_TypeDef *RTCx)
  358. {
  359. RTCx->IF = (1 << RTC_IF_ALARM_Pos);
  360. }
  361. /******************************************************************************************************************************************
  362. * 函数名称: RTC_IntAlarmStat()
  363. * 功能说明: 闹钟中断状态
  364. * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
  365. * 输 出: uint32_t 1 闹钟中断发生 0 闹钟中断未发生
  366. * 注意事项: 无
  367. ******************************************************************************************************************************************/
  368. uint32_t RTC_IntAlarmStat(RTC_TypeDef *RTCx)
  369. {
  370. return (RTCx->IF & RTC_IF_ALARM_Msk) ? 1 : 0;
  371. }