环境:
主机: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位也可以指示是否发生独立看门狗复位.
源代码:
独立看门狗复位测试:
//检查唤醒标志是否设置if (PWR_GetFlagStatus(PWR_FLAG_WU) == RESET){ //首次启动,或者独立看门狗复位 //初始化备份寄存器 //BKP_DeInit(); //RTC功能开启 //使能外部晶振 RCC_LSEConfig(RCC_LSE_ON); //等待外部晶振准备好 while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET); //设置RTC时钟为外部晶振 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //使能RTC时钟 RCC_RTCCLKCmd(ENABLE); //等待RTC_CTL寄存器中的RSF位(寄存器同步标志)被硬件置1 RTC_WaitForSynchro(); RTC_WaitForLastTask(); //使能闹钟中断 RTC_ITConfig(RTC_IT_ALR, ENABLE); RTC_WaitForLastTask(); //分频系数为1,即最小时间单位1/2^15 = 30.5us RTC_SetPrescaler(RTC_PRESCALE); RTC_WaitForLastTask(); //启动独立看门狗 IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //访问之前要首先使能寄存器写 IWDG_SetPrescaler(IWDG_Prescaler_64); //64分频 一个周期1.6ms IWDG_SetReload(1250); //最长12位 [0,4096] 1250*1.6 = 2s IWDG_ReloadCounter(); //喂狗 //使能开门狗 IWDG_Enable(); if (BKP_ReadBackupRegister(BKP_DR6) == 0xabcd) { GPIO_ResetBits(GPIOA, GPIO_Pin_11) ; BKP_WriteBackupRegister(BKP_DR6,0); } else { GPIO_SetBits(GPIOA,GPIO_Pin_11) ; BKP_WriteBackupRegister(BKP_DR6,0xabcd); } }else{ //从待机模式中退出 //清除唤醒标志 RCC_ClearFlag(); if (BKP_ReadBackupRegister(BKP_DR7) == 0xabcd) { GPIO_ResetBits(GPIOA, GPIO_Pin_8) ; BKP_WriteBackupRegister(BKP_DR7,0); } else { GPIO_SetBits(GPIOA,GPIO_Pin_8) ; BKP_WriteBackupRegister(BKP_DR7,0xabcd); }}while (1);
测试结果PA11引脚所连的LED不断闪烁,PA8所连的LED常亮,这说明不断进入看门狗复位.
待机模式RTC闹钟唤醒测试:
//检查唤醒标志是否设置if (PWR_GetFlagStatus(PWR_FLAG_WU) == RESET){ //首次启动,或者独立看门狗复位 //初始化备份寄存器 //BKP_DeInit(); //RTC功能开启 //使能外部晶振 RCC_LSEConfig(RCC_LSE_ON); //等待外部晶振准备好 while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET); //设置RTC时钟为外部晶振 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //使能RTC时钟 RCC_RTCCLKCmd(ENABLE); //等待RTC_CTL寄存器中的RSF位(寄存器同步标志)被硬件置1 RTC_WaitForSynchro(); RTC_WaitForLastTask(); //使能闹钟中断 RTC_ITConfig(RTC_IT_ALR, ENABLE); RTC_WaitForLastTask(); //分频系数为1,即最小时间单位1/2^15 = 30.5us RTC_SetPrescaler(RTC_PRESCALE); RTC_WaitForLastTask(); //启动独立看门狗 IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //访问之前要首先使能寄存器写 IWDG_SetPrescaler(IWDG_Prescaler_64); //64分频 一个周期1.6ms IWDG_SetReload(1250); //最长12位 [0,4096] 1250*1.6 = 2s IWDG_ReloadCounter(); //喂狗 //使能开门狗 //IWDG_Enable(); if (BKP_ReadBackupRegister(BKP_DR6) == 0xabcd) { GPIO_ResetBits(GPIOA, GPIO_Pin_11) ; BKP_WriteBackupRegister(BKP_DR6,0); } else { GPIO_SetBits(GPIOA,GPIO_Pin_11) ; BKP_WriteBackupRegister(BKP_DR6,0xabcd); } }else{ //从待机模式中退出 //清除唤醒标志 RCC_ClearFlag(); if (BKP_ReadBackupRegister(BKP_DR7) == 0xabcd) { GPIO_ResetBits(GPIOA, GPIO_Pin_8) ; BKP_WriteBackupRegister(BKP_DR7,0); } else { GPIO_SetBits(GPIOA,GPIO_Pin_8) ; BKP_WriteBackupRegister(BKP_DR7,0xabcd); }}
//延时1sfor (i = 0;i < 100;i++){ _delay_ms(10);}
//打开待机模式,1s后唤醒
open_standy_mode(30000);
每次刚上电所有LED会亮,进入待机模式则全部灭.测试结果PA8引脚所连的LED会亮1s进入灭进入待机模式,下次则常灭进入待机模式.PA11所连的LED随着低功耗进入正常亮灭,这说明不断发生闹钟唤醒(看门狗已关).
待机模式IWDG唤醒测试:
//检查唤醒标志是否设置if (PWR_GetFlagStatus(PWR_FLAG_WU) == RESET){ //首次启动,或者独立看门狗复位 //初始化备份寄存器 //BKP_DeInit(); //RTC功能开启 //使能外部晶振 RCC_LSEConfig(RCC_LSE_ON); //等待外部晶振准备好 while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET); //设置RTC时钟为外部晶振 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //使能RTC时钟 RCC_RTCCLKCmd(ENABLE); //等待RTC_CTL寄存器中的RSF位(寄存器同步标志)被硬件置1 RTC_WaitForSynchro(); RTC_WaitForLastTask(); //使能闹钟中断 RTC_ITConfig(RTC_IT_ALR, ENABLE); RTC_WaitForLastTask(); //分频系数为1,即最小时间单位1/2^15 = 30.5us RTC_SetPrescaler(RTC_PRESCALE); RTC_WaitForLastTask(); //启动独立看门狗 IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //访问之前要首先使能寄存器写 IWDG_SetPrescaler(IWDG_Prescaler_64); //64分频 一个周期1.6ms IWDG_SetReload(1250); //最长12位 [0,4096] 1250*1.6 = 2s IWDG_ReloadCounter(); //喂狗 //使能开门狗 IWDG_Enable(); if (BKP_ReadBackupRegister(BKP_DR6) == 0xabcd) { GPIO_ResetBits(GPIOA, GPIO_Pin_11) ; BKP_WriteBackupRegister(BKP_DR6,0); } else { GPIO_SetBits(GPIOA,GPIO_Pin_11) ; BKP_WriteBackupRegister(BKP_DR6,0xabcd); } }else{ //从待机模式中退出 //清除唤醒标志 RCC_ClearFlag(); if (BKP_ReadBackupRegister(BKP_DR7) == 0xabcd) { GPIO_ResetBits(GPIOA, GPIO_Pin_8) ; BKP_WriteBackupRegister(BKP_DR7,0); } else { GPIO_SetBits(GPIOA,GPIO_Pin_8) ; BKP_WriteBackupRegister(BKP_DR7,0xabcd); }}//延时1sfor (i = 0;i < 100;i++){ _delay_ms(10);} //打开待机模式,2s后唤醒open_standy_mode(60000);
每次刚上电所有LED会亮,进入待机模式则全部灭.测试结果PA11引脚所连的LED会亮1s进入灭进入待机模式,下次则常灭进入待机模式.PA8所连的LED随着低功耗进入正常亮灭,而且待机模式是待机2s加延时1s应该是3s唤醒,LED闪烁频率2s左右说明被提前唤醒.这说明不断发生看门狗唤醒.
完整的测试程序:判断出首次启动程序,单片机处于正常状态时看门狗复位,单片机处于待机模式下被闹钟唤醒/看门狗唤醒.
注意:每次看门狗复位都要被重新配置启动
//检查是否正常状态发生看门狗复位if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET){ //清楚标志位 RCC_ClearFlag(); //RTC功能开启 //使能外部晶振 RCC_LSEConfig(RCC_LSE_ON); //等待外部晶振准备好 while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET); //设置RTC时钟为外部晶振 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //使能RTC时钟 RCC_RTCCLKCmd(ENABLE); //等待RTC_CTL寄存器中的RSF位(寄存器同步标志)被硬件置1 RTC_WaitForSynchro(); RTC_WaitForLastTask(); //使能闹钟中断 RTC_ITConfig(RTC_IT_ALR, ENABLE); RTC_WaitForLastTask(); //分频系数为1,即最小时间单位1/2^15 = 30.5us RTC_SetPrescaler(RTC_PRESCALE); RTC_WaitForLastTask(); //启动独立看门狗 IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //访问之前要首先使能寄存器写 IWDG_SetPrescaler(IWDG_Prescaler_64); //64分频 一个周期1.6ms IWDG_SetReload(1250); //最长12位 [0,4096] 1250*1.6 = 2s IWDG_ReloadCounter(); //喂狗 //使能开门狗 IWDG_Enable(); if (BKP_ReadBackupRegister(BKP_DR5) == 0xabcd) { GPIO_SetBits(GPIOA,GPIO_Pin_12) ; BKP_WriteBackupRegister(BKP_DR5,0); } else { GPIO_ResetBits(GPIOA, GPIO_Pin_12) ; BKP_WriteBackupRegister(BKP_DR5,0xabcd); } }else{ //检查唤醒标志是否设置,判断是否首次启动 if (PWR_GetFlagStatus(PWR_FLAG_WU) == RESET) { //首次启动 //初始化备份寄存器 //BKP_DeInit(); //RTC功能开启 //使能外部晶振 RCC_LSEConfig(RCC_LSE_ON); //等待外部晶振准备好 while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET); //设置RTC时钟为外部晶振 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //使能RTC时钟 RCC_RTCCLKCmd(ENABLE); //等待RTC_CTL寄存器中的RSF位(寄存器同步标志)被硬件置1 RTC_WaitForSynchro(); RTC_WaitForLastTask(); //使能闹钟中断 RTC_ITConfig(RTC_IT_ALR, ENABLE); RTC_WaitForLastTask(); //分频系数为1,即最小时间单位1/2^15 = 30.5us RTC_SetPrescaler(RTC_PRESCALE); RTC_WaitForLastTask(); //启动独立看门狗 IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //访问之前要首先使能寄存器写 IWDG_SetPrescaler(IWDG_Prescaler_64); //64分频 一个周期1.6ms IWDG_SetReload(1250); //最长12位 [0,4096] 1250*1.6 = 2s IWDG_ReloadCounter(); //喂狗 //使能开门狗 IWDG_Enable(); if (BKP_ReadBackupRegister(BKP_DR6) == 0xabcd) { GPIO_ResetBits(GPIOA, GPIO_Pin_11) ; BKP_WriteBackupRegister(BKP_DR6,0); } else { GPIO_SetBits(GPIOA,GPIO_Pin_11) ; BKP_WriteBackupRegister(BKP_DR6,0xabcd); } } else { //从待机模式中退出,有闹钟唤醒或者看门狗唤醒 //清除唤醒标志 RCC_ClearFlag(); if (BKP_ReadBackupRegister(BKP_DR7) == 0xabcd) { GPIO_ResetBits(GPIOA, GPIO_Pin_8) ; BKP_WriteBackupRegister(BKP_DR7,0); } else { GPIO_SetBits(GPIOA,GPIO_Pin_8) ; BKP_WriteBackupRegister(BKP_DR7,0xabcd); } }}//延时1sfor (i = 0;i < 100;i++){ _delay_ms(10);}//打开待机模式,2s后唤醒open_standy_mode(60000);
上一篇:stm32 低功耗下使用看门狗(不喂狗)
下一篇:STM32 休眠模式下,难道 看门狗和低功耗模式没法同时使用?
推荐阅读最新更新时间:2024-11-05 04:13
设计资源 培训 开发板 精华推荐
- MC33364通用输入电池充电器典型应用电路
- 具有环境光收集器或 USB 供电充电功能的 LTC3106EFE 便携式医疗设备的典型应用电路
- LTC3110EFE 3.6V 自主备份和充电应用的典型应用电路
- 【智能车】语音遥控避障小车
- LT3477IUF 降压-升压模式 LED 驱动器的典型应用电路
- 具有双输入的 LTC3126HFE 12V、1MHz 降压转换器的典型应用电路
- 第一次实验
- STEVAL-ISA118V1,在反激拓扑中使用 Viper16 离线电源转换器的演示板
- LT6658AIMSE-2.5 的典型应用电路驱动两个代码相关的 DAC 基准输入,单独的 DAC 基准偏置消除了代码相关的基准电流相互作用
- MC3403 单电源函数发生器运算放大器的典型应用电路