历史上的今天
返回首页

历史上的今天

今天是:2025年03月04日(星期二)

正在发生

2020年03月04日 | 【菜鸟入门】stm32 之 实时时钟

2020-03-04 来源:eefocus

经过这么10天的瞎搞,我的库已经初具规模了,于是,不用每次都把所有的文件copy过去,直接在Option里面把path给加上就ok了。

RTC的时钟配置,RTC的时间寄存器是2个32位的寄存器,无非就是一个计数器,大概可以这样理解吧,我们先看看时钟吧

RTC的时钟可以从这3路来,我们需要PTCSEL寄存器来进行设置,

上面这个图是摘自李想老师的课件里面的,我觉得这个是做的相对好的!


位了保证RTC正常工作,我们需要在系统断电时,RTC不受影响,当然我们一般都需要接一个Battery,作为rtc的后备电源,这里设计到电源管理,我们先来看看电源管理里面关于rtc的

只要我们把第八位置1我们就可以对其进行正常供电,我们还发现,他也可以给后备寄存器供电,这个后备寄存器是是个什么东东呢?


有兴趣的可以研究研究备份寄存器(BKP),他的主要功能是侵入检查和RTC校准,他既然跟RTC有关系,我们就要好好看看他了;


复位和时钟控制里面有个备份域控制寄存器RCC_BDCR


注意:备份域控制寄存器中(RCC_BDCR)的LSEON、LSEBYP、RTCSEL和RTCEN位处于备份域。因此,这些位在复位后处于写保护状态,只有在电源控制寄存器(PWR_CR)中的DBP位置’1’后才能对这些位进行改动。进一步信息请参考5.1节。这些位只能由备份域复位清除(见6.1.3节)。任何内部或外部复位都不会影响这些位。

位31:17  保留,始终读为0。

BDRST:备份域软件复位(Backup domain software reset)  位16 

由软件置’1’或清’0’ 

0:复位未激活;

1:复位整个备份域。

RTCEN:RTC时钟使能(RTC clock enable)  位15 

由软件置’1’或清’0’ 

0:RTC时钟关闭;

1:RTC时钟开启。

位14:10  保留,始终读为0。

RTCSEL[1:0]:RTC时钟源选择(RTC clock source selection)  位9:8 

由软件设置来选择RTC时钟源。一旦RTC时钟源被选定,直到下次后备域被复位,它不能在被改变。可通过设置BDRST位来清除。

00:无时钟;

01:LSE振荡器作为RTC时钟;

10:LSI振荡器作为RTC时钟;

11:HSE振荡器在128分频后作为RTC时钟。

位7:3  保留,始终读为0。

LSEBYP:外部低速时钟振荡器旁路(External low-speed oscillator bypass)  位2 

在调试模式下由软件置’1’或清’0’来旁路LSE。只有在外部32kHz振荡器关闭时,才能写入该位

0:LSE时钟未被旁路;

1:LSE时钟被旁路。

LSERDY:外部低速LSE就绪(External low-speed oscillator ready)  位1 

由硬件置’1’或清’0’来指示是否外部32kHz振荡器就绪。在LSEON被清零后,该位需要6个外部低速振荡器的周期才被清零。

0:外部32kHz振荡器未就绪;

1:外部32kHz振荡器就绪。

LSEON:外部低速振荡器使能(External low-speed oscillator enable)  位0 

由软件置’1’或清’0’ 

0:外部32kHz振荡器关闭;

1:外部32kHz振荡器开启。


看来这一寄存器果真与RTC有很大的联系,我们需要启用外部32K的振荡器,所以RCC->BDCR |= 1<<0;


设置完了,我们还需要等待32K的时钟就绪,判断bit1的状态!


由于我们选用的32K的LSE作为RTC的时钟,所以上面我们提到的RTCSEL寄存器必须设置为1,设置完后我们就开启32K时钟


RCC->BDCR |= 1<<8;

RCC->BDCR |= 1<<15;


