跪求各位大神指教,我在调试STM32F429+uCOSIII多串口数据处理任务的时候,出现了数据丢失现象。
我使用了五个串口中断,USART1、USART6、USART3、UART7、USART2(模拟时钟),使用串口调试助手模拟设备发送串口数据。
在main函数中设置了4个任务来获取前四路串口的数据,并使用USART2的数据打上时间戳,然后使用FATFS将数据保存到TF卡上
当我设置自动发送周期一样的时候(比如都是500ms),数据完整无丢失。
但是如果有一个发送周期不一致,比如250ms或1000ms,则会出现数据无故多一位或少一些的情况:
比如 我让四个串口发送1.111,2.222,3.333,让USART2发送2017.3.31,12:34:56
则会出现:
22017.3.31,12:34:56,1.111,2.222,3.333
或者
2017.3.31,12:34:56,11.111,2.222,3.333
甚至前面的时间戳丢失一大部分数据
请教各位大神,是任务设置的问题,还是任务调度的问题,还是串口中断优先级的问题呢。
程序由于仓促没贴上,下午贴上。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
#define START_TASK_PRIO 3
//任务堆栈大小
#define START_STK_SIZE 128
//任务控制块
OS_TCB StartTaskTCB;
//任务堆栈
CPU_STK START_TASK_STK[START_STK_SIZE];
//任务函数
void start_task(void *p_arg);
//任务优先级
#define CAN_TASK_PRIO 4
//任务堆栈大小
#define CAN_STK_SIZE 128
//任务控制块
OS_TCB CAN_TaskTCB;
//任务堆栈
CPU_STK CAN_TASK_STK[CAN_STK_SIZE];
void Can_task(void *p_arg);
//任务优先级
#define TIME_TASK_PRIO 9
//任务堆栈大小
#define TIME_STK_SIZE 1024
//任务控制块
OS_TCB TIME_TaskTCB;
//任务堆栈
CPU_STK TIME_TASK_STK[TIME_STK_SIZE];
void Time_task(void *p_arg);
//任务优先级
#define COM1_TASK_PRIO 7
//任务堆栈大小
#define COM1_STK_SIZE 1024
//任务控制块
OS_TCB COM1_TaskTCB;
//任务堆栈
CPU_STK COM1_TASK_STK[COM1_STK_SIZE];
void Com1_task(void *p_arg);
//任务优先级
#define COM6_TASK_PRIO 8
//任务堆栈大小
#define COM6_STK_SIZE 1024
//任务控制块
OS_TCB COM6_TaskTCB;
//任务堆栈
CPU_STK COM6_TASK_STK[COM6_STK_SIZE];
//任务函数
void Com6_task(void *p_arg);
//任务优先级
#define COM3_TASK_PRIO 5
//任务堆栈大小
#define COM3_STK_SIZE 1024
//任务控制块
OS_TCB COM3_TaskTCB;
//任务堆栈
CPU_STK COM3_TASK_STK[COM3_STK_SIZE];
//任务函数
void Com3_task(void *p_arg);
//任务优先级
#define COM7_TASK_PRIO 6
//任务堆栈大小
#define COM7_STK_SIZE 1024
//任务控制块
OS_TCB COM7_TaskTCB;
//任务堆栈
CPU_STK COM7_TASK_STK[COM7_STK_SIZE];
//任务函数
void Com7_task(void *p_arg);
这是串口数据处理任务:(只写了一个)
void Com1_task(void *p_arg)
{
CPU_SR_ALLOC();
OS_ERR err;
OS_MSG_SIZE size;
u8 * msg1;
p_arg = p_arg;
printf("Run COM1 ");
while(1)
{
msg1=OSTaskQPend((OS_TICK )500,
(OS_OPT )OS_OPT_PEND_BLOCKING,
(OS_MSG_SIZE* )&size,
(CPU_TS* )0,
(OS_ERR* )&err);
sprintf(u1data,"UART1:%s,%s",timedata,msg1);
printf("%s",u1data);
// res_sd = f_lseek(&file1,f_size(&file1));
// do
// {
// res_sd = f_write(&file1,u1data,strlen(u1data),&fnum);
// }
// while(fnum<strlen(u1data));
// f_sync(&file1);
OSTimeDlyHMSM(0,0,0,500,OS_OPT_TIME_HMSM_STRICT,&err); //延时ms
}
}
这是其中相对应的串口中断:
void USART1_IRQHandler(void)
{
u8 Res;
// unsigned int i;
OS_ERR err;
// CPU_SR_ALLOC();
OSIntEnter();
if((__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_RXNE)!=RESET))
{
HAL_UART_Receive(&UART1_Handler,&Res,1,1000);
if((Res!=0x0d)&&(Res!=0x0a))
{
USART1_RX_BUF[USART1_RX_STA]=Res;
USART1_RX_STA++;
}
else if(Res==0x0d)
{
USART1_RX_BUF[USART1_RX_STA]=0x0d;
USART1_RX_BUF[USART1_RX_STA+1]=0x0a;
USART1_RX_BUF[USART1_RX_STA+2]=' ';
OSTaskQPost((OS_TCB* )&COM1_TaskTCB,
(void* )&USART1_RX_BUF,
(OS_MSG_SIZE)sizeof(USART1_RX_BUF),
(OS_OPT )OS_OPT_POST_FIFO,
(OS_ERR* )&err);
USART1_RX_STA=0;
}
else
{
USART1_RX_STA=0;
}
if(USART1_RX_STA>(USART_REC_LEN-1))USART1_RX_STA=0;
}
HAL_UART_IRQHandler(&UART1_Handler);
OSIntExit();
}
您的意思是串口DMA方式接收么
一周热门 更多>