单片机
返回首页

STM32待机模式唤醒测试以及独立看门狗测试

2016-12-19 来源:eefocus

环境:

主机:WIN7

开发环境:MDK4.23

MCU:STM32F103CBT6


说明:

在上篇文章中http://blog.csdn.net/jdh99/article/details/7369844,进行了一些STM32待机模式的测试.其中关于如何在再次启动时判断是否是待机模式没有进行测试.另外上篇文章有个问题,闹钟中断在待机模式下是进入不了的.

本文进行了独立看门狗IWDG测试,以及待机模式更详细的测试.

 

STM32中,复位分为3种:

1.系统复位:外部复位,WWDG,IWDG,SW复位,低功耗管理复位.除复位标志寄存器RCC_CSR不被复位,全部都被复位

2.电源复位:上电/掉电复位,从待机模式复位.上电/掉电复位除备份域外寄存器全部复位.待机复位不会复位备份域寄存器以及PWR_CSR寄存器.

3.备份域复位.

寄存器说明:

 

由图可以看出,可以通过WUF位来判断是否由待机模式唤醒.

 

RCC_CSR寄存器:

由图可以看出,RCC_CSR寄存器的IWDGRSTF位可以指示是否发生独立看门狗复位.

因为在看门狗复位时如果系统不处在待机模式,PWR_CSR寄存器也会被复位,所以WUF位也可以指示是否发生独立看门狗复位.

 

源代码:

独立看门狗复位测试:

 

  1. //检查唤醒标志是否设置  

  2. if (PWR_GetFlagStatus(PWR_FLAG_WU) == RESET)  

  3. {  

  4.     //首次启动,或者独立看门狗复位   

  5.     //初始化备份寄存器  

  6.     //BKP_DeInit();  

  7.   

  8.     //RTC功能开启  

  9.     //使能外部晶振  

  10.     RCC_LSEConfig(RCC_LSE_ON);  

  11.     //等待外部晶振准备好  

  12.     while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);  

  13.   

  14.     //设置RTC时钟为外部晶振  

  15.     RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);  

  16.   

  17.     //使能RTC时钟  

  18.     RCC_RTCCLKCmd(ENABLE);  

  19.     //等待RTC_CTL寄存器中的RSF位(寄存器同步标志)被硬件置1  

  20.     RTC_WaitForSynchro();  

  21.     RTC_WaitForLastTask();    

  22.   

  23.     //使能闹钟中断     

  24.     RTC_ITConfig(RTC_IT_ALR, ENABLE);    

  25.     RTC_WaitForLastTask();    

  26.   

  27.     //分频系数为1,即最小时间单位1/2^15 = 30.5us  

  28.     RTC_SetPrescaler(RTC_PRESCALE);    

  29.     RTC_WaitForLastTask();  

  30.   

  31.     //启动独立看门狗  

  32.     IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);                   //访问之前要首先使能寄存器写  

  33.     IWDG_SetPrescaler(IWDG_Prescaler_64);                           //64分频 一个周期1.6ms  

  34.     IWDG_SetReload(1250);                                           //最长12位 [0,4096] 1250*1.6 = 2s  

  35.     IWDG_ReloadCounter();                                           //喂狗  

  36.     //使能开门狗  

  37.     IWDG_Enable();    

  38.       

  39.     if (BKP_ReadBackupRegister(BKP_DR6) == 0xabcd)  

  40.     {  

  41.         GPIO_ResetBits(GPIOA, GPIO_Pin_11) ;  

  42.         BKP_WriteBackupRegister(BKP_DR6,0);  

  43.     }  

  44.     else  

  45.     {  

  46.         GPIO_SetBits(GPIOA,GPIO_Pin_11) ;  

  47.         BKP_WriteBackupRegister(BKP_DR6,0xabcd);  

  48.     }                                             

  49. }  

  50. else  

  51. {     

  52.     //从待机模式中退出    

  53.     //清除唤醒标志  

  54.     RCC_ClearFlag();   

  55.   

  56.     if (BKP_ReadBackupRegister(BKP_DR7) == 0xabcd)  

  57.     {  

  58.         GPIO_ResetBits(GPIOA, GPIO_Pin_8) ;  

  59.         BKP_WriteBackupRegister(BKP_DR7,0);  

  60.     }  

  61.     else  

  62.     {  

  63.         GPIO_SetBits(GPIOA,GPIO_Pin_8) ;  

  64.         BKP_WriteBackupRegister(BKP_DR7,0xabcd);  

  65.     }  

  66. }  

  67. while (1);  