下面正式看RTC的寄存器,先从低位控制寄存器开始CRL

位15:6  保留,被硬件强制为0。

位5 RTOFF:RTC操作关闭(RTC operation OFF)  位5 

RTC模块利用这位来指示对其寄存器进行的最后一次操作的状态,指示操作是否完成。若此位为’0’,则表示无法对任何的RTC寄存器进行写操作。此位为只读位。

0:上一次对RTC寄存器的写操作仍在进行; 

1:上一次对RTC寄存器的写操作已经完成。

位4 CNF:配置标志(Configuration flag)  位4 

此位必须由软件置’1’以进入配置模式,从而允许向RTC_CNT、RTC_ALR或RTC_PRL寄存器

写入数据。只有当此位在被置’1’并重新由软件清’0’后,才会执行写操作。

0:退出配置模式(开始更新RTC寄存器);

1:进入配置模式。


位3 RSF:寄存器同步标志(Registers synchronized flag)

每当RTC_CNT寄存器和RTC_DIV寄存器由软件更新或清’0’时,此位由硬件置’1’。在APB1复位后,或APB1时钟停止后,此位必须由软件清’0’。要进行任何的读操作之前,用户程序必须等待这位被硬件置’1’,以确保RTC_CNT、RTC_ALR或RTC_PRL已经被同步。

0:寄存器尚未被同步;

1:寄存器已经被同步。

位2 OWF:溢出标志(Overflow flag)  位2 

当32位可编程计数器溢出时,此位由硬件置’1’。如果RTC_CRH寄存器中OWIE=1,则产生中断。此位只能由软件清’0’。对此位写’1’是无效的。

0:无溢出;

1:32位可编程计数器溢出。

位1 ALRF:闹钟标志(Alarm flag)  位1 

当32位可编程计数器达到RTC_ALR寄存器所设置的预定值,此位由硬件置’1’。如果RTC_CRH寄存器中ALRIE=1,则产生中断。此位只能由软件清’0’。对此位写’1’是无效的。

0:无闹钟;

1:有闹钟。

位0 SECF:秒标志(Second flag)  位0 

当32位可编程预分频器溢出时,此位由硬件置’1’同时RTC计数器加1。因此,此标志为分辨率可编程的RTC计数器提供一个周期性的信号(通常为1秒)。如果RTC_CRH寄存器中SECIE=1,则产生中断。此位只能由软件清除。对此位写’1’是无效的。

0:秒标志条件不成立;

1:秒标志条件成立。


感觉CRL更像SR,我在想为什么他有点功能不放到SR的里面呢?


好吧,CRL里的功能说的很清楚,看着不会有什么异议,我这里就不解释了,直接掠过,包括CRH。

在RTC计数器寄存器里面和RTC闹钟寄存器里面有这么一段话


RTC核有一个32位可编程的计数器,可通过两个16位的寄存器访问。计数器以预分频器产生的TR_CLK时间基准为参考进行计数。RTC_CNT寄存器用来存放计数器的计数值。他们受

RTC_CR的位RTOFF写保护,仅当RTOFF值为’1’时,允许写操作。在高或低寄存器

(RTC_CNTH或RTC_CNTL)上的写操作,能够直接装载到相应的可编程计数器,并且重新装载

RTC预分频器。当进行读操作时,直接返回计数器内的计数值(系统时间)。


当可编程计数器的值与RTC_ALR中的32位值相等时,即触发一个闹钟事件,并且产生RTC闹钟中断。此寄存器受RTC_CR寄存器里的RTOFF位写保护,仅当RTOFF值为’1’时,允许写操作。


所以我们在配置RTC_CNTx RTC_ALRx 寄存器时,不行把RTOFF寄存器置为1,当写完之后将CNT设为1,即进入配置模式,等待RTOFF配置完成,即RTOFF自动置为0,才完成对CNTx和ALRx两个寄存器进行修改!


为了实现计数的时间间隔,我们要对RTC预分频装载寄存器进行配置


