Chinaunix首页 | 论坛 | 博客
  • 博客访问: 226501
  • 博文数量: 52
  • 博客积分: 15
  • 博客等级: 民兵
  • 技术积分: 390
  • 用 户 组: 普通用户
  • 注册时间: 2012-09-06 09:31
文章分类

全部博文(52)

文章存档

2015年(1)

2014年(44)

2013年(7)

我的朋友

分类: 嵌入式

2014-05-30 09:38:28

"RTC"是Real Time Clock 的简称,意为实时时钟。stm32提供了一个秒中断源和一个闹钟中断源。
 
RTC的技术器是一个32位的计数器,使用32.768khz的外部晶振。
 
2038年问题
 
 在计算机应用上,2038年问题可能会导致某些软件在2038年无法正常工作。所有使用UNIX时间表示时间的程序都将受其影响,因为它们以自1970年1月1日经过的秒数(忽略闰秒)来表示时间。这种时间表示法在类Unix(Unix-like)操作系统上是一个标准,并会影响以其C编程语言开发给其他大部份操作系统使用的软件。
    在大部份的32位操作系统上,此“time_t”数据模式使用一个有正负号的32位元整数(signedint32)存储计算的秒数。也就是说最大可以计数的秒数为 2^31次方 可以算得:
                2^31/3600/24/365 ≈ 68年
所以依照此“time_t”标准,在此格式能被表示的最后时间是2038年1月19日03:14:07,星期二(UTC)。超过此一瞬间,时间将会被掩盖(wrap around)且在内部被表示为一个负数,并造成程序无法工作,因为它们无法将此时间识别为2038年,而可能会依个别实作而跳回1970年或1901年。
 
    对于PC机来说,时间开始于1980年1月1日,并以无正负符号的32位整数的形式按秒递增,这与UNIX时间非常类似。可以算得:
                 2^32/3600/24/365 ≈ 136年
到2116年,这个整数将溢出。
 
    Windows NT使用64位整数来计时。但是,它使用100纳秒作为增量单位,且时间开始于1601年1月1日,所以NT将遇到2184年问题。
 
苹果公司声明,Mac在29,940年之前不会出现时间问题!
 
        由于RTC是一个32位计数器,同样其计时时间是有限的。库函数中使用到了C标准时间库,时间库中的计时起始时间是1900年,可以知道时间库中不是用 有符号位的32位整数来表示时间的,否则在1968年就已经溢出了。如果用32位无符号整数计时,其溢出时间为2036年左右,所以会遇到这个问题。
 
    直接操作寄存器中,可以自由设定这个时间戳起始的年份,RTC的32位寄存器存储的只是距离这个起始年份的总秒数,所以不会遇到这个问题。而且可以用无符号32位的二进制表示时间,这意味着此类系统的时间戳可以表示更多的秒数。但是由于其使用32位寄存器表示秒数,最大只能计时到136年后。
 
本例实现使用stm32每秒输出一次当前的时间,并设置一个闹钟,到时间时输出提醒信息。
 


直接操作寄存器
 
RTC实时时钟的操作原则是 在每次读写前都要保证上一次读写完成。
 
代码较多,使用到的寄存器请参见手册  (system.h 和 stm32f10x_it.h 等相关代码参照 )
 