测试结果PA11引脚所连的LED不断闪烁,PA8所连的LED常亮,这说明不断进入看门狗复位.

 

待机模式RTC闹钟唤醒测试:

 

  1. //检查唤醒标志是否设置  

  2. if (PWR_GetFlagStatus(PWR_FLAG_WU) == RESET)  

  3. {  

  4.     //首次启动,或者独立看门狗复位   

  5.     //初始化备份寄存器  

  6.     //BKP_DeInit();  

  7.   

  8.     //RTC功能开启  

  9.     //使能外部晶振  

  10.     RCC_LSEConfig(RCC_LSE_ON);  

  11.     //等待外部晶振准备好  

  12.     while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);  

  13.   

  14.     //设置RTC时钟为外部晶振  

  15.     RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);  

  16.   

  17.     //使能RTC时钟  

  18.     RCC_RTCCLKCmd(ENABLE);  

  19.     //等待RTC_CTL寄存器中的RSF位(寄存器同步标志)被硬件置1  

  20.     RTC_WaitForSynchro();  

  21.     RTC_WaitForLastTask();    

  22.   

  23.     //使能闹钟中断     

  24.     RTC_ITConfig(RTC_IT_ALR, ENABLE);    

  25.     RTC_WaitForLastTask();    

  26.   

  27.     //分频系数为1,即最小时间单位1/2^15 = 30.5us  

  28.     RTC_SetPrescaler(RTC_PRESCALE);    

  29.     RTC_WaitForLastTask();  

  30.   

  31.     //启动独立看门狗  

  32.     IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);                   //访问之前要首先使能寄存器写  

  33.     IWDG_SetPrescaler(IWDG_Prescaler_64);                           //64分频 一个周期1.6ms  

  34.     IWDG_SetReload(1250);                                           //最长12位 [0,4096] 1250*1.6 = 2s  

  35.     IWDG_ReloadCounter();                                           //喂狗  

  36.     //使能开门狗  

  37.     //IWDG_Enable();      

  38.       

  39.     if (BKP_ReadBackupRegister(BKP_DR6) == 0xabcd)  

  40.     {  

  41.         GPIO_ResetBits(GPIOA, GPIO_Pin_11) ;  

  42.         BKP_WriteBackupRegister(BKP_DR6,0);  

  43.     }  

  44.     else  

  45.     {  

  46.         GPIO_SetBits(GPIOA,GPIO_Pin_11) ;  

  47.         BKP_WriteBackupRegister(BKP_DR6,0xabcd);  

  48.     }                                             

  49. }  

  50. else  

  51. {     

  52.     //从待机模式中退出    

  53.     //清除唤醒标志  

  54.     RCC_ClearFlag();   

  55.   

  56.     if (BKP_ReadBackupRegister(BKP_DR7) == 0xabcd)  

  57.     {  

  58.         GPIO_ResetBits(GPIOA, GPIO_Pin_8) ;  

  59.         BKP_WriteBackupRegister(BKP_DR7,0);  

  60.     }  

  61.     else  

  62.     {  

  63.         GPIO_SetBits(GPIOA,GPIO_Pin_8) ;  

  64.         BKP_WriteBackupRegister(BKP_DR7,0xabcd);  

  65.     }  

  66. }  

 

  1. //延时1s  

  2. for (i = 0;i < 100;i++)  

  3. {  

  4.       _delay_ms(10);  

  5. }  

 

  1. //打开待机模式,1s后唤醒  

 

  1. open_standy_mode(30000);  

每次刚上电所有LED会亮,进入待机模式则全部灭.测试结果PA8引脚所连的LED会亮1s进入灭进入待机模式,下次则常灭进入待机模式.PA11所连的LED随着低功耗进入正常亮灭,这说明不断发生闹钟唤醒(看门狗已关).

 

