历史上的今天
今天是:2025年03月29日(星期六)
2019年03月29日 | STM32休眠与唤醒
2019-03-29 来源:eefocus
这两天研究了STM32的低功耗知识,低功耗里主要研究的是STM32的待机模式和停机模式。让单片机进入的待机模式和停机模式比较容易,实验中通过设置中断口PA1来响应待机和停机模式。
voidEXTI1_IRQHandler(void)
{
if(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1))
{
delay_ms(10);
while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1));
if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1))
{
EXTI_ClearITPendingBit(EXTI_Line1);
RTC_SetAlarm(RTC_GetCounter()+4); //设置4S后闹钟唤醒
RTC_ITConfig(RTC_IT_ALR, ENABLE);//使能闹钟中断.
RTC_WaitForLastTask();//等待上一次写RTC任务完成
Standby(); //进入待机(停机)状态
}
}
}
void Standby()
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR , ENABLE);//开电源管理时钟PWR_Regulator_LowPower
PWR_WakeUpPinCmd(ENABLE);//使能唤醒引脚,默认PA0
PWR_EnterSTANDBYMode();//进入待机
//PWR_EnterSTOPMode(PWR_Regulator_ON,PWR_STOPEntry_WFI|PWR_STOPEntry_WFE);//进入停机
}
进入的待机模式和停机模式很简单,基本一样。那么问题来了。
主要问题有:
1:如何对他们进行唤醒?
2:唤醒的闹钟中断能否执行?
2:唤醒后的程序入口在哪?
通过各种实验和查资料,得到了如下结论:(本实验通过设定RTC_SetAlarm(RTC_GetCounter()+4); 为设置4S后进行闹钟唤醒,并开启闹钟中断,手册中可以查到闹钟中断能产生唤醒,故用闹钟中断进行实验)
先研究待机模式下的唤醒,在闹钟中断函数如下:
voidRTCAlarm_IRQHandler(void)
{
if(RTC_GetFlagStatus(RTC_IT_ALR))
{
RTC_ClearITPendingBit(RTC_IT_ALR);
RTC_WaitForLastTask();
EXTI_ClearITPendingBit(EXTI_Line17);
if(PWR_GetFlagStatus(PWR_FLAG_WU) != RESET)
{
PWR_ClearFlag(PWR_FLAG_WU);
}
GPIO_WriteBit(GPIOA, GPIO_Pin_5, 0);//LED指示
}
}
实验结果:PA5的LED不指示,并且从其他LED灯的指示可以知道程序又重新开始运行。也就是被复位。
因此待机模式下的唤醒结论如下:
1:唤醒形式直接产生闹钟中断就能唤醒。
2:唤醒后不会进入闹钟中断函数
3:唤醒后程序复位,重新执行
再研究停机模式下的唤醒,停机模式唤醒和待机唤醒差别很大,开始还以为两者相同,停机唤醒相对复杂些,中途调试了很长时间,才明白了停机唤醒的过程,贴上闹钟中断程序如下:
char Wakeflag=0;
voidRTCAlarm_IRQHandler(void)
{
if(RTC_GetFlagStatus(RTC_IT_ALR))
{
EXTI_ClearITPendingBit(EXTI_Line17);
RTC_ClearITPendingBit(RTC_IT_ALR);
RTC_WaitForLastTask();
EXTI_ClearITPendingBit(EXTI_Line7);
EXTI_ClearITPendingBit(EXTI_Line1);//对于程序可能产生的标志位必须的清除干净,不清除会出现唤醒失灵现象!!
if(PWR_GetFlagStatus(PWR_FLAG_WU) != RESET)
{
PWR_ClearFlag(PWR_FLAG_WU);//一般没用
}
SystemInit();//重要,由于停机下对所有时钟关闭,所以唤醒需要重新配置时钟!!
Wakeflag=!Wakeflag;
GPIO_WriteBit(GPIOA, GPIO_Pin_5, Wakeflag);//LED灯指示
}
}
相比待机的闹钟中断是不复杂了很多,停机模式下的唤醒的中断函数需要注意这两点(能得到这两点,耗费了大量时间,终于还是搞定了,嗨皮!!):
1:重要,对于程序可能产生的标志位必须的清除干净,不清除会出现唤醒失灵现象!!
2:重要,由于停机下对所有时钟关闭,所以唤醒需要重新配置时钟!!
实验现象:LED可以产生开通与关断的效果。并且从其他LED的指示可以看到程序没有被复位,而是继续原来运行。
因此停机模式下的唤醒结论如下:
1:唤醒形式产生闹钟中断不一定就唤醒,需要对任何可能的标志位清楚,并且时钟要重新配置。
2:唤醒后进入闹钟中断函数
3:唤醒后程序进入闹钟中断函数,然后再进入原来停机的位置继续运行。没有复位,单片机寄存器里的各种变量值仍然保留!!
stm32用于进入停止模式的中断和用于产生唤醒的中断,后者的抢占优先级一定要高,否则无法唤醒!
之前做实验时,实验时遇到了一个很严重的问题,就是停止模式无法唤醒。
实验内容主要是:用一个外部中断的响应,使得程序进入停机模式。然后再通过其他一个外部中断或者闹钟中断将单片机唤醒。但是调试了很久
用于进入停止模式的中断和用于产生唤醒的中断,后者要抢占优先级一定要高,否则无法唤醒。
由实验结果分析原因:
由于进入停止模式后,调节器以低功耗模式提供1.8V电源未断开,寄存器的内容还是保持的,所以程序还处在中断里面。但另一个中断来唤醒时,由于抢占的优先级不够高,无法抢占原来的中断,故无法唤醒。所以只有用来唤醒的中断抢占优先级高,才可以唤醒!!
史海拾趣
|
1.用STM32的芯片做主机,PIC16F677作为从机作数据采集。主机用模拟方式实现IIC通信,速率是400K,从机是通过配置相关的IIC寄存器实现。 2.上电后用示波器观察,主机有发送配置地址0XF0和10连续的共10个位的数据。 3.发送的地址和677的SSPADD配置地 ...… 查看全部问答> |
|
大家好 我用一块ARM开发板来控制GPRS模块MC55,让MC55 与因特网建立一个TCP连接并传输数据 开发板上运行着ARM-Linux,我使用了cssl(一个串口通信库)来发送AT指令 建立配置文件到建立连接“AT^SISO=1”都没有问题 在测试时我想发送一个二进制 ...… 查看全部问答> |
|
工作地点:北京 (面试地:北京) 招聘岗位:软件工程师、高级软件工程师 职责描述 1)负责通信产品软件模块设计、开发工作,完成相关的设计文档、代码编写。 2)参与软件模块的部分测试工作,完成测试用例的设计、执行与测试报告的输出。 3) ...… 查看全部问答> |
|
有没有人用过威盛的UM_EPIA-M830_100,现在不会下系统,不知道怎么装系统开机的BIOS和电脑的一样,说明上写的支持wince现在想安装wince,不知道怎么安装,wince 的映像也不知道在哪找… 查看全部问答> |




