状态机串口接收中断,switch&case语句,break后无法直接跳出?
写了个状态机接收中断的程序。 但是在switch --case..语句中。 判断完 case 1 ,break后。老是先跳到 case21 的break.然后才会跳到末尾的default中。 为什么呢。 程序看了几遍。都不知道哪里错了。程序如下:
void USART_GetData()
{
u8 mychar=0;
mychar=USART1->DR;
switch(receiveState)
{
case 0: //
if(mychar==0x40)
{
receiveState=1;
ByteCount=0;
checksum=0;
}
else
{
receiveState=0;//状态机复位
}
break;
case 1: //设备地址头高4位
if(mychar==HexToAscii(SLAVE_ID>>4))
{
receiveState=2;
checksum^=mychar;
}
else
{
receiveState=0;//状态机复位
}
break;
case 2: //设备地址头低4位
if(mychar==HexToAscii(SLAVE_ID&0x0f))
{
receiveState=3;
checksum^=mychar;
}
else
{
receiveState=0;//状态机复位
}
break;
case 3:
if(mychar==0x41) //命令&标志
{
receiveState=4;
checksum^=mychar;
}
else
{
receiveState=0;
}
break;
case 4://到这个位置,读写分离
{
switch(mychar) //读命令
{ case 0x30:
receiveState=5;
checksum^=mychar;
//printf("\r\nthat is %x",mychar);
break;
case 0x31: //写命令
receiveState=14;
checksum^=mychar;
break;
default:
receiveState=0;
break;
}
}
break;
/*Read command*/
case 5://读命令30 数据地址
if(mychar==0x30)
{
receiveState=6;
checksum^=mychar;
//printf("\r\nthat is %x",mychar);
}
else
{
receiveState=0;
}
break;
case 6: //30
if(mychar==0x30)
{
receiveState=7;
checksum^=mychar;
//printf("\r\nthat is %x",checksum);
}
else
{
receiveState=0;
}
break;
case 7: //4 //from this ,dynamic & static
{
switch(mychar)
{ case 0x43:
receiveState=8;
checksum^=mychar;
g_cmd=1; //动态读标志
break;
case 0x44:
receiveState=11;
checksum^=mychar;
g_cmd=2;//静态读标志
break;
default:
receiveState=0;
break;
}
}
break;
/*A:DYNAMIC READ*/
case 8: //dynamic
if(mychar==0x30)//30动态读低4位
{
receiveState=9;
checksum^=mychar;
// printf("\r\nthat is %x",mychar);
}
else
{
receiveState=0;
}
break;
case 9://动态读数据长度判断高4位
if(mychar==0x31)
{
receiveState=10;
checksum^=mychar;
ByteCount=AsciiToHex(mychar);
// printf("\r\nthat is %x",mychar);
}
else
{
receiveState=0;
}
break;
case 10://动态读数据长度判断低4位
if(mychar==0x32)
{
receiveState=44;//转到校验判断程序
checksum^=mychar;
ByteCount<<=4;
ByteCount+=AsciiToHex(mychar);
}
else
{
receiveState=0;
}
break;
/*B:STATIC READ*/
case 11:
//static
if(mychar==0x32)//30静态读低4位
{
receiveState=12;
checksum^=mychar;
}
else
{
receiveState=0;
}
break;
case 12://静态读数据长度判断高4位
if(mychar==0x31)
{
receiveState=13;
checksum^=mychar;
ByteCount=AsciiToHex(mychar);
//printf("\r\nthat is %x",mychar);
}
else
{
receiveState=0;
}
break;
case 13://静态读数据长度判断低4位
if(mychar==0x30)
{
receiveState=44;//转到校验判断程序
checksum^=mychar;
ByteCount<<=4;
//printf("\r\nthat isfist %x",ByteCount);
ByteCount+=AsciiToHex(mychar);
// printf("\r\nthat is %x",checksum);OK
}
else
{
receiveState=0;
}
break;
/*Write command*/
case 14:
//写命令30 数据地址
if(mychar==0x30)
{
receiveState=15;
checksum^=mychar;
}
else
{
receiveState=0;
}
break;
case 15: //30
if(mychar==0x30)
{
receiveState=16;
checksum^=mychar;
// printf("\r\nthe eveis%x",checksum);OK
}
else
{
receiveState=0;
}
break;
case 16:
{
switch(mychar) //清零地址(累积量)
{
case 0x43:
receiveState=17;
checksum^=mychar;
g_cmd=4;//清零标志位
break;
case 0x44: //各个参数写地址
receiveState=21;
checksum^=mychar;
break;
case 0x45://测零功能调用地址
receiveState=40;
checksum^=mychar;
break;
default:
receiveState=0;
break;
}
}
break;
case 17:
if(mychar==0x45) //清零开始
{
receiveState=18;
checksum^=mychar;
}
else
{
receiveState=0;
}
break;
case 18://清零(累积量)的字节数,高4位
if(mychar==0x30)
{
receiveState=19;
checksum^=mychar;
ByteCount=AsciiToHex(mychar);
ByteCount<<=4;
}
else
{
receiveState=0;
}
break;
case 19://清零(累积量)的字节数,低4位
if(mychar==0x34)
{
receiveState=43;
checksum^=mychar;
ByteCount+=AsciiToHex(mychar);
//printf("\r\nthe clearsumis%x",checksum);//OK
}
else
{
receiveState=0;
}
break;
case 21://写参数各个系数数据地址末4位
{
switch(mychar)//写系数
{
case 0x32:
receiveState=22;
checksum^=mychar;
g_cmd=5;//系数标志位
break;
case 0x36: //写恒定速度
receiveState=25;
checksum^=mychar;
g_cmd=6; //速度标志位
break;
case 0x38: //写流量限值
receiveState=28;
checksum^=mychar;
g_cmd=7; //流量限值标志位
break;
case 0x41: //写零点
receiveState=31;
checksum^=mychar;
g_cmd=8;//静态零点标志位
break;
case 0x43: //写测零时间
receiveState=34;
checksum^=mychar;
g_cmd=9; //测零时间标志位
break;
case 0x45: //写空态界限
receiveState=37;
checksum^=mychar;
g_cmd=10;//空态界限标志位
break;
default:
receiveState=0;
break;
}
}
break; //程序老是先跳到了这里,然后再跳到末尾。 为什么呢? 哪里错了?
case 22://具体写系数的字节数长度高4位
if(mychar==0x30)
{
receiveState=23;
checksum^=mychar;
ByteCount=AsciiToHex(mychar);
ByteCount<<=4;
}
else
{
receiveState=0;
}
break;
case 23://写系数的字节数长度,低4位
if(mychar==0x34)
{
receiveState=43;
checksum^=mychar;
ByteCount+=AsciiToHex(mychar);
}
else
{
receiveState=0;
// printf("OK");
}
break;
case 25://具体写速度的字节数长度高4位
if(mychar==0x30)
{
receiveState=26;
checksum^=mychar;
ByteCount=AsciiToHex(mychar);
ByteCount<<=4;
}
else
{
receiveState=0;
}
break;
case 26://写速度的字节数长度,低4位
if(mychar==0x32)
{
receiveState=43;
checksum^=mychar;
ByteCount+=AsciiToHex(mychar);
}
else
{
receiveState=0;
}
break;
case 28://具体写流量限值的字节数长度高4位
if(mychar==0x30)
{
receiveState=29;
checksum^=mychar;
ByteCount=AsciiToHex(mychar);
ByteCount<<=4;
}
else
{
receiveState=0;
}
break;
case 29://写流量限值的字节数长度,低4位
if(mychar==0x32)
{
receiveState=43;
checksum^=mychar;
ByteCount+=AsciiToHex(mychar);
}
else
{
receiveState=0;
}
break;
case 31://具体写零点的字节数长度高4位
if(mychar==0x30)
{
receiveState=32;
checksum^=mychar;
ByteCount=AsciiToHex(mychar);
ByteCount<<=4;
}
else
{
receiveState=0;
}
break;
case 32://写零点的字节数长度,低4位
if(mychar==0x32)
{
receiveState=43;
checksum^=mychar;
ByteCount+=AsciiToHex(mychar);
}
else
{
receiveState=0;
}
break;
case 34:
//具体写测零时间的字节数长度高4位
if(mychar==0x30)
{
receiveState=35;
checksum^=mychar;
ByteCount=AsciiToHex(mychar);
ByteCount<<=4;
}
else
{
receiveState=0;
}
break;
case 35://写测零时间的字节数长度,低4位
if(mychar==0x32)
{
receiveState=43;
checksum^=mychar;
ByteCount+=AsciiToHex(mychar);
}
else
{
receiveState=0;
}
break;
case 37:
//具体写空态界限的字节数长度高4位
if(mychar==0x30)
{
receiveState=38;
checksum^=mychar;
ByteCount=AsciiToHex(mychar);
ByteCount<<=4;
}
else
{
receiveState=0;
}
break;
case 38://写空态界限的字节数长度,低4位
if(mychar==0x32)
{
//receiveState=39;
receiveState=43;
checksum^=mychar;
ByteCount+=AsciiToHex(mychar);
}
else
{
receiveState=0;
}
break;
/***************测零与CPU复位功能的调用*******************/
case 40:
if(mychar==0x30)
{
receiveState=41;
checksum^=mychar;
}
else
{
receiveState=0;
}
break;
//此处是为了增加测零与CPU复位功能的区别而修改
case 41://测零(累积量)的字节数,30 32
if(mychar==0x30)
{
receiveState=42;
checksum^=mychar;
}
else
{
receiveState=0;
}
break;
case 42://测零(累积量)的字节数,30 32
if(mychar==0x32)
{
receiveState=47;
checksum^=mychar;
}
else
{
receiveState=0;
}
break;
case 47:
if(mychar==0x30)
{
receiveState=48;
checksum^=mychar;
}
else
{
receiveState=0;
}
break;
case 48:
if(mychar==0x30)
{
receiveState=49;
checksum^=mychar;
}
else
{
receiveState=0;
}
break;
case 49:
if(mychar==0x30)
{
receiveState=50;
checksum^=mychar;
}
else
{
receiveState=0;
}
break;
case 50:
{
switch(mychar)//表明调用的是测零功能。
{
case 0x31:
g_cmd=3;//测零标志位
receiveState=44;
checksum^=mychar;
break;
case 0x32:
g_cmd=11;// cpu复位标志位
receiveState=44;
checksum^=mychar;
break;
default:
receiveState=0;
break;
}
}
break;
/**************数据接收端*******************/
case 43:
USART_Rx_Buffer=mychar;
checksum^=mychar;
if(USART_Rx_ptr_in==(ByteCount<<1))//当协议中,数据长度为定长时。
{
receiveState=44;
}
break;
/***********CRC&END*************************/
case 44: //动态读命令的异或校验值得比较
if((HexToAscii(checksum>>4))==mychar)//higt 4 bit
{
receiveState=45;
}
else
{
//Error();//
USART_Rx_Buffer_Clear();
receiveState=0;
}
break;
case 45: //动态读命令的异或校验值得比较
if((HexToAscii(checksum&0x0f))==mychar)//low 4 bit
{
receiveState=46;//下一步就是帧的结束位
}
else
{
//Error();
USART_Rx_Buffer_Clear();
receiveState=0;
}
break;
case 46:
if(mychar==0x0D)
{
Analyze_command();
}
USART_Rx_Buffer_Clear();
receiveState=0;
break;
default:
break;
}
} 先不管问题在哪,先改成这样再试试:
casexx:
{
.......
break;
} 应该是优化问题,因为所有的break都是做的同一件事,就是goto xxx
所以你在调试的时候可能就跑到那个break了。没问题的。
页:
[1]