你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm32f030f4p6进入stop的问题

[复制链接]
阳阳NO1 提问时间:2015-6-4 10:43 /
          前两天发过一篇帖子,但是还没有结果,重新发一个帖子吧,重新思路,因为之前做的时候很多问题没想明白。
         处理方式:看过很多帖子以及自己实验的结果,如果在中断里面进入stop模式,会导致异常,外部中断无法唤醒的,一般的做法都是在中断里面设置一个标志位,在主程序里面再进入stop模式。

         贴上我昨晚重新修改的程序:                        void Sys_WakeUp(void)        
       {
             SYSCLKConfig_STOP();
             PWM_For_Light_Start(10);
             TIM16_For_Tick_Start();        
             RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
             RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
       }

       void Sys_Sleep(void)
      {   
            PWM_For_Light_Start(0);
            TIM16_For_Tick_Stop();        
            RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, DISABLE);
            RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, DISABLE);
            EXTI_ClearITPendingBit(EXTI_Line0 | EXTI_Line1);         
            EXTI_ClearFlag(EXTI_Line0 | EXTI_Line1);     
            PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
      }

     在main函数里面添加:
     if(b_sys_enter_stop_mode )
     {
              b_sys_enter_stop_mode = 0;
              Sys_Sleep();
             Sys_WakeUp();                        
     }
     然后在外部中断函数里面添加:
     void EXTI0_1_IRQHandler(void)
    {
          unsigned int i;
          for(i=0;i<2000;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;
                EXTI_ClearITPendingBit(EXTI_Line0);               
                EXTI_ClearFlag(EXTI_Line0);
          }               
          else if(EXTI_GetITStatus(EXTI_Line1)!= RESET )
         {               
                EXTI_ClearITPendingBit(EXTI_Line1);               
                EXTI_ClearFlag(EXTI_Line1);
                if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0)
               {
                   b_sys_enter_stop_mode = 1;
                }
        }
        
    }
    我的测试方法是接了数码管,内部有ADC+DMA,还有定时器,数码管上有定时器计时和转换的AD值。
    按照这种处理方式,按下PA1(EXI1),能正常的进入STOP模式,但再次按下PA1(EXTI1),芯片能被唤醒,但马上又进入stop模式了 。    进入休眠的现象是AD值不变化,定时器计数也不走了。
    这个时候如果按下PA0(EXTI0),是能正常唤醒的。

    疑问:
              1. 外部中断唤醒之后,会进入中断处理函数吗?
              2. 如果会进入中断处理函数,那是先进入中断处理函数,还是先恢复到进入stop模式下面的语句开始执行呢?

    根据我上面的现象,我感觉是进入中断处理函数了,让b_sys_enter_stop_mode =1,所以才导致又进入休眠了。
    于是在进入休眠时改成:
           if(b_sys_enter_stop_mode )
          {
                 b_sys_enter_stop_mode = 0;
                 Sys_Sleep();
               
                  Sys_WakeUp();        
                delay_ms(1000);
       }
       现象还是一样。
       于是我再改成:
        if(b_sys_enter_stop_mode )
       {
               b_sys_enter_stop_mode = 0;
                Sys_Sleep();

               Sys_WakeUp();        
               while(1)
              {               
                   DataToDspBuf(tick_for_sys_dida,0);
                   DspLcd3();
             }
       }
       有时能进入休眠,现象是显示的AD值不变,定时器数值也不变,但有时似乎冲过去了,能看到执行了while(1)里面的函数。
       如果是进入了休眠,再次按下PA1(EXTI1),程序就进到while(1)里面执行了,也没有再进STOP模式,这样是比较符合期望的。

       接着修改:
       if(b_sys_enter_stop_mode )
       {
               b_sys_enter_stop_mode = 0;
               Sys_Sleep();

               PA1_Interrupt_Config(DISABLE);
               Sys_WakeUp();        
       }   
       现象是:按下PA1(EXTI1),芯片进入stop模式,但再按PA1,就唤不醒了,我的程序是唤醒之后才禁止中断,似乎程序又冲过了一样,搞不明白。

      其实我想到了用独立看门狗IWDG,修改代码如下:
      if(b_sys_enter_stop_mode )
      {
            b_sys_enter_stop_mode = 0;
            Sys_Sleep();

            Sys_WakeUp();        
                IWdog_Init();
            while(1);
       }

      我的独立看门狗是1s,这样按下PA1(EXTI1),进入休眠,再次按下PA1(EXTI1),马上看门狗就导致系统复位了,我的项目这么做也可以,
      只是还搞不清楚外部中断唤醒到底问题出在哪里?还请高手指点一二。。。




