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