我们需要1s钟计时一次,而我们用的是LSE 32KHz的振荡器,所以我们需要配置的分频器是?

可以看出我们只需让RTC_PRLL = 0x7fff 即 32767即可得到1s的周期


当然我们需要两秒的话那就是0xffff了。


这样,整个就配置完成了,下面附上我的代码,大家可以研究下!


#include

#include "init.h"

#include "usart.h"

 

#define RTC_CF 0x01CD //Define RTC Config Flag

 

int rtc_init()

{

u8 temp = 0;

if(BKP->DR1 != RTC_CF)

{

RCC->APB1ENR |= 1<<28; //Power Interface Clock Enable

RCC->APB1ENR |= 1<<27; //Backup Interface Clock Enable

PWR->CR |= 1<<8; //Disable backup domain write protection

RCC->BDCR |= 1<<16;

RCC->BDCR &= ~(1<<16);

RCC->BDCR |= 1<<0;

while((!(RCC->BDCR&1<<1))&&(temp++)<250)

delay_ms(10);

if(temp>=250)return -1;

RCC->BDCR |= 1<<8;

RCC->BDCR |= 1<<15;

while(!(RTC->CRL & (1<<5)));

while(!(RTC->CRL & (1<<3)));

RTC->CRH |= 1<<0;

while(!(RTC->CRL & (1<<5)));

/* Config Time */

RTC->CRL |= 1<<4;

RTC->PRLH = 0;

RTC->PRLL = 32767;

RTC->CNTH = 0;//Config time

RTC->CNTL = 0;

RTC->ALRH = 0;

RTC->ALRL = 20;

RTC->CRL &= ~(1<<4);

while(!(RTC->CRL & (1<<5)));

BKP->DR1 = RTC_CF;

}

else{

while(!(RTC->CRL & (1<<3)));

RTC->CRH |= 1<<0;

while(!(RTC->CRL & (1<<5)));

}

init_interrupt(2,3,3,2);

rs232_send_int(RTC->CNTL);

return 0;

}

 

void RTC_IRQHandler(void)

{

rs232_send_str("INTERn",6);

if(RTC->CRL & (1<<0))

{

rs232_send_int(RTC->CNTL);

rs232_send_byte('n');

}

if(RTC->CRL & (1<<1))

{

RTC->CRL |= 1<<4;

RTC->CNTL = 1;

RTC->CRL &= ~(1<<4);

rs232_send_str("Time==>n",8);

}

RTC->CRL &= ~(7<<0);//Clear all interrupt flag

while(!(RTC->CRL & (1<<5)));

}

推荐阅读

史海拾趣

CalAmp公司的发展小趣事

CalAmp公司以其卓越的无线产品、设备和方案供应能力,赢得了业界的广泛认可。某年,CalAmp与全球知名的电子分销商Mouser签署了全球分销协议。这一合作使得Mouser能够备有CalAmp公司的一系列产品,如UHF和VHF收发器模块、遥感勘测模块以及适用于不同频带的无线通信装置。这些产品广泛应用于各种无线通信领域,其方便快速集成的特点大大加快了客户产品的上市时间,同时提供了性价比极高的无线解决方案。这一协议的签署不仅进一步巩固了CalAmp在全球无线产品市场的领导地位,也为Mouser带来了更多的业务机会。

EPIC公司的发展小趣事

Epic Games一直关注并支持独立游戏开发者的发展。过去,独立开发者有机会与Epic Store签订协议以获得财务支持或提高游戏的知名度。然而,随着市场环境的变化和金融合约结构的转变,独立开发者面临着越来越多的挑战。尽管如此,Epic Games仍然致力于提供支持和资源来帮助独立开发者克服障碍、实现创新并推动整个游戏行业的进步。通过与独立开发者的紧密合作和持续支持,Epic Games不仅促进了游戏行业的多样性发展,也为自己赢得了广泛的好评和声誉。

艾吉芯(Agertech)公司的发展小趣事