待机模式IWDG唤醒测试:

 

  1. //检查唤醒标志是否设置  

  2. if (PWR_GetFlagStatus(PWR_FLAG_WU) == RESET)  

  3. {  

  4.     //首次启动,或者独立看门狗复位   

  5.     //初始化备份寄存器  

  6.     //BKP_DeInit();  

  7.   

  8.     //RTC功能开启  

  9.     //使能外部晶振  

  10.     RCC_LSEConfig(RCC_LSE_ON);  

  11.     //等待外部晶振准备好  

  12.     while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);  

  13.   

  14.     //设置RTC时钟为外部晶振  

  15.     RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);  

  16.   

  17.     //使能RTC时钟  

  18.     RCC_RTCCLKCmd(ENABLE);  

  19.     //等待RTC_CTL寄存器中的RSF位(寄存器同步标志)被硬件置1  

  20.     RTC_WaitForSynchro();  

  21.     RTC_WaitForLastTask();    

  22.   

  23.     //使能闹钟中断     

  24.     RTC_ITConfig(RTC_IT_ALR, ENABLE);    

  25.     RTC_WaitForLastTask();    

  26.   

  27.     //分频系数为1,即最小时间单位1/2^15 = 30.5us  

  28.     RTC_SetPrescaler(RTC_PRESCALE);    

  29.     RTC_WaitForLastTask();  

  30.   

  31.     //启动独立看门狗  

  32.     IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);                   //访问之前要首先使能寄存器写  

  33.     IWDG_SetPrescaler(IWDG_Prescaler_64);                           //64分频 一个周期1.6ms  

  34.     IWDG_SetReload(1250);                                           //最长12位 [0,4096] 1250*1.6 = 2s  

  35.     IWDG_ReloadCounter();                                           //喂狗  

  36.     //使能开门狗  

  37.     IWDG_Enable();    

  38.       

  39.     if (BKP_ReadBackupRegister(BKP_DR6) == 0xabcd)  

  40.     {  

  41.         GPIO_ResetBits(GPIOA, GPIO_Pin_11) ;  

  42.         BKP_WriteBackupRegister(BKP_DR6,0);  

  43.     }  

  44.     else  

  45.     {  

  46.         GPIO_SetBits(GPIOA,GPIO_Pin_11) ;  

  47.         BKP_WriteBackupRegister(BKP_DR6,0xabcd);  

  48.     }                                             

  49. }  

  50. else  

  51. {     

  52.     //从待机模式中退出    

  53.     //清除唤醒标志  

  54.     RCC_ClearFlag();   

  55.   

  56.     if (BKP_ReadBackupRegister(BKP_DR7) == 0xabcd)  

  57.     {  

  58.         GPIO_ResetBits(GPIOA, GPIO_Pin_8) ;  

  59.         BKP_WriteBackupRegister(BKP_DR7,0);  

  60.     }  

  61.     else  

  62.     {  

  63.         GPIO_SetBits(GPIOA,GPIO_Pin_8) ;  

  64.         BKP_WriteBackupRegister(BKP_DR7,0xabcd);  

  65.     }  

  66. }  

  67.   

  68. //延时1s  

  69. for (i = 0;i < 100;i++)  

  70. {  

  71.     _delay_ms(10);  

  72. }  

  73.       

  74. //打开待机模式,2s后唤醒  

  75. open_standy_mode(60000);  

 

每次刚上电所有LED会亮,进入待机模式则全部灭.测试结果PA11引脚所连的LED会亮1s进入灭进入待机模式,下次则常灭进入待机模式.PA8所连的LED随着低功耗进入正常亮灭,而且待机模式是待机2s加延时1s应该是3s唤醒,LED闪烁频率2s左右说明被提前唤醒.这说明不断发生看门狗唤醒.

 

完整的测试程序:判断出首次启动程序,单片机处于正常状态时看门狗复位,单片机处于待机模式下被闹钟唤醒/看门狗唤醒.

