请教STM32F030之低功耗模式的串口唤醒

2019-07-21 01:19发布

本帖最后由 C919WAY 于 2019-5-16 14:45 编辑

经过查阅资料,STM32F030在低功耗STOP模式下用串口唤醒,须将串口接收引脚PA10先设置成普通管脚,用管脚中断唤醒,唤醒单片机后,再设置时钟和串口配置,再进行串口通信,于是小弟写了如下代码:主函数:
#include "stm32f0xx.h"
#include  "led.h"
#include  "exit.h"
#include  "uart.h"
unsigned int i0=1;
unsigned int tmp;
unsigned int CommandFromPc[7];
unsigned int ADD;
unsigned int keyflag=0;
unsigned int downswitchflag=0;
unsigned int upwaterflag=0;
unsigned int RXD_OK_flag=0;
unsigned int AnswerData[7];
unsigned int RXD_flag;
int main(void)
{
        SystemInit();
        LED_Init();
  LED_Init1();
        AnswerData[1]=0XED;                        //**μ±Ç°½úμãoÅ****//
  AnswerData[2]=0X27;             //**é趨½Ç¶èÖμ****//
  AnswerData[3]=0X10;             //**é趨½Ç¶èÖμ****//
        AnswerData[4]=0XEA;             //**é趨½Ç¶èÖμ****//
        EXIT_KEY_Init();
  SYSTEM_PWR();
        while(1)
        {
                if(RXD_flag==1)
                {
                         RXD_flag=0;               
                         SystemInit();
                         USART_Configuration();
                }
                if(RXD_OK_flag==1)
                {
                         RXD_OK_flag=0;
                         USART_SendData(USART1,AnswerData[1]);
                         while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
                         USART_SendData(USART1,AnswerData[2]);
                         while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
                         USART_SendData(USART1,AnswerData[3]);
                         while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
                         USART_SendData(USART1,AnswerData[4]);
                         while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
                         GPIO_ResetBits(GPIOA, GPIO_Pin_3);
                         GPIO_SetBits(GPIOA, GPIO_Pin_4);
                         SYSTEM_PWR();
                }
        }
}



串口通信配置C文件:
#include "uart.h"
#include <stdio.h>

extern unsigned int i0;
extern unsigned int tmp;
extern unsigned int CommandFromPc[7];
extern unsigned int ADD;
extern unsigned int RXD_OK_flag;
extern unsigned int AnswerData[7];
void USART_Configuration(void)//′&#174;&#191;ú3&#245;ê&#188;&#187;ˉoˉêy
{  

        GPIO_InitTypeDef  GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
                    NVIC_InitTypeDef    NVIC_InitStructure;

        RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE );

        GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1);
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1);        

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;                 
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);        

        USART_InitStructure.USART_BaudRate = 9600;//éè&#214;&#195;′&#174;&#191;ú2¨ì&#216;&#194;ê
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;//éè&#214;&#195;êy&#190;Y&#206;&#187;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;//éè&#214;&#195;í£&#214;1&#206;&#187;
        USART_InitStructure.USART_Parity = USART_Parity_No;//éè&#214;&#195;D§&#209;é&#206;&#187;
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//éè&#214;&#195;á÷&#191;&#216;&#214;&#198;
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//éè&#214;&#195;1¤×÷&#196;£ê&#189;
        USART_Init(USART1, &USART_InitStructure); //&#197;&#228;&#214;&#195;è&#235;&#189;á11ì&#229;

                                USART_ClearFlag(USART1,USART_FLAG_TC);

        USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
        USART_Cmd(USART1,ENABLE);      
                                
                                NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);     
}                        
void USART1_IRQHandler(void)                        //??1??????
{
        
  unsigned int m;
        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //????(?????????0x0d 0x0a??)
        {
                USART_ClearITPendingBit(USART1,USART_IT_RXNE);
                tmp=USART_ReceiveData(USART1);//(USART1->DR);        //????????
                switch(i0)
    {
         case 0x01 : //???
           if(tmp==0xED)
              {                                  //**?????****//
                 CommandFromPc[i0]=tmp;          //**????******//
                 i0++;
              }
           else
              {  i0=1;  }                        //**??????**//
         break ;      
         case 0x02 :
            if(tmp==0x27)
              {                                  //**?????****//
                 CommandFromPc[i0]=tmp;          //**????******//
                 i0++;
              }
           else
              {  i0=1;  }
         break ;

         case 0x03 :
                           for(m=1;m<3;m++)
                                  {  ADD=ADD+CommandFromPc[m]; }
                           ADD=ADD&0XFF;   
                           if(tmp==ADD)
                                 {                                  //**?????****//
                                         CommandFromPc[i0]=tmp;          //**????******//
                                         i0++;
                                 }
                           else
                                 {  i0=1;  
                              ADD=0;
                     }                 
         break;               
                                          
         case 0x04 :                        
                           if(tmp==0xEA)
                           {
                                  CommandFromPc[i0]=tmp;                //**??????**//
                                  RXD_OK_flag=1;                   //**??????**//
                                        ADD=0;
                                  i0=1;
                           }
         else
         {
           i0=1;
                       ADD=0;
                     }
         break ;  
         default:               
          i0=1;
                      ADD=0;
      }
               
     }

}