随着公司业务的不断扩展,艾吉芯公司积极寻求与行业内其他企业的战略合作。通过与国内外知名电子企业的合作,艾吉芯成功将其产品应用于更广泛的领域,进一步拓宽了市场渠道。这些合作不仅提升了艾吉芯的品牌影响力,还为其带来了更多的商业机会和发展空间。

ARCOLECTRICSWITCHES公司的发展小趣事

在市场竞争日益激烈的情况下,ARCOLECTRIC SWITCHES公司始终坚持质量至上的原则。公司建立了完善的质量管理体系,从原材料采购到生产加工、产品检验等各个环节都严格把关,确保产品质量符合客户要求。同时,公司不断创新升级产品,推出更加智能化、节能环保的新型开关产品,满足市场不断变化的需求。

Connector City公司的发展小趣事

随着国内市场的饱和,Connector City公司开始寻求海外市场的发展机遇。公司制定了详细的国际化战略,积极开拓海外市场,加强与国外客户的合作与交流。同时,公司还注重本土化运营,根据不同国家和地区的市场需求和文化差异,灵活调整产品设计和营销策略。通过不断拓展海外市场,公司的销售业绩实现了快速增长。

Fagor Electrónica公司的发展小趣事

进入1960年代,Fagor Electrónica迎来了其发展的第一个重大里程碑。1964年,公司成功启动了第一批硅整流器的制造。这一创新不仅提高了产品的性能,还为公司带来了更大的市场份额。硅整流器的推出标志着Fagor Electrónica在电子制造技术上的领先地位,也为其后续的发展奠定了坚实的基础。

问答坊 | AI 解惑

protel dxp注册机

希望对大家有用!!!!!!!!…

查看全部问答>

招聘研发工程师

方向一: DSP6000 开发工程师   职位要求 1.        本科以上学历,电子、自动化等相关专业 2.        熟练掌握 C 语言,熟悉汇编语言。 3.        熟练掌握 DSP 的 ...…

查看全部问答>

Wince 6.0导出SDK成功,新建应用程序却找不到该SDK。

我使用的TQ2440定制WINCE6.0,镜像生成成功,导出SDK都是没有问题,我没有添加MFC的支持,安装SDK也没有问题, 但是在新建的工程里面却找不到,只有一个PLATFORM BUILDER(_TGTCPU),如下图: 后来我发现在OS Design 里面的配置管理器也是这样的 ...…

查看全部问答>

有谁能翻一下下面的术语,拜托了!

reentrant functions 这是什么意思啊!?…

查看全部问答>

借路,谢谢!本人长期从事数字电视及多媒体软件开发,对uClinux,linux系统的内核改造,驱动编写,应用程序等,有精炼的设计开发经验

本人长期从事数字电视及多媒体软件开发,对uClinux,linux系统的内核改造,驱动编写,应用程序等,有精炼的设计开发经验,现有如下服 务业务: 1.嵌入式系统的驱动程序编写。 2.linux系统类内核裁减改造等。 3.媒体类关于图片,电影, ...…

查看全部问答>

(80分请教):armcc 与 arm-elf-gcc的区别?

armcc 与 arm-elf-gcc有什么区别?有能够在Linux环境下使用的armcc吗?如果能提供,可以再加分。 …

查看全部问答>

请问香水城,STM32是否支持通过USB口IAP?

                                 如题.…

查看全部问答>

STM32为何用段时间后不能运行?

我一块板子,使用正常,但使用过一段时间后(1个月左右),就发现不能再运行了,因为没用JTAG,只有在系统刚开始还没配置时钟前就做了段点亮LED的方法,发现,LED既然都不亮,也就是说程序根本就没运行起来。 奇怪的是原来使用正常,现在是能 ...…

查看全部问答>

VHDL仿真时signal的问题

 ELSIF(romout(3 downto 0)=\"0111\")THEN                      dangwei<=temp1;        &nbs ...…

查看全部问答>