历史上的今天
今天是:2025年02月07日(星期五)
2020年02月07日 | 基于STM32单片机秒中断源和闹钟中断源的解决方案
2020-02-07 来源:elecfans
“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等相关代码参照STM32 直接操作寄存器开发环境配置)
User/main.c
#include#include“system.h”#include“usart.h”#include“rtc.h”#defineLED1PAout(4)#defineLED2PAout(5)voidGpio_Init(void);externconstu8*Week_Table[7];intmain(void){Rcc_Init(9);//系统时钟设置Usart1_Init(72,9600);Nvic_Init(0,0,RTC_IRQChannel,0);//设置中断Gpio_Init();Rtc_Init();//Rtc_TIME_AutoSet();//将当前编译时间作为RTC开始时间Rtc_TIME_Set(2012,7,7,20,50,0);//设定开始时间参数说明:年,月,日,时,分,秒Rtc_ALARM_Set(2012,7,7,20,50,30);//设定闹钟事件时间LED1=1;while(1);}voidGpio_Init(void){RCC-》APB2ENR|=1《《2;//使能PORTA时钟GPIOA-》CRL&=0x0000FFFF;//PA0~3设置为浮空输入,PA4~7设置为推挽输出GPIOA-》CRL|=0x33334444;//USART1串口I/O设置GPIOA-》CRH&=0xFFFFF00F;//设置USART1的Tx(PA.9)为第二功能推挽,50MHz;Rx(PA.10)为浮空输入GPIOA-》CRH|=0x000008B0;}
User/stm32f103x_it.c
#include“stm32f10x_it.h”#include“system.h”#include“stdio.h”#include“rtc.h”#defineLED1PAout(4)#defineLED2PAout(5)#defineLED3PAout(6)#defineLED4PAout(7)//externvoidWwdg_Feed(void);//externu16Read_Bkp(u8reg);externvoidRtc_Get(void);externconstu8*Week_Table[7];voidRTC_IRQHandler(void){if(RTC-》CRL&0x0001)//秒钟中断{LED4=!LED4;Rtc_Get();printf(“rnTime:%d-%d-%d,%d:%d:%d,Todayis%srn”,timer.year,timer.month,timer.date,timer.hour,timer.minute,timer.second,Week_Table[timer.week]);}if(RTC-》CRL&0x0002)//闹钟中断{LED3=1;printf(“rnIt‘stimetodosth.rn”);RTC-》CRL&=~(0x0002);//清除闹钟中断}RTC-》CRL&=0x0FFA;//清除溢出,秒钟中断while(!(RTC-》CRL&(1《《5)));//等待RTC寄存器操作完成}
Library/src/rtc.c
#include#include“rtc.h”#include“stdio.h”tmtimer;//定义时钟结构体,主函数直接可以调用此结构体读出时间//平年
史海拾趣
|
HOHO 申请到了下面的开发板 有图和大家分享:(手机拍摄,可能不清楚) 申请表发送目标邮箱 market@prochip.com.cnHOHO就是发到这个邮箱申请的,希望大家也能成功 申请地址为:大家可以去它的官方网站看看去 如果 ...… 查看全部问答> |
|
1、多级放大器的级间关系:在多级放大器中,后级电路相当于前级的负载,前级负载是后级放大器的输入电阻;前级相当后级的信号源,后级信号源内阻为前级的输出电阻。2、n级放大器的动态指标a、总电压放大倍数 :可见, n级放大器的总电压放大倍数 ...… 查看全部问答> |
|
本帖最后由 paulhyde 于 2014-9-15 04:14 编辑 竞赛,单片机(处理器)怎么选取?是带队老师建议?是芯片厂商推荐?还是自己一个个测试? 当然,2013年全国大学生电子设计竞赛竞赛题目及要求中有以下说明: 竞赛题目包括 ...… 查看全部问答> |




