linux系统定时器中断优先级,请教定时器中断与串口中断优先级配置问题

各位大神,最近做项目遇到一问题,如下:功能要求:串口要接收大量数据,用于绘图;使用串口屏绘图,每5ms刷新一次。

实现过程:使用TIM3,每5ms取一次数据,并发送一次绘图命令,优先级设置为抢占3,组内2;使能串口1接收中断(或DMA空闲中断),把数据放置在某缓冲区,优先级设置为最高(抢占0,组内0);中断优先级分组为2。

故障表现:定时器绘图正常,但串口接收大量数据丢失,把TIM3关掉,或者TIM3中断时间改成100ms,串口就能正常工作。貌似定时器优先级比串口优先级高,非常奇怪。

部分代码如下:

void USART1_Init(uint32_t baud)

{

USART_InitTypeDef USART1_InitStruct;

GPIO_InitTypeDef GPIO_InitStruct;

NVIC_InitTypeDef NVIC_InitStruct;

//enable clock

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE);

//reset usart1

USART_DeInit(USART1);

//init GPIO

//PA9 TX

GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;

GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;

GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_Init(GPIOA,&GPIO_InitStruct);

//PA10 RX

GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;

GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;

GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_Init(GPIOA,&GPIO_InitStruct);

//Init usart

USART1_InitStruct.USART_BaudRate=baud;

USART1_InitStruct.USART_WordLength=USART_WordLength_8b;

USART1_InitStruct.USART_StopBits=USART_StopBits_1;

USART1_InitStruct.USART_Parity=USART_Parity_No;

USART1_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;

USART1_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;

USART_Init(USART1,&USART1_InitStruct);

//init NVIC

NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;

NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;

NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;

NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;

NVIC_Init(&NVIC_InitStruct);

//enable rx interrupt

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);

//enable usart1

USART_Cmd(USART1,ENABLE);

}

void SendChar1(char ch)

{

USART_SendData(USART1,ch);

while(!USART_GetFlagStatus(USART1,USART_FLAG_TC));

USART_ClearFlag(USART1,USART_FLAG_TC);

}

void SendStr1(char *str)

{

while(*str)

{

SendChar(*str);

str++;

}

}

void USART1_IRQHandler(void)

{

if(USART1->CR1 & RXNEIE)

{

//receive first byte

*(usart1->buff+0)=USART1->DR;

SendChar1(*(usart1->buff+0));//直接转发

USART_ClearFlag(USART1,USART_IT_RXNE);

//定时器代码

void TIM3_Init(u16 arr,u16 psc)

{

NVIC_InitTypeDef NVIC_InitStruct;

TIM_TimeBaseInitTypeDef TIM_InitStruct;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

TIM_InitStruct.TIM_Period=arr;

TIM_InitStruct.TIM_Prescaler=psc;

TIM_InitStruct.TIM_ClockDivision=TIM_CKD_DIV1;

TIM_InitStruct.TIM_CounterMode=TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM3,&TIM_InitStruct);

TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);

NVIC_InitStruct.NVIC_IRQChannel=TIM3_IRQn;

NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;

NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0x03;

NVIC_InitStruct.NVIC_IRQChannelSubPriority=0x02;

NVIC_Init(&NVIC_InitStruct);

TIM_Cmd(TIM3,ENABLE);

}

void TIM3_IRQHandler(void)

{

if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)

{

TEST_LED_ON();

if(rt->Data_Length>0&&rt->ECG_Started==TRUE)

{

//set end point position

rt->EndPoint.x = ECG_START_DRAWING_POS_X + 1 + (u16)(ECG_SCALE_X*rt->time_Counter);

rt->EndPoint.y = ECG_DRAWING_BASELINE_Y +0x80- rt->pData[rt->Data_Index];

if(rt->EndPoint.x > ECG_END_DRAWING_POS_X)

{

rt->EndPoint.x=ECG_START_DRAWING_POS_X;

rt->time_Counter=0;

rt->StartPoint.x=ECG_START_DRAWING_POS_X;

rt->StartPoint.y=rt->EndPoint.y;

}

if(rt->StartPoint.x<455)

{

//draw line

DrawLine(&rt->StartPoint,&rt->EndPoint);

}

rt->StartPoint.x=rt->EndPoint.x;

rt->StartPoint.y=rt->EndPoint.y;

rt->time_Counter=(rt->time_Counter+1)%459;

//change ECG_Data index

rt->Data_Index=(rt->Data_Index+1)%rt->Data_Length;

}

TEST_LED_OFF();

}

TIM_ClearITPendingBit(TIM3,TIM_IT_Update);

}

初始化部分:

USART1_Init(9600);

TIM3_Init(49,7199);//5ms

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

用示波器看TIM3中断,脉宽5ms,正常。求救!!!!

我来回答

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值