wakojosin 发表于 2015-6-2 23:23:30

STM32F103停止模式唤醒异常,求助啦

本帖最后由 wakojosin 于 2015-6-3 16:28 编辑

现在对这个问题做一个小结吧,希望对遇到类似问题的朋友有点参考价值。如有什么不对或是不全的地方,希望大神能够指出,在此谢谢啦。
1.关于无法进入停机模式,单独运行却可以:目前的解决方法是当通过仿真器下载完程序之后,拔掉仿真器后运行就OK了,具体为什么会造成单独运行停机模式是可以的,加入其他程序就不行的原因还未知,但是这也算一个解决方法吧。
2.关于PA0的WKUP功能,从手册上看,WKUP功能是在待机模式下使用的,在停机模式下,现在的测试结果是无效,同时使能唤醒Pin功能之后对PA0的中断有影响,这个也就是造成了在进入停机模式之前,PA0的中断函数是能够进入的,但是进入停机模式之后却没有任何反应,因为在进入停机模式之前开启了WKUP功能。
3.关于USART2对PA0的影响,首先PA0的复用功能有USART_CTS,这是硬件流控制使用的,我在配置串口的时候未使用该功能,在程序测试中,USART2暂时还没有出现对唤醒功能有影响,或是PA0的设置对串口有影响的情况。

我在使用PA0中是将PA0配置成普通中断使用来唤醒停机模式的,为什么选PA0也是为了之后在待机模式上作兼容的考虑。仅供各位参考哈。

==============分=============割=============线===================

程序独立运行的时候没有问题,但是加入了串口,定时器等等,就出现问题了;其中定时器是开中断的,但是在进入停止模式之前停止了,并且做了定时器中断标志位的清除,如下:
TIM_Cmd(TIM2, DISABLE);
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
/* Enable PWR and BKP clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
PWR_WakeUpPinCmd(ENABLE);
PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);//进入停机模式
SYSCLKConfig();
/* TIM2 enable counter */
TIM_Cmd(TIM2, ENABLE);

程序运行之后直接跳过了停机模式,不知道为什么,看了和试了好多例子都不行,希望大神出来指点一下吧

今天用同样的程序竟然可以进停止模式了!!原因未知好郁闷。

使用PA0的WKUP功能需要作引脚映射吗?

main.c
#include "main.h"
#include "stdio.h"

void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;

/* 1 bit for pre-emption priority, 3 bits for subpriority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

/* Configure and enable SPI_MASTER interrupt -------------------------------
NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
      NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);*/
      /* Configure and enable TIM interrupt -------------------------------*/
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
      /* Configure and enable USART interrupt -------------------------------*/
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
      NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
      NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void WKUP_IOInit(void)
{
      GPIO_InitTypeDef GPIO_InitStructure;
      EXTI_InitTypeDef   EXTI_InitStructure;
      
      /* Enable GPIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
      
      /* Configure EXTI0 line */
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
      
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
      
/* Connect EXTI0 Line to PA.00 pin */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
}
void SYSCLKReConfig(void)
{
      ErrorStatus HSEStartUpStatus;
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);

/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp();

if(HSEStartUpStatus == SUCCESS)
{
    /* Enable PLL */
    RCC_PLLCmd(ENABLE);

    /* Wait till PLL is ready */
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {
    }

    /* Select PLL as system clock source */
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    /* Wait till PLL is used as system clock source */
    while(RCC_GetSYSCLKSource() != 0x08)
    {
    }
}
}
void Board_Init(void)
{
      NVIC_Configuration();
My_COM2_Init(9600);
      My_COM1_Init(2400);
      
      //My_ADC1_Init();//需要更换IO
      My_Delay_Init();
      TIM2_Init();
      LCD_Init();
      WKUP_IOInit();
      
      OLED_B_Init();
      delayMs(500);
      LLW_D_LoadData();
      delayMs(500);
      WIFI_Init();
}
uint8_t wifi_sed_s=0;
int main(void)
{
      char lcdstr;
      uint16_t gp2y10_data;
      uint8_t keyvalue;
      
      Board_Init();

      LCD_Fill(0x00);
      
while(1)
      {

                LCD_P12x24Str(0,2,"T:   H:%");
                LCD_P12x24Str(0,5,"PM2.5:");
                while(1)
                {
                        gp2y10_data=10;
                        while(gp2y10_data)
                        {
                              keyvalue=OLEDGUI_B_Read();
                              if(keyvalue==0XFF)
                              {
                                        delayMs(100);
                              }
                              else
                              {
                                        break;
                              }
                              gp2y10_data--;
                        }
                        if(keyvalue==0XFF)
                        {
                              if(DHT11_ReadData())
                              {
                                        sprintf(lcdstr,"T:%2d H:%2d%%",DHT11_Data,((DHT11_Data&0XF0)>>4)*16+(DHT11_Data&0X0F));
                                        sprintf(LLW_D_TVALUE,"%2d",DHT11_Data);
                                        sprintf(LLW_D_HVALUE,"%2d",DHT11_Data);
                                        LCD_P12x24Str(0,2,lcdstr);
                              }
                              /*if((gp2y10_data=GP2Y10_ReadData())!=0XFFFF)
                              {
                                        sprintf(LLW_D_PVALUE,"%3d",gp2y10_data);
                                        LCD_P12x24Str(72,5,LLW_D_PVALUE);
                              }*/
                              if(wifi_sed_s)
                              {
                                        wifi_sed_s=0;
                                        WIFI_D_Send();
                              }
                        }
                        else
                        {
                              break;
                        }
                        WIFI_EN(0);
                        LCD_Fill(0x00);
                        TIM_Cmd(TIM2, DISABLE);
                        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
                        delayMs(10);
                        /* Enable PWR and BKP clock */
                        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
                        PWR_WakeUpPinCmd(ENABLE);
                        PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);//进入停机模式
                        SYSCLKReConfig();
                        /* TIM2 enable counter */
                        TIM_Cmd(TIM2, ENABLE);
                        WIFI_EN(1);
                        delayMs(20);
                }
                //进入设置
                MenuGeneralSet();
      }
}