注意:每次看门狗复位都要被重新配置启动

 

  1. //检查是否正常状态发生看门狗复位  

  2. if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET)  

  3. {  

  4.     //清楚标志位  

  5.     RCC_ClearFlag();  

  6.   

  7.     //RTC功能开启  

  8.     //使能外部晶振  

  9.     RCC_LSEConfig(RCC_LSE_ON);  

  10.     //等待外部晶振准备好  

  11.     while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);  

  12.   

  13.     //设置RTC时钟为外部晶振  

  14.     RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);  

  15.   

  16.     //使能RTC时钟  

  17.     RCC_RTCCLKCmd(ENABLE);  

  18.     //等待RTC_CTL寄存器中的RSF位(寄存器同步标志)被硬件置1  

  19.     RTC_WaitForSynchro();  

  20.     RTC_WaitForLastTask();    

  21.   

  22.     //使能闹钟中断     

  23.     RTC_ITConfig(RTC_IT_ALR, ENABLE);    

  24.     RTC_WaitForLastTask();    

  25.   

  26.     //分频系数为1,即最小时间单位1/2^15 = 30.5us  

  27.     RTC_SetPrescaler(RTC_PRESCALE);    

  28.     RTC_WaitForLastTask();  

  29.   

  30.     //启动独立看门狗  

  31.     IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);                   //访问之前要首先使能寄存器写  

  32.     IWDG_SetPrescaler(IWDG_Prescaler_64);                           //64分频 一个周期1.6ms  

  33.     IWDG_SetReload(1250);                                           //最长12位 [0,4096] 1250*1.6 = 2s  

  34.     IWDG_ReloadCounter();                                           //喂狗  

  35.     //使能开门狗  

  36.     IWDG_Enable();  

  37.   

  38.     if (BKP_ReadBackupRegister(BKP_DR5) == 0xabcd)  

  39.     {  

  40.         GPIO_SetBits(GPIOA,GPIO_Pin_12) ;  

  41.         BKP_WriteBackupRegister(BKP_DR5,0);  

  42.     }  

  43.     else  

  44.     {  

  45.         GPIO_ResetBits(GPIOA, GPIO_Pin_12) ;  

  46.         BKP_WriteBackupRegister(BKP_DR5,0xabcd);  

  47.     }     

  48. }  

  49. else  

  50. {  

  51.     //检查唤醒标志是否设置,判断是否首次启动  

  52.     if (PWR_GetFlagStatus(PWR_FLAG_WU) == RESET)  

  53.     {  

  54.         //首次启动  

  55.         //初始化备份寄存器  

  56.         //BKP_DeInit();  

  57.   

  58.         //RTC功能开启  

  59.         //使能外部晶振  

  60.         RCC_LSEConfig(RCC_LSE_ON);  

  61.         //等待外部晶振准备好  

  62.         while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);  

  63.       

  64.         //设置RTC时钟为外部晶振  

  65.         RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);  

  66.       

  67.         //使能RTC时钟  

  68.         RCC_RTCCLKCmd(ENABLE);  

  69.         //等待RTC_CTL寄存器中的RSF位(寄存器同步标志)被硬件置1  

  70.         RTC_WaitForSynchro();  

  71.         RTC_WaitForLastTask();    

  72.   

  73.         //使能闹钟中断     

  74.         RTC_ITConfig(RTC_IT_ALR, ENABLE);    

  75.         RTC_WaitForLastTask();    

  76.   

  77.         //分频系数为1,即最小时间单位1/2^15 = 30.5us  

  78.         RTC_SetPrescaler(RTC_PRESCALE);    

  79.         RTC_WaitForLastTask();  

  80.   

  81.         //启动独立看门狗  

  82.         IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);                   //访问之前要首先使能寄存器写  

  83.         IWDG_SetPrescaler(IWDG_Prescaler_64);                           //64分频 一个周期1.6ms  

  84.         IWDG_SetReload(1250);                                           //最长12位 [0,4096] 1250*1.6 = 2s  

  85.         IWDG_ReloadCounter();                                           //喂狗  

  86.         //使能开门狗  

  87.         IWDG_Enable();    

  88.           

  89.         if (BKP_ReadBackupRegister(BKP_DR6) == 0xabcd)  

  90.         {  

  91.             GPIO_ResetBits(GPIOA, GPIO_Pin_11) ;  

  92.             BKP_WriteBackupRegister(BKP_DR6,0);  

  93.         }  

  94.         else  

  95.         {  

  96.             GPIO_SetBits(GPIOA,GPIO_Pin_11) ;  

  97.             BKP_WriteBackupRegister(BKP_DR6,0xabcd);  

  98.         }                                             

  99.     }  

  100.     else  

  101.     {     

  102.         //从待机模式中退出,有闹钟唤醒或者看门狗唤醒   

  103.         //清除唤醒标志  

  104.         RCC_ClearFlag();   

  105.   

  106.         if (BKP_ReadBackupRegister(BKP_DR7) == 0xabcd)  

  107.         {  

  108.             GPIO_ResetBits(GPIOA, GPIO_Pin_8) ;  

  109.             BKP_WriteBackupRegister(BKP_DR7,0);  

  110.         }  

  111.         else  

  112.         {  

  113.             GPIO_SetBits(GPIOA,GPIO_Pin_8) ;  

  114.             BKP_WriteBackupRegister(BKP_DR7,0xabcd);  

  115.         }  

  116.     }  

  117. }  

  118.   

  119. //延时1s  

  120. for (i = 0;i < 100;i++)  

  121. {  

  122.     _delay_ms(10);  

  123. }  

  124.   

  125. //打开待机模式,2s后唤醒  

  126. open_standy_mode(60000);  


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 简洁的过零调功器电路设计与分析

  • 单稳态控制电路设计与分析

  • IGBT模块通过控制门极阻断过电流

  • CCFL的工作原理及电子驱动电路解析

  • 运算放大器IC741的基本工作原理及在电路中的实现方式

  • 基于CA3193的热电偶放大器电路

    相关电子头条文章