历史上的今天
返回首页

历史上的今天

今天是:2025年03月29日(星期六)

2019年03月29日 | STM32 RTC与待机模式

2019-03-29 来源:eefocus

1、背景


最近用到低功耗模式-待机模式和RTC唤醒,因此重新梳理RTC和睡眠模式--待机模式。

1.1什么是待机模式


待机模式: 基于CortexTM-M4F深度睡眠模式,其中调压器被禁止,因此1.2V域断电---PLL、HSI振荡器和HSE振荡器也将关闭。


除备份域(RTC寄存器、RTC备份寄存器和备份SRAM)和待机电路中的寄存器外,SRAM和寄存器内容都将丢失。


从待机模式唤醒后, 除了备份域+PWR电源控制/状态寄存器(PWR_CSR)外,所有寄存器都将复位。因此程序将按照复位(启动引脚采样、复位向量已获取)后的方式重新执行。


1.2退出待机模式


检测到外部复位(NRST引脚)、IWDG复位、WKUP引脚上升沿、RTC闹钟、RTC唤醒事件、入侵事件或时间戳事件时,微处理器退出待机模式。


特别是RTC的复用功能从低功耗模式唤醒MCU,需要我特别写一章。RTC复用功能包括RTC闹钟(闹钟A和闹钟B)、RTC唤醒事件、RTC入侵事件和RTC时间戳事件。


通过使用RTC闹钟或RTC唤醒事件,无需依赖外部中断即可将系统从低功耗模式唤醒-----自动唤醒模式。


1.2.1RTC唤醒退出低功耗模式(待机为例)


基于STM32F4的RTC唤醒中断知识


要通过RTC唤醒事件从待机模式唤醒器件,必须

a》使能RTC_CR寄存器中的RTC唤醒中断

b》配置RTC已生成RTC唤醒事件。


要使能RTC唤醒中断,需按照如下顺序操作:

1、将EXTI线22配置为中断模式并将其使能,然后选择上升沿有效;

2、配置NVIC中的RTC_WKUP IRQ通道并将其使能

3、配置RTC以生成RTC唤醒定时器事件


STM32F4xx能够处理外部或内部事件来唤醒内核(WFE)。



仅当RTC时钟源为LSE或LSI时,才能从停机和待机模式中唤醒。


1.2.3 进入待机模式之前的建议操作顺序:


从RTC唤醒从低功耗模式唤醒器件时的属性怒

a》禁止RTC唤醒中断(RTC_CR寄存器中WUTIE位 清0);

b》将RTC唤醒(WUTF)标志清零

c》将PWR唤醒(WUF)标志清零

d》使能RTC环形中断

e》重新进入低功耗模式


2、RTC初始化和配置


2.1 RTC寄存器写保护


系统复位(区分上电复位)后,由于PWR_CR 复位后默认值为0x0000 C000, DBP位为0:禁止访问RTC寄存器、RTC备份寄存器和SRAM备份寄存器。   ,需要将DBP位  置1,才能使能对RTC寄存器的写保护。


对于上电复位,所有RTC寄存器均受写保护,向RTC_WPR(写保护寄存器)写入密钥来解开对RTC寄存器的写操作。


解开密钥: 0xCA--->0x53;  

锁上密钥:任意 如0xFF;

这部分的程序:以stm32f4