wakojosin 发表于 2015-6-3 16:01:05

本帖最后由 wakojosin 于 2015-6-3 16:06 编辑

安 发表于 2015-6-3 15:57
按照手册的说明是外部一个上升沿可以唤醒。进入这种STOP模式,外部只要是中断都能唤醒的。串口1对这个没影 ...
这个WKUP唤醒是在待机模式,手册上没有对停机模式有这个描述,是写了中断唤醒。现在的状态是,拔掉仿真器的线,全部OK,再次插上线之后也是正常进入停止模式,还有唤醒。所以这个又有还多需要学习研究的了。通过断开仿真器线后正常运行程序也解释了,昨天为什么不能进入待机模式和程序不能正常跑,而今天再次运行就可以了,可能是仿真器的状态影响着单片机的程序执行,所以出现了这种效果,详情还得好好学习学习才知道了。

发表于 2015-6-3 10:47:36

在线仿真的时候,是进去不了休眠模式的。要进入需要设置,休眠模式建议不要在线仿真。

发表于 2015-6-3 09:01:45

楼主用的是在线仿真吗?

wakojosin 发表于 2015-6-3 10:33:10

安 发表于 2015-6-3 09:01
楼主用的是在线仿真吗?

嗯嗯是的,用的stlink

wakojosin 发表于 2015-6-3 11:09:18

安 发表于 2015-6-3 10:47
在线仿真的时候,是进去不了休眠模式的。要进入需要设置,休眠模式建议不要在线仿真。 ...

可以的呀,在调试模式里面的低功耗模式调试支持有写可以的,只要配置一下就可以了,如果不配置,仿真会断开,而且在单独运行停止模式的时候也没有什么问题呢,就是加入了其他东西之后就不正常了。试了一下,不仿真,通过串口打印信息,也是没有达到进入低功耗的效果

你好我好大家好! 发表于 2015-6-3 12:51:24

帮顶了            

发表于 2015-6-3 14:06:53

楼主可否将整个工程上传一下?看不到其他的代码配置。

wakojosin 发表于 2015-6-3 14:34:40

安 发表于 2015-6-3 14:06
楼主可否将整个工程上传一下?看不到其他的代码配置。

main.c已经贴出来了,现在的问题是无法唤醒,用的PA0,有问题不明白,PA0中断唤醒跟其他外部中断唤醒有什么区别吗

发表于 2015-6-3 15:17:35

之前的唤醒,有没有考虑是串口中断引起的?
我这边测试PA0配置可以产生中断。楼主在运行模式下,PA0是否可以产生中断?

wakojosin 发表于 2015-6-3 15:36:49

安 发表于 2015-6-3 15:17
之前的唤醒,有没有考虑是串口中断引起的?
我这边测试PA0配置可以产生中断。楼主在运行模式下,PA0是否可 ...

独立运行是可以的,也是用串口2,串口1应该对PA0没有影响吧。目前中断是在while之外是可以进入的,但是进入之后也不好把握这个是否能够进入中断,因为很快就断开仿真了。没法看,在进入停止模式之前能不能进入中断函数,我再试试。关于PA0 它的复用功能有一个是WKUP,这个是指唤醒的IO吗?只是在待机模式跟其他IO有区别是吧,我从手册上理解是这样的,因为STOP模式所有EXTI都可以唤醒,但觉也就没啥区别了吧
页: [1] 2
查看完整版本: STM32F103停止模式唤醒异常,求助啦