收藏 评论25 发布时间:2015-6-4 10:43

举报

25个回答
阳阳NO1 回答时间:2015-6-5 09:53:21
creep 发表于 2015-6-5 09:07
我想了下你说的这个长按按键会导致唤醒后再次进入休眠模式的可能性确实是存在的,但是比较可惜的是我在这 ...

你的这种办法我昨晚上也想到了,我还做了实验,效果很差:
QQ图片20150605094052.png

我甚至修改按键扫描,添加了松手检测,只有在手松开的时候,才去返回KEY_PRESS;
U8 Key_Scan(void)
{
    if(g_KeyRelease && (!KEY_USER_STA)) /*表示有按键按下*/
    {
        delay_ms(10);
        if(!KEY_USER_STA)
                {
                          while(!KEY_USER_STA);
                          g_KeyRelease = ENABLE;
                          return  KEY_PRESS;
                }
                                       
    }
        else if(KEY_USER_STA)               
             g_KeyRelease = ENABLE;
        return 0;
}
现象如下:

QQ图片20150605094313.png
而且一出现这样的情况,按键就失去左右了,再也唤不醒芯片了。
说实话,我真的有点想不通了,将测试工程上传至附件,希望得到高人指点
file:///C:\Users\Administrator\AppData\Roaming\Tencent\Users\413351855\QQ\WinTemp\RichOle\}DN2_P0I$BQ97$Z7R05F}IL.png


测试进入stop模式.rar

下载

7.23 MB, 下载次数: 41, 下载积分: ST金币 -1

阳阳NO1 回答时间:2015-6-4 13:25:52
creep 发表于 2015-6-4 11:13
我的这个帖子对你的这2个疑问进行了解答,你先看看,不明白我们再讨论。
【STM32F303开发】+ RTC闹钟中断唤 ...

file:///C:\Users\Administrator\AppData\Roaming\Tencent\Users\413351855\QQ\WinTemp\RichOle\@OK(QES952K`Q%N$SSOD$39.png
程序唤醒后从先进入唤醒的外部中断,然后执行进入STOP休眠的下一条代码。
如果是这样的话,我在程序里面价格状态判断应该就没问题了,在外部中断里面修改成如下:
        else if(EXTI_GetITStatus(EXTI_Line1)!= RESET )
        {                            
                EXTI_ClearITPendingBit(EXTI_Line1);
               if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_1)==0)
              {
                     if(mcu_state == MCU_IS_RUNNING)
                        b_sys_enter_stop_mode = 1;
     }
QQ图片20150604131918.png

很是奇怪,仿真的时候,程序执行玩sys_sleep()之后,直接执行sys_WakeUp()了,
怎么芯片执行    PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
并不进入stop模式。

creep 回答时间:2015-6-5 09:07:28
阳阳NO1 发表于 2015-6-4 23:40
我的硬件就一个上拉电阻,配置我上拉下拉都改过,无济于事,那我明天换个按键试试。
但是从道理上讲,是 ...

我想了下你说的这个长按按键会导致唤醒后再次进入休眠模式的可能性确实是存在的,但是比较可惜的是我在这个开发板怎么也测试不到这种情况的发生,无论是长按还是短按程序都能正常工作。为了避免你i说的那个情况的发生可以修改下按键中断代码如下,加上按键的按下使能标志。你再测试下在你的板子上是否能正常工作。
  1. void EXTI15_10_IRQHandler(void)
  2. {
  3.     if(EXTI_GetITStatus(EXTI_Line13) != RESET)
  4.     {
  5.         SYSCLKConfig_STOP();
  6.         g_keyWorkMode = IO_MODE;
  7.         KEY_CheckMode(IO_MODE);
  8.         g_KeyRelease = DISABLE;
  9.         printf("\n\r-----按键中断唤醒MCU--------\n\r\n\r");
  10.         EXTI_ClearITPendingBit(EXTI_Line13);
  11.     }
  12. }
