该文章是针对于串口通讯过程中快速定义命令而写的,算是我自己的一个通用化的平台,专门用来进行串口调试用,莫要取笑
要处理串口数据首先是要对单片机的串口中断进行处理,我的方法是正确的命令必须要在命令的结尾处同时带有回车和换行,处理过程如下
//串口接收缓冲区
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 == 'n')serial_Buffer_Length |= 0x8000;
else
{
//一帧接受失败
serial_Buffer_Length = 0;
}
}
else
{
if((serial_Buffer_Length&0xff) < SERIAL_MAX_LENGTH)
{
if(ch == 'r')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 commandrn");
}
}
else
{
printf("command can't all spacern");
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] = '