初级会员

- 积分
- 54
- 金钱
- 54
- 注册时间
- 2019-5-29
- 在线时间
- 154 小时
|
现有系统对串口数据的处理方式如下,具体代码在最后面。
1、系统串口每隔100ms左右会收到50个BYTE的数据,目前是定义了一个200BYTE的全局数组usart_rxbuf和一个全局变量作为接收标志位rec_flag,每次串口有收到数据就会往里面存,并且标志位置2,在主任务较忙的情况下,最多可以缓存四块数据(每块数据50个BYTE,BYTE0如果等于0xff,则代表这一块50BYTE数据已经被处理过了,可以往里面存入有效数据)。
2、主任务在while循环里面不断判断rec_flag标志位,如果等于2,则把usart_rxbuf数据中有效的数据赋给内部缓存,并且把对应数据块的BYTE0给置成0xff,这样串口中断里面判断到0xff,就可以继续存入。之后就是对收到的串口数据进行处理。
3、主任务比较空闲的时候,基本上都是串口存入数据块1,然后主任务处理数据块1,串口存入数据块1.....依此流程循环下去
系统在跑了几万个循环后会无缘无故卡死了,系统完全停止,串口调试信息也不输出,也不是进入数组溢出等HardFault_Handler错误,目前比较怀疑是usart_rxbuf全局数组在两个任务里面都有读写,会不会是usart_rxbuf数组在主任务里面正在被读取,这时串口中断来了,又进入串口中断去读写usart_rxbuf全局数组,就导致系统无故卡死了。哪位大哥有什么办法可以处理掉这种同时读写的情况的,这样轻微改动后解决这个问题最好。
如果上面这种方式铁定不行,请问大伙在UCOS II系统中都是怎么处理串口接收到的数据的,有例程最好,谢谢!
/********************串口中断处理函数*******************************/
volatile u8 usart_rxbuf[200];
volatile u8 rec_flag=0;
volatile u8 USART2_RX_BUF[100]; //接收缓冲
void USART2_IRQHandler(void)
{
u8 res;
u8 i=0,j=0;
u8 temp=0;
u16 crc_check=0;
OSIntEnter();
if(USART2->SR&(1<<5))//接收到数据
{
res=USART2->DR;
if((res==0xAA)&&(start_rev==0))
{
rev_num=0;
start_rev=1;
}
if(start_rev==1)
{
USART2_RX_BUF[rev_num]=res;
rev_num++;
if(rev_num>63)
{
if(USART2_RX_BUF[1]==0x55)
{
if(USART2_RX_BUF[3]==0x5C) //采集模块数据上报
{
crc_check=cal_crc(&USART2_RX_BUF[0],63);
temp=crc_check&0x00ff;
if(temp==USART2_RX_BUF[63]) //必须校验和正确 才会执行写入动作
{
rec_flag=2;
UART2_SEND(0xAA);
UART2_SEND(0x55);
UART2_SEND(0x02);
UART2_SEND(0x5D); //数据上报接收应答 在串口中断里面发送串口数据会不会也会导致系统卡死?
UART2_SEND(0xFF);
for(j=0;j<4;j++)
{
temp=j*50;
if(usart_rxbuf[temp]==0xff) //0xff代表本段没数据 可以存入
{
for(i=5;i<45;i++)
usart_rxbuf[4+i+temp]=USART2_RX_BUF;
usart_rxbuf[temp]=USART2_RX_BUF[52]; //点数
usart_rxbuf[temp+1]=USART2_RX_BUF[53];
usart_rxbuf[temp+2]=USART2_RX_BUF[45]; //周期
usart_rxbuf[temp+3]=USART2_RX_BUF[46];
usart_rxbuf[temp+4]=USART2_RX_BUF[47];
usart_rxbuf[temp+5]=USART2_RX_BUF[54]; //范围1~4
usart_rxbuf[temp+6]=USART2_RX_BUF[57]; //电池电量高位
usart_rxbuf[temp+7]=USART2_RX_BUF[58]; //电池电量低位
usart_rxbuf[temp+8]=USART2_RX_BUF[59];
break;
}
}
}
else
{
errtime+=1;
}
}
start_rev=0;
rev_num=0;
}
else
{
start_rev=0;
rev_num=0;
}
}
}
}
OSIntExit();
}
/************主任务程序*****************/
while(1)
{
if(rec_flag==2)
{
rec_flag=0;
for(i=0;i<4;i++)
{
temp=i*50;
if(usart_rxbuf[temp]!=0xff) //代表该位置存在数据
{
//INTX_DISABLE();
for(j=0;j<50;j++)
{
//usart_rxbuffer数组是while循环内部定义的局部变量
usart_rxbuffer[j]=usart_rxbuf[temp+j];
}
usart_rxbuf[temp]=0xff; //该条数据处理完成后第一个BYTE置FF 代表数据已处理过了
//INTX_ENABLE();
//后面是对收到的数据进行处理和显示
}
}
}
}
|
|