广州seo网站推广费用,做电商网站价格,房屋装修设计公司,室内设计方案设计说明目录
一、停止模式基础知识
1、进入停止模式
2、停止模式的状态
3、退出停止模式
4、SysTick定时器的影响
二、停止模式应用示例
1、示例功能和CubeMX项目配置
#xff08;1#xff09;时钟
#xff08;2#xff09;RTC
#xff08;3#xff09;ADC1
#xf…目录
一、停止模式基础知识
1、进入停止模式
2、停止模式的状态
3、退出停止模式
4、SysTick定时器的影响
二、停止模式应用示例
1、示例功能和CubeMX项目配置
1时钟
2RTC
3ADC1
4 NVIC
5DEBUG、LED1、USART6、CodeGenerator
2、软件设计
1KEYLED
2main.h
3main.c
3、运行并调试 一、停止模式基础知识
1、进入停止模式 用户可以通过执行WFI指令或WFE指令进入停止模式。进入停止模式之前用户需要将Cortex-M4F系统控制寄存器SCR的SLEEPDEEP位置1内部调压器可以设置为正常运行或低功耗模式。函数HAL_PWR_EnterSTOPMode()用于进入停止模式其源代码如下 函数HAL_PWR_EnterSTOPMode()用于进入停止模式其源代码如下
void HAL_PWR_EnterSTOPMode(uint32_t Regulator,uint8_t STOPEntry)
{/*Check the parameters */assert_param(IS_PWR_REGULATOR(Regulator));assert_param(IS_PWR_STOP_ENTRY(STOPEntry));/*设置调压器的模式根据参数Regulator设置PDDS位和LPDS位*/MODIFY_REG(PWR-CR,(PWR_CR_PDDS I PWR_CR_LPDS),Regulator);/*将Cortex系统控制寄存器SCR的SLEEPDEEP位置1*/SET_BIT(SCB-SCR,((uint32_t)SCB_SCR_SLEEPDEEP_Msk));/*Select Stop mode entry*/if(STOPEntry PWR_STOPENTRY_WFI){/*Request Wait For Interrupt */__WFI();}else{/*Request Wait For Event */__SEV();__WFE();__WFE();}/*唤醒后将SLEEPDEEP位清零*/CLEAR_BIT(SCB-SCR,((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
} 参数Regulator用于表示调压器在停止模式下的工作方式取值为宏定义常量PWR_MAINREGULATOR_ON调压器正常运行或PWR_LOWPOWERREGULATOR_ON调压器处于低功耗模式。 参数SLEEPEntry表示用何种指令进入睡眠模式WFI或WFE指令。其取值为宏定义常量PWR_SLEEPENTRY_WFI或PWR_SLEEPENTRY_WFE。 函数HAL_PWR_EnterSTOPMode()在进入停止模式之前将Cortex-M4F系统控制寄存器SCR的SLEEPDEEP位置1被唤醒后再将SLEEPDEEP位清零。 特别地要进入停止模式所有EXTI线的中断挂起标志都必须清零否则将忽略进入停止模式的操作而继续执行程序。 在停止模式下可以保持或关闭Flash的电源在进入停止模式之前可以使用以下两个函数进行设置。
HAL_PWREX_EnableFlashPowerDown(); //关闭Flash的电源
HAL_PWREx_DisableFlashPowerDown(); //不关闭Flash的电源
2、停止模式的状态 进入停止模式后系统的状态如下。
CPU的时钟关闭CPU停止运行也就是程序暂停。所有1.2V域外设的时钟停止外设停止工作。ADC和DAC不会自动停止工作需要编程使其停止。1.2V调压器开启或处于低功耗状态所有寄存器、SRAM的内容保留。Flash处于正常模式或掉电模式。HSI振荡器和HSE振荡器关闭。
3、退出停止模式 如果使用WFI指令进入停止模式所有配置为中断模式的EXTI线都可以唤醒系统。由中断唤醒后先执行中断的ISR然后执行WFI指令后面的程序。 如果使用WFE指令进入停止模式所有配置为事件模式的EXTI线都可以唤醒系统唤醒后执行WFE后面的程序。 EXTI线共23根EXTI线0:15对应于外部引脚中断EXTI线16:22对应一些内部事件如RTC闹钟事件、RTC周期唤醒事件等。 从停止模式唤醒时系统有一定的唤醒延迟时间包括以下几个时间。
HSI振荡器的启动时间。系统将重新启动HSI振荡器并且将HSI作为HCLK的时钟源。对STM32F407来说HSI频率为16MHz使用HSI作为时钟源的HCLK最高频率为16MHz。如果需要系统从停止模式唤醒后使用更高频率的HCLK需要重新配置系统时钟。如果调压器处于低功耗模式需要从低功耗模式恢复到正常模式的时间。若Flash处于掉电模式需要从掉电模式恢复到正常模式的时间。 在停止模式下如果调压器处于低功耗模式、Flash处于掉电模式则可以降低停止模式的功耗但这同时也会增加唤醒延迟。
4、SysTick定时器的影响 MCU进入停止模式后将只会由EXTI中断或事件唤醒而不受SysTick定时器的影响。此外在进入停止模式后所有的1.2V域外设都会停止工作SysTick定时器其实也停止了。
二、停止模式应用示例 本文将创建一个示例项目测试系统的STOP模式。继续使用旺宝红龙开发板STM32F407ZGT6 KIT V1.0。一些设置参考本文作者的其他文章。 参考文章细说STM32F407单片机电源低功耗SleepMode模式及应用示例-CSDN博客 https://wenchm.blog.csdn.net/article/details/145226004
1、示例功能和CubeMX项目配置 本文演示MCU的停止模式。示例的功能和操作流程如下。
在主程序的while循环里让MCU进入停止模式。使用RTC的周期唤醒中断使MCU从停止模式唤醒RTC唤醒周期为5s。MCU从停止模式唤醒后进行一次轮询方式ADC转换。
1时钟 禁用HSE这样做很重要因为不这样做依旧设置外部时钟的话系统将不能清空EXTI的中断线标志位。将HSI直接作为HCLK时钟源HCLK设置为16MHz。因为MCU从停止模式唤醒后自动使用HSI作为SYSCLK时钟源所以如果要使用HSE或更高频率的HCLK需要重新配置系统时钟。本示例在系统唤醒后不再配置HCLK时钟频率故正常运行时也使用HSI作为HCLK时钟源。 2RTC 并使用LSE作为RTC的时钟源。开启RTC的周期唤醒功能 并设置唤醒时钟为1Hz信号唤醒计数值为4。RTC的周期唤醒使用的是EXTI线22中断在NVIC中开启RTC周期唤醒中断设置其抢占优先级为1。这样设置后每5s发生一次EXTI线22中断。 3ADC1 启用ADC1的内部参考电压通道设置为12位精度、右对齐、软件触发转换。ADC1的参数设置结果如图。 4 NVIC 5DEBUG、LED1、USART6、CodeGenerator 同参考文章。
2、软件设计
1KEYLED 本示例工程继续引用KEYLED文件夹中的keyled.h详见参考文章。
2main.h 声明一个函数用于EXTI线清零。
/* USER CODE BEGIN Private defines */
void EXTI_ClearITPendingBit();
/* USER CODE END Private defines */
3main.c
/* USER CODE BEGIN Includes */
#include keyled.h
#include stdio.h //用到函数sprintf()
#include string.h //用到函数strlen()
/* USER CODE END Includes */
/* USER CODE BEGIN 2 */printf(Demo22_2_StopMode:Test Stop Mode.\r\n);printf(Wake up by RTC every 5s.\r\n);//如果配置了FSMC//HAL_PWREx_EnableFlashPowerDown(); //在停止模式下关闭Flash电源//HAL_PWREx_DisableFlashPowerDown(); //不关闭Flash电源/* USER CODE END 2 */ /* USER CODE BEGIN 3 */LED1_OFF(); //LED1熄灭//以下3种清零除EXTI线pending位的方法都是正确的,确保能进入STOP模式//EXTI-PR 0; //将EXTI线的pending位清零EXTI-PR EXTI_PR_PR0 22; //将EXTI线22的pending位清零//EXTI_ClearITPendingBit(EXTI_PR_PR22); //将EXTI线22的pending位清零//进入停止模式, WFI指令进入HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON,PWR_SLEEPENTRY_WFI);//RTC周期唤醒中断(EXTI22)唤醒系统LED1_ON();HAL_ADC_Start(hadc1); //使能ADC1并开始转换,内部通道参考电压if (HAL_ADC_PollForConversion(hadc1,200) HAL_OK){uint32_t val HAL_ADC_GetValue(hadc1) 0x0000FFFF; //12位数uint32_t Volt 3300*val; //单位mVVolt Volt12; //除以2^12printf(ADC Voltage(mV) %ld\r\n,Volt);}HAL_ADC_Stop(hadc1); //停止ADC1HAL_Delay(500); //消除按键抖动影响并且使LED1亮500ms}/* USER CODE END 3 */ 在进入while循环之前调用了函数HAL_PWREx_EnableFlashPowerDown()这可以在MCU进入停止模式后关闭Flash存储器的电源进一步降低功耗。也可以不关闭Flash存储器电源也就是调用函数HAL_PWREx_DisableFlashPowerDown()可选。 在while循环里调用函数HAL PWR EnterSTOPMode()使系统进入停止模式。必须在所有EXTI线中断的挂起标志位清零的情况下才能进入停止模式。为此直接将外部中断挂起标志寄存器PR的内容清零即执行语句
EXTI-PR 0; 进入停止模式后CPU停止运行程序暂停所有外设停止工作但RTC仍能正常工作。停止模式可以由任意EXTI线的中断或事件唤醒RTC的周期唤醒中断是EXTI线22。本示例中设置的RTC唤醒周期是5s所以在发生RTC周期唤醒中断时系统会被唤醒但是会先执行RTC中断的ISR也就是会执行RTC周期唤醒回调函数HAL_RTCEx_WakeUpTimerEventCallback()这个回调函数里读取RTC当前时间并显示在串口助手上。RTC中断的ISR退出后再继续执行WFI指令后面的程序。后面的程序用轮询方式进行一次ADC转换将结果显示在串口助手上。ADC转换结束后停止然后MCU又进入停止模式。
/* USER CODE BEGIN 4 */
// RTC 周期唤醒中断回调函数
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc)
{RTC_TimeTypeDef sTime;RTC_DateTypeDef sDate;if (HAL_RTC_GetTime(hrtc,sTime,RTC_FORMAT_BIN) HAL_OK){HAL_RTC_GetDate(hrtc,sDate,RTC_FORMAT_BIN);uint8_t str[30];sprintf((char *)str,%2d:%2d:%2d,sTime.Hours,sTime.Minutes,sTime.Seconds);//HAL_UART_Transmit(huart6,str,strlen ((const char *)(str)),200);printf(RTC current time: %s\r\n,str);}
}//清除EXTI线[0:22]的Pending register
void EXTI_ClearITPendingBit(uint32_t EXTI_Line)
{/* Check the parameters */assert_param(IS_EXTI_LINE(EXTI_Line));EXTI-PR EXTI_Line;
}int __io_putchar(int ch)
{HAL_UART_Transmit(huart6,(uint8_t*)ch,1,0xFFFF);return ch;
}
/* USER CODE END 4 */
3、运行并调试 运行时会发现每隔5s串口助手上刷新显示一次RTC时间和ADC转换结果LED1点亮500ms后熄灭。 停止模式比较适合于需要周期性唤醒执行完一些操作后又进入低功耗模式的应用。例如网络化的温度监测可能每隔60s才需要测量一次数据并通过网络发送出去使用周期唤醒的停止模式就可以大大降低功耗。 在CubeMX里可以对本示例进行功耗计算。因为使用了16MHz的HCLKRUN模式下的耗电流是8.78mASTOP模式下的耗电流是280μA。如果还选用3400mAh的锂电池供电如果一个序列中RUN模式持续10msSTOP模式持续100ms电池可以用4月12天10小时若修改为STOP模式持续1000ms其他参数不变电池可以用1年28天可见降低功耗的效果是非常明显的。