中断配置C文件:
#include "exit.h"

extern unsigned int keyflag;
extern unsigned int downswitchflag;
extern unsigned int RXD_flag;

void EXIT_UART_Init(void)
{
        GPIO_InitTypeDef   GPIO_InitStructure;
  NVIC_InitTypeDef   NVIC_InitStructure;
        EXTI_InitTypeDef EXTI_InitStruct;

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//????
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

        NVIC_InitStructure.NVIC_IRQChannel = EXTI4_15_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPriority = 0x00;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);

        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource10);
        EXTI_InitStruct.EXTI_Line = EXTI_Line10;
        EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising; //?????
        EXTI_InitStruct.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_InitStruct);
}
void EXTI4_15_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line10) != RESET)
  {
    EXTI_ClearITPendingBit(EXTI_Line10);
          RXD_flag=1;
  }
}
void SYSTEM_PWR(void)
{
         GPIO_InitTypeDef GPIO_InitStruct;
        
         GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_13|GPIO_Pin_14;
         GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
   GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; // é&#207;à-ê&#228;è&#235;
         GPIO_Init(GPIOA, &GPIO_InitStruct);
        
         GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
         GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
   GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; // é&#207;à-ê&#228;è&#235;
         GPIO_Init(GPIOB, &GPIO_InitStruct);
         
         EXIT_UART_Init();
         EXTI_ClearITPendingBit(0xFFFFFFFF);
         
         RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR , ENABLE);
         PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);
}

实际编译后编译器报错:.key_init.axf: Error: L6200E: Symbol EXTI4_15_IRQHandler multiply defined (by exit.o and stm32f0xx_it.o).
小弟自查是同一管脚中断重复配置,实际上是PA10配置两次中断:
void EXTI4_15_IRQHandler(void)
{
  if(EXTI_GetITStatus(EXTI_Line10) != RESET)
  {
    EXTI_ClearITPendingBit(EXTI_Line10);
          RXD_flag=1;
  }
}

void USART1_IRQHandler(void)                        //??1??????
{
        
  unsigned int m;
        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //????(?????????0x0d 0x0a??)
        {
                USART_ClearITPendingBit(USART1,USART_IT_RXNE);
                tmp=USART_ReceiveData(USART1);//(USART1->DR);        //????????
                switch(i0)
    {
         case 0x01 : //???
           if(tmp==0xED)
              {                                  //**?????****//
                 CommandFromPc[i0]=tmp;          //**????******//
                 i0++;
              }
           else
              {  i0=1;  }                        //**??????**//
         break ;      
         case 0x02 :
            if(tmp==0x27)
              {                                  //**?????****//
                 CommandFromPc[i0]=tmp;          //**????******//
                 i0++;
              }
           else
              {  i0=1;  }
         break ;

         case 0x03 :
                           for(m=1;m<3;m++)
                                  {  ADD=ADD+CommandFromPc[m]; }
                           ADD=ADD&0XFF;   
                           if(tmp==ADD)
                                 {                                  //**?????****//
                                         CommandFromPc[i0]=tmp;          //**????******//
                                         i0++;
                                 }
                           else
                                 {  i0=1;  
                              ADD=0;
                     }                 
         break;               
                                          
         case 0x04 :                        
                           if(tmp==0xEA)
                           {
                                  CommandFromPc[i0]=tmp;                //**??????**//
                                  RXD_OK_flag=1;                   //**??????**//
                                        ADD=0;
                                  i0=1;
                           }
         else
         {
           i0=1;
                       ADD=0;
                     }
         break ;  
         default:               
          i0=1;
                      ADD=0;
      }
               
     }

}
代码见附件
请教大家,如果同一管脚需要先后使用两种中断,怎么写代码呢?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
1条回答
C919WAY
1楼-- · 2019-07-21 03:44

代码已经搞定,确实如大师所说,是中断被重复定义了两次,起初我以为是同一个管脚不能被定义两种中断,最后发现是清风的下载的STM32F030的模板里stm32f0xx_it.c文件中,重复定义了EXTI4_15_IRQHandler()函数,去掉之后就好了,我真是太弱鸡了,还是要感谢大师指点,无奈小弟悟性太差了,基础差,所以没闹明白

一周热门 更多>