该文章是针对于串口通讯过程中快速定义命令而写的,算是我自己的一个通用化的平台,专门用来进行串口调试用,莫要取笑
要处理串口数据首先是要对单片机的串口中断进行处理,我的方法是正确的命令必须要在命令的结尾处同时带有回车和换行,处理过程如下
//串口接收缓冲区 u8 serial_Buffer[SERIAL_MAX_LENGTH] = {0}; //串口接收数据长度 u16 serial_Buffer_Length = 0; static void SerialRecv(u8 ch) { if((serial_Buffer_Length&0x8000) == 0x8000)//已经接收完成,系统还没处理 { serial_Buffer_Length |= 0x8000;//退出 } else if((serial_Buffer_Length&0x4000) == 0x4000)//接收到回车还没接收到换行 { if(ch == ' ')serial_Buffer_Length |= 0x8000; else { //一帧接受失败 serial_Buffer_Length = 0; } } else { if((serial_Buffer_Length&0xff) < SERIAL_MAX_LENGTH) { if(ch == ' ')serial_Buffer_Length |= 0x4000; else { serial_Buffer[(serial_Buffer_Length&0xff)] = ch; serial_Buffer_Length++; } } else { //一帧接受失败 serial_Buffer_Length = 0; } } } void USART1_IRQHandler(void) { u8 ch = 0; if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)//检查中断发生 { ch = (u8)USART_ReceiveData(USART1); USART_ClearITPendingBit(USART1, USART_IT_RXNE); //清除中断 // Debug_Serial_Send_Char(ch); //将收到的数据发送出去 SerialRecv(ch); //处理中断数据 } }
这一帧数据接收到了之后就会阻塞串口,不再接受新数据,这时候我们就要定时的调用命令处理任务,将接收到的数据提取出来,如下
//扫描命令字符串,并调用相应处理函数 void CommandScan(void) { u8 commandLength1; u8 commandLength2; u8 i = 0,j = 0; //数据满 if((serial_Buffer_Length & 0x8000) == 0x8000) { //检测命令不是全为空格 if(Command_Is_Vailed()) { Command_Copy();//copy命令字符串等待处理 //去除命令头上的空白 Command_Remove_Space_Head(); //去除命令尾巴上的空格 Command_Remove_Space_End(); //去除中间的重复空格 Command_Remove_Space_Inner(); commandLength1 = Command_Find_Space_Postion(1);//获取长度 if(commandLength1 == 0)commandLength1 = commandStringLength;//当第二个空格获取返回0的时候,说明没有参数,纯命令,所以没有空格 for(i = 0; i < COMMAND_NUM; i++) { commandLength2 = StringGetLength(commandStringList[i]); if(commandLength1 == commandLength2) { //长度相同,比对每个字符 for(j = 0; j < commandLength1; j++) { if(commandStringBuffer[j] == commandStringList[i][j])continue; else break; } if(j == commandLength1)//比对成功 { //调用函数 Command_Proc_Func_Table[i](); return; } } else { //直接长度不同,不需要比对了 continue; } } if(i == COMMAND_NUM) { //没找到对应命令 printf("not find command "); } } else { printf("command can't all space "); serial_Buffer_Length = 0; } } }
先去除发送过来的数据头尾的空格,然后去除中间的空格,这样就能保证一定的数据纠错能力去除空白的代码段如下
//去除命令字符串的前面的空格字符 void Command_Remove_Space_Head(void) { u8 index = 0; u8 i = 0; for(index = 0; index < commandStringLength; index++) { if(commandStringBuffer[index] == ' ')continue; else break; } if(index == 0)//前面没有空格 { return; } else { //删除空格 for(i = 0; i < (commandStringLength-index);i++) { commandStringBuffer[i] = commandStringBuffer[index+i]; } commandStringLength -= index; } }
//去除命令字符串后面的空格 void Command_Remove_Space_End(void) { u8 i = 0; //寻找字符串最尾巴上空格的位置 for(i = commandStringLength; i > 0; i--) { if(commandStringBuffer[i-1] == ' ')continue;//如果这个是空格,继续下一次寻找 else break;//不是空格,到此为止 } if(i == commandStringLength)//尾上没有空格 { return; } else //尾上有空格 { commandStringBuffer[i] = '