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
24
25 static uint32_t calcWeekDay(uint32_t year, uint32_t month, uint32_t date);
26 /******************************************************************************************************************************************
27 * 函数名称: RTC_Init()
28 * 功能说明: RTC初始化
29 * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,有效值包括RTC
30 * RTC_InitStructure * initStruct 包含RTC相关设定值的结构体
31 * 输 出: 无
32 * 注意事项: 无
33 ******************************************************************************************************************************************/
RTC_Init(RTC_TypeDef * RTCx,RTC_InitStructure * initStruct)34 void RTC_Init(RTC_TypeDef * RTCx, RTC_InitStructure * initStruct)
35 {
36 SYS->CLKEN |= (1 << SYS_CLKEN_RTCBKP_Pos);
37
38 SYS->LRCCR &= ~(1 << SYS_LRCCR_OFF_Pos); //RTC使用32KHz RC时钟
39
40 SYS->CLKEN |= (1 << SYS_CLKEN_RTC_Pos) |
41 ((uint32_t)1 << SYS_CLKEN_ALIVE_Pos);
42
43 RTC_Stop(RTCx);
44
45 while(RTCx->CFGABLE == 0);
46
47 RTCx->MINSEC = (initStruct->Second << RTC_MINSEC_SEC_Pos) |
48 (initStruct->Minute << RTC_MINSEC_MIN_Pos);
49
50 RTCx->DATHUR = (initStruct->Hour << RTC_DATHUR_HOUR_Pos) |
51 (initStruct->Date << RTC_DATHUR_DATE_Pos);
52
53 RTCx->MONDAY = (calcWeekDay(initStruct->Year, initStruct->Month, initStruct->Date) << RTC_MONDAY_DAY_Pos) |
54 (initStruct->Month << RTC_MONDAY_MON_Pos);
55
56 RTCx->YEAR = initStruct->Year;
57
58 RTCx->LOAD = 1 << RTC_LOAD_TIME_Pos;
59
60 RTCx->IF = 0x1F;
61 RTCx->IE = (initStruct->SecondIEn << RTC_IE_SEC_Pos) |
62 (initStruct->MinuteIEn << RTC_IE_MIN_Pos);
63
64 if(initStruct->SecondIEn | initStruct->MinuteIEn)
65 {
66 NVIC_EnableIRQ(RTC_IRQn);
67 }
68 else
69 {
70 NVIC_DisableIRQ(RTC_IRQn);
71 }
72 }
73
74 /******************************************************************************************************************************************
75 * 函数名称: RTC_Start()
76 * 功能说明: 启动RTC
77 * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
78 * 输 出: 无
79 * 注意事项: 无
80 ******************************************************************************************************************************************/
RTC_Start(RTC_TypeDef * RTCx)81 void RTC_Start(RTC_TypeDef * RTCx)
82 {
83 RTCx->EN = 1;
84 }
85
86 /******************************************************************************************************************************************
87 * 函数名称: RTC_Stop()
88 * 功能说明: 停止RTC
89 * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
90 * 输 出: 无
91 * 注意事项: 无
92 ******************************************************************************************************************************************/
RTC_Stop(RTC_TypeDef * RTCx)93 void RTC_Stop(RTC_TypeDef * RTCx)
94 {
95 RTCx->EN = 0;
96 }
97
98 /******************************************************************************************************************************************
99 * 函数名称: RTC_GetDateTime()
100 * 功能说明: 获取当前的时间和日期
101 * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,有效值包括RTC
102 * RTC_DateTime * dateTime 获取到的时间、日期值存入此指针指向的结构体
103 * 输 出: 无
104 * 注意事项: 无
105 ******************************************************************************************************************************************/
RTC_GetDateTime(RTC_TypeDef * RTCx,RTC_DateTime * dateTime)106 void RTC_GetDateTime(RTC_TypeDef * RTCx, RTC_DateTime * dateTime)
107 {
108 dateTime->Year = RTCx->YEAR;
109 dateTime->Month = (RTCx->MONDAY & RTC_MONDAY_MON_Msk) >> RTC_MONDAY_MON_Pos;
110 dateTime->Date = (RTCx->DATHUR & RTC_DATHUR_DATE_Msk) >> RTC_DATHUR_DATE_Pos;
111 dateTime->Day = 1 << ((RTCx->MONDAY & RTC_MONDAY_DAY_Msk) >> RTC_MONDAY_DAY_Pos);
112 dateTime->Hour = (RTCx->DATHUR & RTC_DATHUR_HOUR_Msk) >> RTC_DATHUR_HOUR_Pos;
113 dateTime->Minute = (RTCx->MINSEC & RTC_MINSEC_MIN_Msk) >> RTC_MINSEC_MIN_Pos;
114 dateTime->Second = (RTCx->MINSEC & RTC_MINSEC_SEC_Msk) >> RTC_MINSEC_SEC_Pos;
115 }
116
117 /******************************************************************************************************************************************
118 * 函数名称: RTC_AlarmSetup()
119 * 功能说明: RTC闹钟设定
120 * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,有效值包括RTC
121 * RTC_AlarmStructure * alarmStruct 包含RTC闹钟设定值的结构体
122 * 输 出: 无
123 * 注意事项: 无
124 ******************************************************************************************************************************************/
RTC_AlarmSetup(RTC_TypeDef * RTCx,RTC_AlarmStructure * alarmStruct)125 void RTC_AlarmSetup(RTC_TypeDef * RTCx, RTC_AlarmStructure * alarmStruct)
126 {
127 while(RTCx->CFGABLE == 0);
128
129 RTCx->MINSECAL = (alarmStruct->Second << RTC_MINSECAL_SEC_Pos) |
130 (alarmStruct->Minute << RTC_MINSECAL_MIN_Pos);
131
132 RTCx->DAYHURAL = (alarmStruct->Hour << RTC_DAYHURAL_HOUR_Pos) |
133 (alarmStruct->Days << RTC_DAYHURAL_SUN_Pos);
134
135 RTCx->LOAD = 1 << RTC_LOAD_ALARM_Pos;
136 while(RTCx->LOAD & RTC_LOAD_ALARM_Msk);
137
138 RTCx->IF = (1 << RTC_IF_ALARM_Pos);
139 RTCx->IE &= ~RTC_IE_ALARM_Msk;
140 RTCx->IE |= (alarmStruct->AlarmIEn << RTC_IE_ALARM_Pos);
141
142 if(alarmStruct->AlarmIEn) NVIC_EnableIRQ(RTC_IRQn);
143 }
144
145 /******************************************************************************************************************************************
146 * 函数名称: calcWeekDay()
147 * 功能说明: 计算指定年、月、日是星期几
148 * 输 入: uint32_t year 年
149 * uint32_t month 月
150 * uint32_t date 日
151 * 输 出: uint32_t 0 星期日 1 星期一 ... ... 6 星期六
152 * 注意事项: 无
153 ******************************************************************************************************************************************/
calcWeekDay(uint32_t year,uint32_t month,uint32_t date)154 static uint32_t calcWeekDay(uint32_t year, uint32_t month, uint32_t date)
155 {
156 uint32_t i, cnt = 0;
157 const uint32_t daysOfMonth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
158
159 for(i = 1; i < month; i++) cnt += daysOfMonth[i];
160
161 cnt += date;
162
163 if((year%4 == 0) && ((year%100 != 0) || (year%400 == 0)) && (month >= 3)) cnt += 1;
164
165 cnt += (year - 1901) * 365;
166
167 for(i = 1901; i < year; i++)
168 {
169 if((i%4 == 0) && ((i%100 != 0) || (i%400 == 0))) cnt += 1;
170 }
171
172 return (cnt+1) % 7;
173 }
174
175 /******************************************************************************************************************************************
176 * 函数名称: RTC_INTEn()
177 * 功能说明: 中断使能
178 * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
179 * uint32_t it interrupt type,有效值RTC_IT_SECOND、RTC_IT_MINUTE、RTC_IT_HOUR、RTC_IT_DATE、RTC_IT_ALARM
180 * 输 出: 无
181 * 注意事项: 无
182 ******************************************************************************************************************************************/
RTC_INTEn(RTC_TypeDef * RTCx,uint32_t it)183 void RTC_INTEn(RTC_TypeDef * RTCx, uint32_t it)
184 {
185 RTCx->IE |= it;
186 }
187
188 /******************************************************************************************************************************************
189 * 函数名称: RTC_INTDis()
190 * 功能说明: 中断禁止
191 * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
192 * uint32_t it interrupt type,有效值RTC_IT_SECOND、RTC_IT_MINUTE、RTC_IT_HOUR、RTC_IT_DATE、RTC_IT_ALARM
193 * 输 出: 无
194 * 注意事项: 无
195 ******************************************************************************************************************************************/
RTC_INTDis(RTC_TypeDef * RTCx,uint32_t it)196 void RTC_INTDis(RTC_TypeDef * RTCx, uint32_t it)
197 {
198 RTCx->IE &= ~it;
199 }
200
201 /******************************************************************************************************************************************
202 * 函数名称: RTC_INTClr()
203 * 功能说明: 中断标志清除
204 * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
205 * uint32_t it interrupt type,有效值RTC_IT_SECOND、RTC_IT_MINUTE、RTC_IT_HOUR、RTC_IT_DATE、RTC_IT_ALARM
206 * 输 出: 无
207 * 注意事项: 无
208 ******************************************************************************************************************************************/
RTC_INTClr(RTC_TypeDef * RTCx,uint32_t it)209 void RTC_INTClr(RTC_TypeDef * RTCx, uint32_t it)
210 {
211 RTCx->IF = it;
212 }
213
214 /******************************************************************************************************************************************
215 * 函数名称: RTC_INTStat()
216 * 功能说明: 中断状态
217 * 输 入: RTC_TypeDef * RTCx 指定要被设置的RTC,可取值包括RTC
218 * uint32_t it interrupt type,有效值RTC_IT_SECOND、RTC_IT_MINUTE、RTC_IT_HOUR、RTC_IT_DATE、RTC_IT_ALARM
219 * 输 出: uint32_t 1 秒中断发生 0 秒中断未发生
220 * 注意事项: 无
221 ******************************************************************************************************************************************/
RTC_INTStat(RTC_TypeDef * RTCx,uint32_t it)222 uint32_t RTC_INTStat(RTC_TypeDef * RTCx, uint32_t it)
223 {
224 return (RTCx->IF & it) ? 1 : 0;
225 }
226