User/main.c
01 #include    
02 #include "system.h"
03 #include "usart.h"
04 #include "rtc.h"    
05  
06 #define LED1 PAout(4)
07 #define LED2 PAout(5)
08  
09 void Gpio_Init(void);
10  
11 extern const u8* Week_Table[7];
12  
13 int main(void)
14 {                
15  
16  
17     Rcc_Init(9);                          //系统时钟设置
18  
19     Usart1_Init(72,9600);
20  
21     Nvic_Init(0,0,RTC_IRQChannel,0);      //设置中断
22  
23      
24     Gpio_Init();
25  
26     Rtc_Init();
27  
28     //Rtc_TIME_AutoSet();               //将当前编译时间作为RTC开始时间
29     Rtc_TIME_Set(2012,7,7,20,50,0);     //设定开始时间 参数说明:年,月,日,时,分,秒
30      
31     Rtc_ALARM_Set(2012,7,7,20,50,30);   //设定闹钟事件时间                                 
32  
33     LED1 = 1;
34      
35     while(1);      
36 }
37  
38  
39 void Gpio_Init(void)
40 {
41     RCC->APB2ENR|=1<<2;    //使能PORTA时钟    
42  
43     GPIOA->CRL&=0x0000FFFF; // PA0~3设置为浮空输入,PA4~7设置为推挽输出
44     GPIOA->CRL|=0x33334444;
45      
46     //USART1 串口I/O设置
47  
48     GPIOA -> CRH&=0xFFFFF00F;   //设置USART1 的Tx(PA.9)为第二功能推挽,50MHz;Rx(PA.10)为浮空输入
49     GPIOA -> CRH|=0x000008B0;     
50 }
User/stm32f103x_it.c
01 #include "stm32f10x_it.h"
02 #include "system.h"
03 #include "stdio.h"
04 #include "rtc.h"
05  
06 #define LED1 PAout(4)
07 #define LED2 PAout(5)
08 #define LED3 PAout(6)
09 #define LED4 PAout(7)
10  
11 //extern void Wwdg_Feed(void);
12 //extern u16 Read_Bkp(u8 reg);
13 extern void Rtc_Get(void);
14 extern const u8* Week_Table[7];
15  
16 void RTC_IRQHandler(void)
17 {
18  
19     if(RTC->CRL&0x0001)                  //秒钟中断
20     {
21         LED4 = !LED4;
22         Rtc_Get();
23  
24         printf("\r\n Time : %d - %d - %d,%d : %d : %d ,Today is %s \r\n",
25      
26                 timer.year,
27      
28                 timer.month,
29      
30                 timer.date,
31      
32                 timer.hour,
33      
34                 timer.minute,
35      
36                 timer.second,
37                 Week_Table[timer.week]
38         );     
39     }
40  
41     if(RTC->CRL&0x0002)                  //闹钟中断
42     {
43         LED3 = 1;
44              
45         printf("\r\nIt's time to do sth.\r\n");
46  
47         RTC->CRL &= ~(0x0002);           //清除闹钟中断   
48  
49     }
50  
51     RTC->CRL &= 0x0FFA;              //清除溢出,秒钟中断
52  
53     while(!(RTC->CRL &(1<<5)));            //等待RTC寄存器操作完成
54  
55 }
Library/src/rtc.c
001 #include    
002 #include "rtc.h"
003 #include "stdio.h"
004  
005 tm timer;                   //定义时钟结构体,主函数直接可以调用此结构体读出时间
006  
007 //平年的月份日期表,月份缩写表
008 const u8 Days_Table[12]={31,28,31,30,31,30,31,31,30,31,30,31};
009 const u8 Month_Table[12][3]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
010  
011 const u8* Week_Table[7]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
012  
013 //月修正数据表                                                                        
014 u8 const _Week[12]={0,3,3,6,1,4,6,2,5,0,3,5};
015  
016 void Rtc_Init(void)
017 {
018     RCC->APB1ENR |= 1<<28; //使能PWR时钟
019     RCC->APB1ENR |= 1<<27;  //使能BKP时钟,RTC校准在BKP相关寄存器中
020     PWR->CR |= 1<<8;       //取消BKP相关寄存器写保护
021  
022     //RCC->BDCR |= 1<<16;  //备份区域软复位
023     //RCC->BDCR |= ~(1<<16);   //备份区域软复位结束
024  
025     RCC->BDCR |= 1<<0;     //外部低速时钟(LSE)使能
026  
027     while(!(RCC->BDCR & 0x02));  //等待外部时钟就绪
028  
029     RCC->BDCR |= 1<<8;         //LSE作为RTC时钟
030     RCC->BDCR |= 1<<15;            //RTC时钟使能
031  
032     while(!(RTC->CRL & (1<<5)));   //等待RTC寄存器最后一次操作完成
033     while(!(RTC->CRL & (1<<3)));   //等待RTC寄存器同步完成
034  
035     RTC->CRH |= 0x07;                //允许溢出中断[2],闹钟中断[1],秒中断[0],CRH寄存器低三位有效 
036  
037     while(!(RTC->CRL & (1<<5)));   //等待RTC寄存器最后一次操作完成
038  
039     RTC->CRL |=  1<<4;             //进入配置模式
040     RTC->PRLH = 0x0000;             
041     RTC->PRLL = 32767;               //设定分频值
042  
043     //Rtc_TIME_AutoSet();               //将当前编译时间写入寄存器
044     //Rtc_TIME_Set(2012,7,7,20,50,0);   //年,月,日,时,分,秒
045  
046     RTC->CRL &= ~(1<<4);           //退出配置模式,开始更新RTC寄存器
047     while(!(RTC->CRL & (1<<5)));   //等待RTC寄存器最后一次操作完成
048  
049 }
050  
051  
052 //设定RTC开始计时时间
053 void Rtc_TIME_Set(u16 year,u8 month,u8 date,u8 hour,u8 minute, u8 second)
054 {
055         u32 sec;   
056  
057         sec = Date_TO_Sec(year,month,date,hour,minute,second);
058      
059         //printf("\nRtc TIME Set  Sec = %x\n",sec);
060      
061         RCC->APB1ENR |= 1<<28;                         //使能PWR时钟,方便独立调用此函数
062         RCC->APB1ENR |= 1<<27;                         //使能BKP时钟
063         PWR->CR |= 1<<8;                               //取消写保护
064      
065         RTC-> CRL |= 1<<4;                             //允许配置
066          
067         RTC-> CNTL = sec&0xffff;                     //取低16位
068         RTC-> CNTH = sec>>16;                          //取高16位
069      
070         RTC-> CRL &= ~(1<<4);                          //开始RTC寄存器更新
071      
072         while(!(RTC->CRL&(1<<5)));                     //等待RTC寄存器操作完成 
073 }
074  
075  
076  
077  
078 //判断是否是闰年函数
079 //
080 //判断方法:
081 //      普通年能整除4且不能整除100的为闰年。(如2004年就是闰年,1900年不是闰年)
082 //      世纪年能整除400的是闰年。(如2000年是闰年,1900年不是闰年)
083 //
084 //返回: 1,是闰年     0,不是闰年
085 u8 Is_LeapYear(u16 year)
086 {            
087     if(year%4==0)               //必须能被4整除
088     {
089         if(year%100==0)
090         {
091             if(year%400==0)
092                 return 1;       //如果以00结尾,还要能被400整除       
093             else
094                 return 0;  
095         }else{
096             return 1;  
097         }
098     }else{
099          return 0; 
100     }
101 }
102  
103  
104 //将时间转化为到1970年1月1日的总秒数
105 //Bugs:此函数秒数会多20左右,所以函数返回值做了校正,校正后没有问题
106 //待优化
107 u32 Date_TO_Sec(u16 year,u8 month,u8 date,u8 hour,u8 minute, u8 second)
108 {
109     u16 t;
110     u32 sec;
111  
112     if(year >= 1970 && year<= 2106)         //判断是否为合法年份,RTC的时间是从1970开始,只能由32位表示秒数,最大只能到2106年左右
113     {
114         for(t= 1970 ;t
115         {
116             if(Is_LeapYear(t))            //判断是否为闰年
117  
118                 sec += 31622400;
119             else   
120                 sec += 31536000;       
121         }  
122  
123  
124         for(t=0;t
125         {
126             sec += (u32) Days_Table[t]*86400;          
127             if(Is_LeapYear(year) && t== 1)              //闰年加一天的秒钟数
128                 sec += 86400;                          
129      
130         }
131      
132         sec += (u32)(date-1)*86400;                     //本月日期的秒数累加
133         sec += (u32)(hour)*3600;
134         sec += (u32)(minute)*60;
135         sec += second;
136     }
137  
138     return sec-20;                                      //校正20秒,原因不详
139  
140 }
141  
142  
143  
144 //自动获取当前时间配置RTC
145 //可以根据MDK关键字获取时间 
146 //__DATE__  获取编译日期, 格式为: Jul 7 2012 
147 //__TIME__  获取编译时间, 格式为: 14:54:44
148  
149 void Rtc_TIME_AutoSet()
150 {
151     u16 year,i=0,j=0;
152     u8  mon,date,sec,min,hour;
153  
154     u8 *_date = __DATE__;
155     u8 *_time = __TIME__;
156  
157     for(i=0;i<12;i++)
158     {
159         for(j=0;j<3;j++)
160         {
161             if(Month_Table[i][j] == _date[j]) mon = i;  //得到月份
162         }
163     }
164  
165  
166     if(_date[4]==' '){          //得到日期
167         date=_date[5]-'0';      //-'0'操作将字符型转换为整型,参考ASCII码的转换,eg '7'-'0' =7
168     }else{
169         date=10*(_date[4]-'0')+_date[5]-'0';
170     }
171            
172  
173     year=1000*(_date[7]-'0')+100*(_date[8]-'0')+10*(_date[9]-'0')+_date[10]-'0';  //得到年份      
174     hour=10*(_time[0]-'0')+_time[1]-'0';                                          //得到小时
175     min=10*(_time[3]-'0')+_time[4]-'0';                                          
176     sec=10*(_time[6]-'0')+_time[7]-'0';
177      
178  
179     //printf("\n%d-%d-%d  %d:%d:%d\n",year,mon,date,hour,min,sec);
180  
181     Rtc_TIME_Set(year,mon,date,hour,min,sec);
182 }
183  
184  
185 //获取RTC时间
186 void Rtc_Get()
187 {
188     u32 secs,days,temp,years = 1970,months = 0;    
189  
190     secs = RTC->CNTH;    //读取RTC的当前时间值(距1970年的总秒数)
191     secs <<= 16;
192     secs += RTC->CNTL;
193  
194     //printf("\nRtc_Get  Sec = %x\n",secs);
195  
196     days = secs/86400;
197     if(days > 0)         //超过一天
198     {
199         temp = days;
200         while(temp >= 365)  
201         {
202             if(Is_LeapYear(years))              //是闰年
203             {
204                 if(temp >= 366)
205                     temp -= 366;    //闰年的天数
206                 else
207                     break;
208             }else{
209                 temp -= 365;
210             }          
211             years++;
212         }
213          
214         timer.year = years;           //得到年份
215  
216         while(days >= 28)
217         {
218             if(Is_LeapYear(years) && months ==1)       //判断是否为闰年的第二月
219             {
220                 if(temp >= 29)
221                     temp -= 29;
222                 else
223                     break;
224             }else{
225                 if(temp >= Days_Table[months])      
226                     temp -= Days_Table[months];
227                 else
228                     break;
229             }
230  
231             months++;  
232         }
233  
234         timer.month = months+1;             //得到月数
235         timer.date  = temp+1;               //得到日期
236     }
237  
238     temp = secs % 86400;                    //得到剩余秒数
239     timer.hour = temp/3600;                 //得到小时
240     timer.minute = (temp%3600)/60;         
241     timer.second = (temp%3600)%60;
242     timer.week = Rtc_DAY_Get(timer.year,timer.month,timer.date);
243  
244                  
245 }
246  
247 //判断当前为星期几                 
248  
249 u8 Rtc_DAY_Get(u16 year,u8 month,u8 day)
250 {  
251     u16 temp;
252     u8 yearH,yearL;
253      
254     yearH = year/100;  
255     yearL = year%100;
256  
257     // 如果为21世纪,年份数加100 
258     if( yearH > 19 ) yearL += 100;
259  
260     // 所过闰年数只算1900年之后的 
261  
262     temp = yearL+yearL/4;
263     temp = temp%7;
264     temp = temp + day + _Week[month-1];
265  
266     if( yearL%4 == 0 && month < 3 ) temp--;
267  
268     return(temp%7);
269 }
270  
271 //设定闹钟时间
272  
273 void Rtc_ALARM_Set(u16 year,u8 month,u8 date,u8 hour,u8 minute, u8 second)
274 {
275  
276         u32 sec;   
277  
278         sec = Date_TO_Sec(year,month,date,hour,minute,second);
279  
280  
281         RTC-> CRL |= 1<<4;                             //允许配置
282  
283         //while(!(RTC->CRL&(1<<5)));                       //RTOFF为1 才可以写入ALRL和ALRH寄存器
284          
285         RTC-> ALRL = sec&0xffff;                     //取低16位
286         RTC-> ALRH = sec>>16;                          //取高16位
287      
288         RTC-> CRL &= ~(1<<4);                          //开始RTC寄存器更新
289      
290         while(!(RTC->CRL&(1<<5)));                     //等待RTC寄存器操作完成
291  
292 }
Library/inc/rtc.h
01 #include    
02  
03 typedef struct
04 {
05     u8 hour;
06     u8 minute;
07     u8 second;
08  
09     u16 year;
10     u8  month;
11     u8  date;
12     u8  week;
13 }tm;
14  
15 extern tm timer;
16  
17 void Rtc_Init(void);
18 void Rtc_TIME_Set(u16 year,u8 month,u8 date,u8 hour,u8 minute, u8 second);
19 u8 Is_LeapYear(u16 year);
20 u32  Date_TO_Sec(u16 year,u8 month,u8 date,u8 hour,u8 minute, u8 second);
21 void Rtc_TIME_AutoSet(void);
22 void Rtc_Get(void);
23 void Rtc_ALARM_Set(u16 year,u8 month,u8 date,u8 hour,u8 minute, u8 second);
24 u8 Rtc_DAY_Get(u16 year,u8 month,u8 day);
这里用到了MDK的两个关键字 __DATE__ 和 __TIME__获得当前编译的日期和时间,详见代码注释
 
库函数操作
 
ANSI C语言所提供的time.h的头文件中关于unix时间戳是从1900年开始的,和直接操作寄存器不同,所以如果unix时间戳中读出年份为100,则正确年份为1900+100=2000
 
代码如下:
 
main.c
001 #include "stm32f10x.h"
002 #include "stdio.h"
003 #include "time.h"
004  
005 #define  PRINTF_ON  1
006  
007 void RCC_Configuration(void);
008 void GPIO_Configuration(void);
009 void NVIC_Configuration(void);
010 void USART_Configuration(void);
011 void RTC_Configuration(void);
012  
013 void TimeShow(void);
014  
015 void SetAlarm(struct tm t);
016 void SetCalendarTime(struct tm t);
017 void SetUnixTime(time_t);
018 struct tm  ConvUnixToCalendar(time_t t);
019 u32 ConvCalendarToUnix(struct tm t);
020 u32 GetUnixTime(void);
021  
022  
023 vu32  Display;
024  
025 struct tm CurrentTime = {0,30,10,11,4,2011};
026 struct tm AlarmTime = {5,30,10,11,4,2011};
027  
028  
029 int main(void)
030 {
031     RCC_Configuration();
032     GPIO_Configuration();
033     NVIC_Configuration();
034     USART_Configuration();
035     RTC_Configuration();
036      
037     SetCalendarTime(CurrentTime);
038     SetAlarm(AlarmTime);
039     while(1){ TimeShow(); }
040 }
041  
042 void TimeShow(void)
043 {
044     u32 Time = 0;
045     if(Display)
046     {
047         Time = GetUnixTime();
048         CurrentTime = ConvUnixToCalendar(Time);
049  
050         printf("\r\n Time : %d - %d - %d,%d : %d : %d \r\n",
051             CurrentTime.tm_year,
052             CurrentTime.tm_mon,
053             CurrentTime.tm_mday,
054             CurrentTime.tm_hour,
055             CurrentTime.tm_min,
056             CurrentTime.tm_sec);
057         Display = 0;
058     }
059 }
060  
061 void SetCalendarTime(struct tm t)
062 {
063     SetUnixTime(ConvCalendarToUnix(t));
064 }
065  
066 void SetUnixTime(time_t t)
067 {
068     RTC_WaitForLastTask();
069     RTC_SetCounter((u32)t);
070     RTC_WaitForLastTask();
071 }
072  
073 void SetAlarm(struct tm t)
074 {
075     RTC_WaitForLastTask();
076     RTC_SetAlarm(ConvCalendarToUnix(t));
077     RTC_WaitForLastTask();
078 }
079  
080 u32 GetUnixTime(void)
081 {
082     return (u32)RTC_GetCounter();
083 }
084  
085 u32 ConvCalendarToUnix(struct tm t)
086 {
087     t.tm_year -=1900;
088     return mktime(&t);
089 }
090  
091 struct tm  ConvUnixToCalendar(time_t t)
092 {
093     struct tm *t_tm;
094     t_tm = localtime(&t);
095     t_tm->tm_year += 1900;
096     return *t_tm;
097 }
098  
099  
100 void GPIO_Configuration(void)
101 {
102     GPIO_InitTypeDef GPIO_InitStructure;                                                                                                                                                                                                                                                   
103     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
104     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
105     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        
106     GPIO_Init(GPIOA , &GPIO_InitStructure);
107  
108     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
109     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;          
110     GPIO_Init(GPIOA , &GPIO_InitStructure);
111 }
112  
113 void RTC_Configuration(void)
114 {
115     PWR_BackupAccessCmd(ENABLE);
116     BKP_DeInit();
117     RCC_LSEConfig(RCC_LSE_ON);
118     while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
119     RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
120     RCC_RTCCLKCmd(ENABLE);
121  
122     RTC_WaitForSynchro();
123     RTC_WaitForLastTask();
124  
125     RTC_ITConfig(RTC_IT_SEC|RTC_IT_ALR,ENABLE);
126     RTC_WaitForLastTask();
127  
128     RTC_SetPrescaler(32767);
129     RTC_WaitForLastTask();
130 }
131  
132  
133 void RCC_Configuration(void)
134 {
135     /* 定义枚举类型变量 HSEStartUpStatus */
136     ErrorStatus HSEStartUpStatus;
137  
138     /* 复位系统时钟设置*/
139     RCC_DeInit();
140     /* 开启HSE*/
141     RCC_HSEConfig(RCC_HSE_ON);
142     /* 等待HSE起振并稳定*/
143     HSEStartUpStatus = RCC_WaitForHSEStartUp();
144     /* 判断HSE起是否振成功,是则进入if()内部 */
145     if(HSEStartUpStatus == SUCCESS)
146     {
147         /* 选择HCLK(AHB)时钟源为SYSCLK 1分频 */
148         RCC_HCLKConfig(RCC_SYSCLK_Div1);
149         /* 选择PCLK2时钟源为 HCLK(AHB) 1分频 */
150         RCC_PCLK2Config(RCC_HCLK_Div1);
151         /* 选择PCLK1时钟源为 HCLK(AHB) 2分频 */
152         RCC_PCLK1Config(RCC_HCLK_Div2);
153         /* 设置FLASH延时周期数为2 */
154         FLASH_SetLatency(FLASH_Latency_2);
155         /* 使能FLASH预取缓存 */
156         FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
157         /* 选择锁相环(PLL)时钟源为HSE 1分频,倍频数为9,则PLL输出频率为 8MHz * 9 = 72MHz */
158         RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
159         /* 使能PLL */
160         RCC_PLLCmd(ENABLE);
161         /* 等待PLL输出稳定 */
162         while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
163         /* 选择SYSCLK时钟源为PLL */
164         RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
165         /* 等待PLL成为SYSCLK时钟源 */
166         while(RCC_GetSYSCLKSource() != 0x08);
167     }
168     /* 打开APB2总线上的GPIOA时钟*/
169     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE);
170  
171     RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP, ENABLE);
172          
173 }
174  
175   
176 void USART_Configuration(void)
177 {
178     USART_InitTypeDef USART_InitStructure;
179     USART_ClockInitTypeDef USART_ClockInitStructure;
180  
181     USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
182     USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
183     USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;                                                                                                                                                     
184     USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
185     USART_ClockInit(USART1 , &USART_ClockInitStructure);
186  
187     USART_InitStructure.USART_BaudRate = 9600;
188     USART_InitStructure.USART_WordLength = USART_WordLength_8b;
189     USART_InitStructure.USART_StopBits = USART_StopBits_1;
190     USART_InitStructure.USART_Parity = USART_Parity_No;
191     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
192     USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
193     USART_Init(USART1,&USART_InitStructure);
194  
195     USART_Cmd(USART1,ENABLE);
196 }
197  
198  
199 void NVIC_Configuration(void)
200 {
201     NVIC_InitTypeDef NVIC_InitStructure;
202  
203     NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
204     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
205     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
206     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
207     NVIC_Init(&NVIC_InitStructure);
208  
209 }
210  
211  
212  
213  
214  
215 #if  PRINTF_ON
216  
217 int fputc(int ch,FILE *f)
218 {
219     USART_SendData(USART1,(u8) ch);
220     while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
221     return ch;
222 }
223  
224 #endif
stm32f10x_it.c:


01 #include "stm32f10x_it.h"
02  
03 #include "stdio.h"
04  
05 extern vu32 Display;
06  
07 void RTC_IRQHandler(void)
08 {
09     if(RTC_GetFlagStatus(RTC_FLAG_ALR) != RESET){
10         printf("\r\nIt's time to do sth.\r\n");    
11     }else{
12         Display =1 ;
13      
14     }
15  
16     RTC_ClearITPendingBit(RTC_IT_ALR|RTC_IT_SEC);
17 }
阅读(2646) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~