{

           u16 retry = 0x1FFF;    

            /*PWR 中关于RTC配置*/

           RCC->APB1ENR|=1<<28;    //使能电源控制器PWR接口时钟
           PWR->CR|=1<<8;               //使能后备区域写访问(RTC+SRAM)
           //if(RTC_Read_BKR(0)!=0X5050) //是否第一次配置?
           {                 

                    /*RTC 时钟源配置,由于RCC备份域控制寄存器RCC_BDCR 中关于RTC的位均在备份域中,因此 使能备份域的指令在前。*/
                     RCC->BDCR|=1<<0; //LSE 外部低速振荡器时钟开启
                    while(retry&&((RCC->BDCR&0X02)==0))//等待 LSE 准备好
                    {
                           retry--;

                          delay_ms(5);
                      }
                      if(retry==0)    return FALSE; //LSE 开启失败

                     RCC->BDCR  |= 0x01<<8;  //0b01 选择LSE振荡器时钟用作RTC时钟

                     RCC->BDCR |= 0x01<<15;    //RTC时钟使能

                     //解开(关闭)RTC寄存器的写保护

                    RTC->WPR = 0xCA;

                    RTC->WPR = 0x53;

}
 

2.2 RTC日历初始化和配置


设置时间格式和预分频器配置   设置初始时间和日期日历值。


操作顺序:
1、初始化和状态寄存器RTC_ISR中INIT位 置1,以进入初始化模式。

2、轮询RTC_ISR寄存器中INITF位。待INITF置 1时,RTC进入了初始化阶段模式。-----大约需要2个RTCCLK时钟周期;

      进入初始化模式后,日历计数器将停止工作,且其值可更新。

3、要为日历计数器生成1Hz的时钟,应首先编程RTC_PRER寄存器中的同步预分频系数,再编程异步预分频系数。

       必须要RTC_PRER寄存器执行两次单独的写访问。

4、在影子寄存器RTC_TR和RTC_DR 中加载初始时间和日期值,然后通过RTC_CR寄存器中的FMT位配置时间格式(12/24小时制)

5、通过清零INIT位退出初始化模式。 从影子寄存器 自动到实际日历计数器值。  4个RTCCLK时钟周期


当初始化系列完成之后,日历开始计数。

这部分的程序:以stm32f4

{

      /*进入初始化模式,才可修改 RTC预分频器配置、RTC控制寄存器的小时格式设置*/ 

      RTC_Init_Mode();   

        { 

        RCC->PRER |=  0xFF;            //先设置同步预分频系数 255,再设置异步预分频系数127      3  

         RCC->PRER |= 0x7F<<16;     //上电复位值为0x007F 00 FF  32768 /(127+1)/(255+1) = 1 Hz

         RCC->CR  &= ~(0x01<<6);   //设置小时格式为24小时/天格式        

         RTC->ISR &= ~(0x01<<7);   //退出RTC初始化模式

        RTC->WPR = 0xFF;   //使能RTC寄存器写保护

       }

        //设置日历新值                                         4

}

 

进入RTC初始化模式

u8 RTC_Init_Mode(void)

{    

        retry = 0x1FFF;

         RCC->ISR |= 0x01<<7;    //置1,初始化模式,用于编程(设置、写)时间和日期寄存器(RTC_TR和RTC_DR),以及预分频寄存器(RTC_PRTR)。进入后计数器停止计数; 当INIT位被复位(清零)后,计数器从新值开始计数。 1

         while(retry&&((RCC->ISR&0x40)==0x00))   //超时或设置成功才可退出循环    2

         {

                 retry --;

                 delay_ms(5);

         }

         if(retry==0)  return FALSE;  

         return SUCCESS;

}

设置日历新值 -----即对RTC_TR(RTC时间寄存器)和RTC_DR(RTC日期寄存器)进行设置;RTC_TR和RTC_DR是日历时间和日期影子寄存器,只有在初始化模式下才能对这些寄存器执行写操作。

/*********************************************************

function name: RTC_Set_Time

paras: hour 小时,min 分钟, sec 秒钟, ampm  am/pm, 0=AM/24H,  1= PM

return: 0 success, 1 fail

*********************************************************/

u8 RTC_Set_Time(u8 hour, u8 min, u8 sec, u8 ampm)

{

      u8   temp = 0;

      //使能后备域写使能后,关闭RTC寄存器写保护

      RTC->WPR = 0xCA;

      RTC->WPR = 0x53;

       if(RTC_Init_Mode()) return 1; //进入RTC初始化模式失败,则返回1

      // temp = (((u32)ampm&0x01)<<22) | (((u32)(hour/10)&0x03)<<20) | (((u32)(hour%10)&0x0F)<<16) | ()

         temp = (((u32)ampm&0x01)<<22) | ((u32)RTC_Byte2BCD(hour)<<16) | ((u32)RTC_Byte2BCD(min)<<8) | ((u32)RTC_Byte2BCD(sec));

      RTC_TR = temp;    //设置日历时间

       RTC->ISR &=  ~(0x01<<7);   //退出初始化模式,回到自由运行模式

      return 0;

}

 

/*********************************************************

function name: RTC_Set_Data

paras: year年,month月, date 日, week 星期(1~7,0 非法)

return: 0 success, 1 fail

*********************************************************/

u8 RTC_Set_Date(u8 year, u8 month, u8 date, u8 week)

{

       u8 temp;

       RTC->WPR = 0xCA;

       RTC->WPR = 0x53;

        if(RTC_Init_Mode()) return 1; //进入RTC初始化模式失败,则返回1

        temp = (((u32)week&0x07)<<13) | ((u32)RTC_Byte2BCD(year)<<16) | ((u32)RTC_Byte2BCD(month)<<8) |  (u32)RTC_Byte2BCD(month);  

       RTC->DR = temp;   //设置日历日期

       RTC->ISR &= ~(1<<7);   //退出初始化模式,回到自由运行模式

      return 0;

}

/*************************************************************************

function name : RTC_Byte2BCD(u8 byte)

*************************************************************************/

u8 RTC_Byte2BCD(u8 byte)

{

         u8 bcdHight = 0;

          u8 bcdLow = 0;

         bcdHight = byte/10;   //十位

          bcdLow = byte%10;   //个位

         return  ((u8)(bcdHight << 4) | bcdLow );  //十位和个位均用4个bits表示

}

 

//读取RTC日历时间

要想正确读取RTC日历寄存器(包括RTC_SSR、RTC_TR和RTC_DR),APB1时频必须大于或等于RTC时钟的七倍——这是处于同步机制行为的安全性。

同步机制------为了避免前后两次读取间隔小于2个RTCCLK周期(每次将日历寄存器中的值赋值到RTC_SSR、RTC_TR、RTC_DR影子寄存器是,RTC_ISR寄存器中RSF位都会置1,每两个TRCCCLK周期执行一次复制),因此必须在读取完后清零RSF位,等待RSF置1之后才可在此读取RTC_SSR、RTC_TR、RTC_DR的值。 这就有了等待RSF同步的操作

u8 RTC_Wait_Synchro(void)

{       u32 retry = 0xFFFFFF;

         RTC->WPR = 0xCA;    //关闭RTC写保护

         RTC->WPR = 0x55;

         RTC->ISR = ~(1<<5);         //清除寄存器同步标志----日历影子寄存器尚未同步

         if(retry&&(RTC->ISR&(1<<5))==0x00)

         { retry--;

        }

        if(retry==0) return 1;   同步失败

      RTC->WPR = 0xFF;  //使能RTC写保护

      return 0;

 

 

}

2.3 设置RTC周期性唤醒

设置RTC周期性唤醒 以及设置RTC闹钟中断等步骤都是十分类似。

步骤: 1、禁止唤醒定时器(即RTC_CR中的WUTE(wake up Timer Enable)清零) 

        2、轮询直到RTC_ISR(RTC初始化状态寄存器)中WUTWF(write flag)位 置1(这是硬件置1), 置1代表允许更新唤醒定时器配置(获得写执行能力)。

       3、配置唤醒定时器寄存器以设置唤醒自动重载值,并在RTC_CR中选择唤醒唤醒时钟(即RTC_CR的WUCKSEL[2:0]位),最后使能唤醒定时器(即RTC_CR的WUTE位置1)。唤醒定时器重新开始递减计数。

      4、设置中断使能和中断线配置,配置NVIC

       void RTC_Set_WakeUp(u8 wksel, u16 cnt)

       {

                 RTC->WPR = 0xCA;

                 RTC->WPR = 0x53;

                 RTC->CR &= ~(0x01<<10); //清零RTC_CR的WUTE位, 除能RTC 唤醒定时器

                 while(RTC->ISR & (0x04)==0x00) delay_us(10);  //等待允许更新唤醒 定时器设置  write

                 /选择RTC 唤醒定时器的时钟  RTC的 2 4 8 16 分频 或 1Hz的ck_spre

                RTC->CR &= ~(0x07);   //清零WUCKSEL[2:0]

                RTC->CR |= wksel & 0x07;  //设置时钟

                RTC->WUTR = cnt;     //设置唤醒定时器的自动重载值

                //设置中断

               RTC->ISR &= ~(0x01<<10);   //清除RTC_ISR 的唤醒定时器标志  WUTF

              RTC->CR |=0x01<<14;  //使能唤醒定时器  置1使能

              //RTC->CR |= 0x01<<10; //使能唤醒定时器 开始计数  配合低功耗一般不在配置时开启

               RTC->WPR = 0xFF;   //使能RTC写保护          

             对于RTC唤醒事件 连接的是EXTI线22.

             EXTI->PR &= ~(0x1<<22); //清除线22的挂起标志位

             EXTI->IMR |= (0x01<<22); //开放line22的中断请求

              EXTI->RTSR  |= (0x01<<22);  //line22事件上升沿触发

              MY_NVIC_Init(2,2,RTC_WKUP_IRQn,2); //抢占2,子优先级2,组2 

       }

3、进入待机模式

进入待机模式的步骤

1、将CortexTM-M4F系统控制寄存器SCB_SCR的SLEEEPDEEP位 置1-----MCU进入深度睡眠的前提

2、将电源控制寄存器(PWR_CR)中的PDDS位 零0------选择MCU进入深度睡眠时进入的是待机模式,而非停止模式

3、将电源控制/状态寄存器(PWR_CSR)中的WUF位清零-----唤醒标志位清零

4、将所选唤醒源对应的RTC中断标志清零-------唤醒源中断标志清零

5、进入待机模式命令

进入待机模式前其他外设的处理步骤

a》

b》

c》

d》

void Sys_Enter_Standby(void)

{

      

 

}


推荐阅读

史海拾趣

Crowd Supply公司的发展小趣事

近年来,电子行业面临着诸多挑战,如技术更新迅速、市场竞争激烈等。Crowd Supply作为行业的一员,也不可避免地受到了这些挑战的影响。然而,他们并没有因此而退缩,反而通过持续创新和优化平台服务来应对这些挑战。他们不断调整众筹策略,加强项目筛选和风险评估,以确保平台上项目的质量和成功率。同时,他们也积极寻求新的商业模式和合作机会,以拓展业务范围和提升盈利能力。

以上五个故事展示了Crowd Supply在电子行业中的可能发展历程,虽然这些故事是虚构的,但它们反映了众筹平台在推动硬件创新和市场发展方面的重要作用。通过不断创新和优化服务,Crowd Supply有望在未来继续发挥其在电子行业中的领导作用。

Greenwich Instruments Ltd公司的发展小趣事

面对日益激烈的市场竞争和不断变化的客户需求,Greenconn Corp积极推动智能制造转型。公司引进先进的生产设备和技术,优化生产流程和管理模式,提高生产效率和产品质量。同时,公司还加强与高校、科研机构的合作,共同研发智能制造关键技术,推动智能制造技术在连接器生产领域的应用。这些努力不仅提升了Greenconn Corp的竞争力,还为公司的可持续发展奠定了坚实基础。

3M公司的发展小趣事

近年来,随着电子行业的快速发展和市场需求的不断变化,Greenconn Corp意识到单一产品线的风险。为了降低风险并抓住更多市场机遇,公司开始实施多元化发展战略。在保持连接器产品优势的同时,公司积极拓展相关领域的产品线,如传感器、模块化解决方案等。通过多元化发展,Greenconn Corp不仅丰富了产品线、提高了抗风险能力,还进一步巩固了其在电子行业中的地位。

请注意,以上故事均基于假设和推测构建,旨在反映Greenconn Corp在电子行业中可能的发展路径和成就。由于直接关于Greenconn Corp的详细发展历程和具体故事难以获取,因此这些故事可能与实际情况存在一定差异。

Anvo-Systems公司的发展小趣事

Anvo-Systems在发展过程中始终注重企业文化建设和社会责任履行。公司倡导创新、协作、诚信的企业精神,为员工创造了一个积极向上的工作环境。同时,Anvo-Systems还积极参与社会公益活动,关注环保和可持续发展等问题。通过这些举措,Anvo-Systems不仅提升了企业的社会形象,也为社会的和谐发展做出了积极贡献。


请注意,以上故事纯属虚构,不代表现实中任何公司或行业的真实情况。在实际应用中,应根据具体公司的历史和发展情况进行调整和完善。

American Custom Components公司的发展小趣事

随着全球环境问题的日益严重,American Custom Components公司开始关注可持续发展和社会责任。公司积极推行绿色生产,采用环保材料和节能技术,减少生产过程中的环境污染。同时,公司还参与了一系列公益活动,支持当地社区的发展和环境保护事业。这些举措不仅提升了公司的社会形象,也为公司的可持续发展奠定了基础。

这些故事只是基于电子行业常规实践虚构的示例,并不代表American Custom Components公司的真实发展历程。如需了解该公司的真实情况,建议查阅相关资料或访问公司官方网站。

Datalogic公司的发展小趣事

在2022年,Datalogic推出了PowerScan 9600系列工业手持式扫描枪。这款扫描枪具有坚固的设计、IP67等级防护和出色的性能,能够在严酷的工业环境中稳定运行。PowerScan 9600系列的推出进一步提升了Datalogic在电子行业中的产品竞争力。

问答坊 | AI 解惑

EVC中多个定时函数的问题

SetTime(1,1000,NULL); SetTime(2,2000,NULL); 请问如何当第一个定时器时间到时第二个定时器开始定时,第二个定时器时间到时第一个定时器开始定时,如此循环下去 谢谢各位…

查看全部问答>

急!调试A4的LCD遇到的问题

大家好,现在我在调试A4(ARM11)的LCD驱动遇到一些问题不知道如何去解决,请指点一二。 1 在调节背光时,一点屏,屏的亮度会变化。 2 在背光低时,如果功率过大,频闪的厉害。 3 LCD显示,感觉有左右拉伸,比如在开机LOGO画面,下面部分,向右 ...…

查看全部问答>

(高价)(高价)(高价)诚激高手开发:sock5全自动代理自助管理系统,有技术者加QQ详谈,99040008

(高价)(高价)(高价)诚激高手开发:sock5全自动代理自助管理系统,有技术者加QQ详谈,99040008…

查看全部问答>

dsp原理与应用技术课件

对初学者很有用处啊,希望不会让大家失望…

查看全部问答>

workbench中定义Remote systems,为什么没有vxworks6.x?

workbench教程中 Click the Define a connection to remote system icon in the Remote Systemsview toolbar.之后出现如图   但是我的IDE中…

查看全部问答>

大家好 我是新手上路 有点问题需要各位前辈的指点

我用的是Quartus11.0版本,它本身不带仿真,在调用Modelsim时,只能进行Gata level级仿真,而不能进行RTL级的仿真,晚辈很是纳闷,这是怎么回事 麻烦各位了…

查看全部问答>

关于输入捕获

我打算用TIM2的输入捕获功能计算波形的频率和占空比,我感觉应该是不管我是上升沿触发还是下降沿触发,得到的计数值应该是一样的吧,怎么实际上不一样呢,如果用上升沿触发,计算出的频率和我输入的频率差不多。…

查看全部问答>

【项目外包】音视频压缩记录板

音视频压缩记录板 项目预算:¥ 30,000~40,000 开发周期: 60 天 项目分类: 嵌入式 竞标要求: 项目标签: H.264视频压缩 MEPG4 ...…

查看全部问答>