楼主需要做两个方式的待机唤醒实验,用的是stm32 F103,初步想达到的实验结果是PA0中断唤醒和RTC闹钟唤醒互相切换:
PA0唤醒后,系统跑一个流程后设置为RTC闹钟唤醒,并将PA0唤醒屏蔽;
RTC闹钟唤醒后,系统跑一个流程后设置为PA0唤醒,不用闹钟唤醒或者将闹钟设置的时间变长;
用到的是原子的例程,函数也是从原子里参考过来的:
发现的问题是PA0单独唤醒和RTC闹钟单独唤醒都是OK的,我在实验中利用了BKP寄存器来保存上一次醒来的方式做判断来切换,
问题是当一次PA0唤醒后,进入待机模式以后,PA0唤醒一直存在,不重启就一直存在,把相应的位禁掉之后不起作用。不知道为什么,代码如下:
/*取消备份区写保护*/
RCC->APB1ENR|=1<<28; //使能电源时钟
RCC->APB1ENR|=1<<27; //使能备份时钟
PWR->CR|=1<<8; //取消备份区写保护
delay_ms(100);
/*****读取上次的唤醒方式*********/
WKUPMod = BKP_ReadBackupRegister(BKP_DR5);
delay_ms(100);
//***********************************
if(WKUPMod==1)//PA0唤醒
{
PWR->CSR|=0<<8; //不设置WKUP用于唤醒
BKP_WriteBackupRegister(BKP_DR5,(uint16_t)2); //写BKP寄存器
DelayMod=30;
RTC_Init(); //RTC初始化
while(RTC_Init()) //RTC初始化 ,一定要初始化成功
{
delay_ms(800);
}
rtccnt=RTC->CNTH;//得到闹钟值
rtccnt<<=16;
rtccnt|=RTC->CNTL;
ALARM_CNT_Set(rtccnt+DelayMod);//设置30秒钟后,闹钟唤醒
}
else//RTC唤醒
{
PWR->CSR|=1<<8;//设置WKUP用于唤醒
BKP_WriteBackupRegister(BKP_DR5,(uint16_t)1);
}
GPIO_ResetBits(GPIOB, PB14);
delay_ms(2000);
Sys_Enter_Standby();
-------------------------------------------------------------------------------------------------------------------
void Sys_Enter_Standby(void)
{
//关闭所有外设(根据实际情况写)
RCC->APB2RSTR|=0X01FC;//复位所有IO口
//关闭所有用到的时钟----串口2NB口
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, DISABLE);
Sys_Standby();//进入待机模式
}
---------------------------------------------------------------------------------------------------
//进入待机模式
void Sys_Standby(void)
{
SCB->SCR|=1<<2;//使能SLEEPDEEP位 (SYS->CTRL)
/*取消备份区写保护*/
RCC->APB1ENR|=1<<28; //使能电源时钟
RCC->APB1ENR|=1<<27; //使能备份时钟
PWR->CR|=1<<8; //取消备份区写保护
delay_ms(100);
PWR->CR|=1<<2; //清除Wake-up 标志
PWR->CR|=1<<1; //PDDS置位
WFI_SET(); //执行WFI指令
}
---------------------------------------------------------------------------------------------------------------------------------
//中断处理函数,清标志即可
void EXTI0_IRQHandler(void)
{
EXTI->PR=1<<0; //清除LINE10上的中断标志位
}
---------------------------------------------------------------------------------------------------------------------------
实验现象是:当板子因为RTC闹钟进入待机后,将PA0短接3.3v,然后松开,会启动板子,然后再次进入待机,此时按照我写的程序来说,PA0唤醒应该已经不起作用了,但是此时再次短接PA0和3.3v,板子又会起来,也就是说
PA0启动一次后像记住了一样,一直存在。按下复位键再次启动程序,PA0恢复正常,无法唤醒板子,唤醒一次后,又杀不掉这个唤醒方法了。
求大神解释下是什么原因。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>