复制代码
creep 回答时间:2015-6-4 11:13:12
我的这个帖子对你的这2个疑问进行了解答,你先看看,不明白我们再讨论。
【STM32F303开发】+ RTC闹钟中断唤醒STOP模式休眠
阳阳NO1 回答时间:2015-6-4 13:28:37
阳阳NO1 发表于 2015-6-4 13:25
程序唤醒后从先进入唤醒的外部中断,然后执行进入STOP休眠的下一条代码。
如果是这样的话,我在程序里面 ...

方便加下QQ吗,413351855,这样沟通起来更快
你好我好大家好! 回答时间:2015-6-4 15:55:18
不是太明白啊
阳阳NO1 回答时间:2015-6-4 16:24:28

什么不是太明白?
废鱼 回答时间:2015-6-4 16:55:31
STOP以后,是从STOP后面继续执行。如果是在线仿真需要设置开启休眠功能。
creep 回答时间:2015-6-4 17:02:13
阳阳NO1 发表于 2015-6-4 13:25
程序唤醒后从先进入唤醒的外部中断,然后执行进入STOP休眠的下一条代码。
如果是这样的话,我在程序里面 ...

休眠模式下在线调试可能不太准确,你尽量将程序的运行信息打印出来(比如到串口或者USB),这样能很清楚的看到到底程序是怎么运行的。
一会有空我在F303RE的这个NUCLEO开发板上写个按键中断触发和唤醒STOP的测试程序。
creep 回答时间:2015-6-4 20:32:53
阳阳NO1 发表于 2015-6-4 13:28
方便加下QQ吗,413351855,这样沟通起来更快

不知道你有没有这个STM32F303RE开发板,你测试下我写的这个按键进入和唤醒STOP的程序
【STM32F303开发】+按键中断唤醒STOP模式
阳阳NO1 回答时间:2015-6-4 20:37:14
creep 发表于 2015-6-4 20:32
不知道你有没有这个STM32F303RE开发板,你测试下我写的这个按键进入和唤醒STOP的程序
【STM32F303开发】+ ...

我没有这个开发板,我改改管脚,在我的板子上试下吧
creep 回答时间:2015-6-4 21:29:25
阳阳NO1 发表于 2015-6-4 20:37
我没有这个开发板,我改改管脚,在我的板子上试下吧

如果还不行的话,去掉你其他的外设代码,只保留按键测试部分。和我的那个测试程序那样把运行信息打印出来或者用LED指示运行状态,休眠模式下调试可能不太准确。
阳阳NO1 回答时间:2015-6-4 21:51:01
creep 发表于 2015-6-4 20:32
不知道你有没有这个STM32F303RE开发板,你测试下我写的这个按键进入和唤醒STOP的程序
【STM32F303开发】+ ...

按照你的程序将自己的程序修改了下,现在的情况是按下去有时进不去stop模式,但只要进到stop模式,唤醒还是很正常的。。。继续查找问题
creep 回答时间:2015-6-4 21:55:31
阳阳NO1 发表于 2015-6-4 21:51
按照你的程序将自己的程序修改了下,现在的情况是按下去有时进不去stop模式,但只要进到stop模式,唤醒还 ...

那个测试程序在F303RE开发板上每次按键都能进入休眠模式每次也都能唤醒休眠模式。
如果一直找不到原因,你可以考虑下是不是其他的外设模块影响的或者硬件有些问题,因为实现这个功能不是很难做,原理和程序都很简单。
阳阳NO1 回答时间:2015-6-4 22:13:43
creep 发表于 2015-6-4 21:55
那个测试程序在F303RE开发板上每次按键都能进入休眠模式每次也都能唤醒休眠模式。
如果一直找不到原因, ...

是啊,原理确实不难,我已将其它的程序都删除了,但还是一样的效果,很可惜的是我的板子上串口没印出来,暂时只能仿真,如果是仿真的话,每次都能进入stop模式,因为进入stop模式之后,j-link就断开了,哎,真实奇怪呢。。。
creep 回答时间:2015-6-4 22:24:06
阳阳NO1 发表于 2015-6-4 22:13
是啊,原理确实不难,我已将其它的程序都删除了,但还是一样的效果,很可惜的是我的板子上串口没印出来, ...

如果能把jlink驱动升级到V4.90e版本以上,可以使用jlink的Jlink RTT client或者Jlink RTT logger 输出打印信息。
升级驱动前请确认jlink固件已经最新,否则可能会导致jlink没法使用。
12下一页

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版