以单片机N32G435为例,串口通信为GPS,配合定时器2接收一包数据。
通过在串口接收中断中不断更新定时器2的计数值,直到定时器2中断溢出(一般定时10ms),表示一包数据接收完成。
在调试过程中,发现接收中断只进了一次,一个字符串只接收到了一个字符,在网上查询后得出了几个解决办法,如下:
- 中断程序占用时间过长,导致后面的数据到达的时候无法接收。
- 中断清除标志位。
- 串口中断优先级太低,导致中断嵌套。将优先级设为最高。
本人中断函数中已添加中断清除,也提高了中断优先级,但并没有解决,后来发现将中断接收函数中的printf();函数删除,发现恢复正常,应该是printf();函数占用时间过长导致后面数据无法接到!!
下面将配置过程和处理部分做个笔记:
// 定时器2初始化配置
void TIM2_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitType TIM_TimeBaseInitStructure;
NVIC_InitType NVIC_InitStructure;
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM2,ENABLE); ///使能TIM2时钟
TIM_TimeBaseInitStructure.Period = arr; //自动重装载值
TIM_TimeBaseInitStructure.Prescaler=psc; //定时器分频
TIM_TimeBaseInitStructure.CntMode=TIM_CNT_MODE_UP; //向上计数模式
TIM_TimeBaseInitStructure.ClkDiv=TIM_CLK_DIV1;
TIM_InitTimeBase(TIM2,&TIM_TimeBaseInitStructure);//初始化TIM2
TIM_ConfigInt(TIM2,TIM_INT_UPDATE,ENABLE); //允许定时器3更新中断
TIM_Enable(TIM2,DISABLE); //先失能定时器3
NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn; //定时器3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ClrIntPendingBit(TIM2,TIM_INT_UPDATE); //清除中断标志位
}
// 定时器2中断函数处理
void TIM2_IRQHandler(void)
{
if(TIM_GetIntStatus(TIM2,TIM_INT_UPDATE)==SET) //溢出中断
{
Uart3DataNeedProcessFlag=1;//需要处理当前数据
TIM_Enable(TIM2,DISABLE);//停止定时器
TIM_ClrIntPendingBit(TIM2,TIM_INT_UPDATE); //清除中断标志位
}
}
//GPS-UART配置
void Uart3Init (void)
{
GPIO_InitType GPIO_InitStructure;
USART_InitType USART_InitStructure;
NVIC_InitType NVIC_InitStructure;
//开时钟
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB,ENABLE);
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_UART5,ENABLE);
//GPIO口配置
GPIO_InitStructure.Pin = GPIO_PIN_8 ; //
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Alternate = GPIO_AF6_UART5;
GPIO_InitPeripheral(GPIOB,&GPIO_InitStructure); //
GPIO_InitStructure.Pin = GPIO_PIN_9;
GPIO_InitStructure.GPIO_Pull = GPIO_Pull_Up;
GPIO_InitStructure.GPIO_Alternate = GPIO_AF6_UART5;
GPIO_InitPeripheral(GPIOB,&GPIO_InitStructure); //
//UART配置
USART_InitStructure.BaudRate = 9600;//串口波特率
USART_InitStructure.WordLength = USART_WL_8B;//字长为8位数据格式
USART_InitStructure.StopBits = USART_STPB_1;//一个停止位
USART_InitStructure.Parity = USART_PE_NO;//无奇偶校验位
USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;//无硬件数据流控制
USART_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX; //收发模式
USART_Init(UART5, &USART_InitStructure); //
//中断配置
NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2 ; //抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
USART_ConfigInt(UART5, USART_INT_RXDNE, ENABLE);
USART_Enable(UART5, ENABLE);
}
//中断函数处理,需要将此函数放到对应的中断函数中
void GPS_IRQHandler(void)
{
volatile u8 Res;
if(USART_GetIntStatus(UART5,USART_INT_RXDNE)!=RESET)
{
Res=USART_ReceiveData(UART5);
if(Uart3DataNeedProcessFlag==0)
{
if(Uart3ReceiveDataNum<=UART3_RECEIVE_MAX_NUM)
{
Uart3ReceiveData[Uart3ReceiveDataNum++] = Res;
TIM_ClrIntPendingBit(TIM2,TIM_INT_UPDATE);//清除定时器溢出中断
TIM_Enable(TIM2,ENABLE);//开始计时
TIM_SetCnt(TIM2,0);//复位定时器
}
else
{
Uart3ReceiveDataNum=0;
Uart3DataNeedProcessFlag=1;
}
}
}
}