本帖最后由 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)//′®¿ú3õê¼»ˉ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;//éèÖÃ′®¿ú2¨ìØÂê
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//éèÖÃêy¾Yλ
USART_InitStructure.USART_StopBits = USART_StopBits_1;//éèÖÃí£Ö1λ
USART_InitStructure.USART_Parity = USART_Parity_No;//éèÖÃD§Ñéλ
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//éèÖÃá÷¿ØÖÆ
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//éèÖÃ1¤×÷Ä£ê½
USART_Init(USART1, &USART_InitStructure); //ÅäÖÃèë½á11ìå
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; // éÏà-êäèë
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; // éÏà-êäèë
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;
}
}
}
代码见附件
请教大家,如果同一管脚需要先后使用两种中断,怎么写代码呢?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
代码已经搞定,确实如大师所说,是中断被重复定义了两次,起初我以为是同一个管脚不能被定义两种中断,最后发现是清风的下载的STM32F030的模板里stm32f0xx_it.c文件中,重复定义了EXTI4_15_IRQHandler()函数,去掉之后就好了,我真是太弱鸡了,还是要感谢大师指点,无奈小弟悟性太差了,基础差,所以没闹明白
一周热门 更多>