各位大神,最近做项目遇到一问题,如下:功能要求:串口要接收大量数据,用于绘图;使用串口屏绘图,每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,正常。求救!!!!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
使用串口5发数据的,因为在主函数的while循环中要进行键盘检测,有较长延时,不能完成实时绘图工作,所以只能用定时器。把定时器间隔改成100ms就没问题了,但不能满足要求。
原子哥,我的是,就是串口发送与接收都有,请问如何解决像楼主这样的问题呢?
1,尽量提高串口波特率。
2,尽量使用DMA接收。
一周热门 更多>