完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
这几天在调试STM32f030f4p6这颗芯片进入stop模式,然后被唤醒,我是用PA1做的,PA1配置成外部下降沿中断,来做开关键:板子开机 -> 按下PA1 -> 芯片进入stop模式 -> 按下PA1 -> 外部中断将芯片唤醒 。。。
程序处理如下: void EXti0_1_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line1)!= RESET ) { if(mcu_state == MCU_IS_RUNNING) mcu_state = MCU_IS_STOP; else if(mcu_state == MCU_IS_STOP) mcu_state = MCU_IS_RUNNING; b_mcu_exti_has_intterrupt = 1; EXTI_ClearITPendingBit(EXTI_Line1); } } 然后在main里面: void MCU_State_Change(void) { if(b_mcu_exti_has_intterrupt) { b_mcu_exti_has_intterrupt = 0; if(mcu_state == MCU_IS_RUNNING) { } else if(mcu_state == MCU_IS_STOP) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); NVIC_SystemLPConfig(NVIC_LP_SLEEPDEEP,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE); PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI); } } } 现在发现两个问题: 1.感觉按键不是很灵敏,有时要按几下才能进入休眠,有时休眠要按几下才能唤醒,外部中断我仿真过,每次按下按键都能进到中断里面。 2.芯片进入stop模式之后被唤醒,时钟明显感觉变慢了,我在数码管上做了TIM16计数,我后来在: if(mcu_state == MCU_IS_RUNNING) { TIM16_For_Tick_Start(); /*开定时器*/ } 这里又将TIM16初始化了一次,感觉还是慢了,不知道是什么问题 |
|
相关推荐
20个回答
|
|
|
|
至于按键不灵敏的情况,既然你每次按下按键都能进入到外部中断说明不是按键响应而是某些原因导致程序没能够进入STOP休眠模式。比如手册上说的这些:
If Flash memory programming is ongoing, the Stop mode entry is delayed until the memory access is finished. If an access to the APB domain is ongoing, The Stop mode entry is delayed until the APB access is finished. |
|
1 条评论
|
|
没遇到过,换个板子或芯片试试
|
|
|
|
亲爱的娜娜 发表于 2018-10-11 07:59 你说的太对了,我在唤醒的地方加了个SystemInit()就没问题了,应该是进入stop的时候程序执行到哪里,唤醒之后接着从这里执行吧,关于按键的问题,我想有可能是因为按键抖动的原因,我在查查,非常感谢您 |
|
|
|
|
|
|
|
60user142 发表于 2018-10-11 08:22 本帖最后由 creep 于 2015-6-2 10:36 编辑 不要用SystemInit(),直接用我上面的那个代码SYSCLKConfig_STOP(void),因为调用SystemInit()的时间可能会大于SYSCLKConfig_STOP,这对于实时性要求高的系统是恢复系统时钟越快越好。唤醒之后从PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);后面的代码接着执行。 |
|
|
|
本帖最后由 creep 于 2015-6-2 10:37 编辑 这个是官方提供的一个函数,你可以试着让系统启动后自动进入休眠模式然后再自动唤醒或者按键唤醒,这个可以测试是不是按键的问题。 |
|
|
|
亲爱的娜娜 发表于 2018-10-11 09:01 我仿真看了下,有的时候连着发生了两次中断,这才是问题的根源,暂时还没想到什么办法 |
|
|
|
进入按键唤醒中断后马上调用恢复系统时钟函数SYSCLKConfig_STOP,然后重新初始化该按键引脚关闭掉中断使能,等需要进入时再次配置为中断引脚。 |
|
|
|
亲爱的娜娜 发表于 2018-10-11 09:21 我这个引脚是做开关用,呵呵,这种办法我也想过,理论上都行不通,我可能会连续的按下这个按键来测试开关功能,也可能按下这个按键 半年不动它 |
|
|
|
亲爱的娜娜 发表于 2018-10-11 09:21 你这种做法不对,我是做开关按键,所以不适用,我为了消抖,在按键按下进入中断之后,又开了一个定时器,定时时间为10ms,如果定时器时间到,就到定时器中断里面去处理进入stop模式,这么做进入stop模式很灵了,但是外部中断无法唤醒芯片了,我用了EXTI0和EXTI1这两个中断,都没办法唤醒了 |
|
|
|
学习了。。。。
|
|
|
|
60user142 发表于 2018-10-11 09:52 你感觉对就行。 我也是作为开关机按键使用的,感觉特别灵敏,无论开机关机都没有误操作过。 |
|
|
|
我就是感觉IO口的状态切换上不知道什么时机最好,现在的问题是为什么外部中断都无法唤醒芯片了 |
|
|
|
能把你的代码给我参考下吗?非常感谢 |
|
|
|
你可以把你的代码贴出来让大家讨论下,外部中断唤不醒会不会是其他问题导致的外部中断没有发生。 |
|
|
|
void EXTI0_1_IRQHandler(void) { unsigned int i; for(i=0;i<200;i++); if(EXTI_GetITStatus(EXTI_Line0)!= RESET ) { if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0) b_current_source = CURRENT_FORM_BAT; else b_current_source = CURRENT_FORM_AC; b_current_has_change = 1; if(mcu_state == MCU_IS_STOP) { Wakeup_Form_Stop_Mode(); } EXTI_ClearITPendingBit(EXTI_Line0); } else if(EXTI_GetITStatus(EXTI_Line1)!= RESET ) { EXTI_ClearITPendingBit(EXTI_Line1); if(mcu_state == MCU_IS_RUNNING) { Enter_Stop_Mode(); } else { Wakeup_Form_Stop_Mode(); } } } void Enter_Stop_Mode(void) { mcu_state = MCU_IS_STOP; sys_sleep_all(); NVIC_SystemLPConfig(NVIC_LP_SLEEPDEEP,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE); PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI); } void Wakeup_Form_Stop_Mode(void) { mcu_state = MCU_IS_RUNNING; SYSCLKConfig_STOP(); PWM_For_Light_Start(10); TIM16_For_Tick_Start(); } 我还好是退回到最开始的那种做法了,不用定时器,按下按键进入中断,在中断里面判断当前芯片的状态,然后修改状态,执行相应的程序,这种做法休眠是进去了,但是休眠之后按此按键 还是唤醒不了芯片 PA0 PA1都唤醒不了,这个问题都困扰我三天了 |
|
|
|
使用这种方法一次也没有唤醒过吗?可不可以贴一下sys_sleep_all();的代码 |
|
|
|
void sys_sleep_all(void)
{ PWM_For_Light_Start(0); /*关灯*/ TIM16_For_Tick_Stop(); /*关定时器*/ red_light_switch_control(LIGHT_OFF); green_light_switch_control(LIGHT_OFF); yellow_light_switch_control(LIGHT_OFF); }这种方法就是直接在中断函数里面调用上面几个函数。 我的第一种处理方式就是在main函数的while(1)里面直接调用 void MCU_State_Change(void) { if(b_mcu_exti_has_intterrupt ) /*只在直流下起左右*/ { b_mcu_exti_has_intterrupt = 0; if(mcu_state == MCU_IS_STOP) { mcu_state = MCU_IS_RUNNING; SYSCLKConfig_STOP(); PWM_For_Light_Start(10); /*开灯*/ TIM16_For_Tick_Start(); /*开定时器*/ } else if(mcu_state == MCU_IS_RUNNING) { mcu_state = MCU_IS_STOP; sys_sleep_all(); NVIC_SystemLPConfig(NVIC_LP_SLEEPDEEP,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE); PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI); } } } 然后在中断函数里面使b_mcu_exti_has_intterrupt = 1;这种方式就是很多误动作,有时按几下才能进入stop |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
2005 浏览 1 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
1858 浏览 3 评论
4442 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
2007 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
2513 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-19 23:20 , Processed in 1.036304 second(s), Total 122, Slave 102 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号