yanse1214 发表于 2014-10-26 17:47:27

状态机串口接收中断,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;
               }
                                                       
                                       
}

sunliezhi 发表于 2014-10-26 18:41:02

先不管问题在哪,先改成这样再试试:

   casexx:
   {
      .......
      break;
   }

lusson 发表于 2014-10-26 18:53:00

应该是优化问题,因为所有的break都是做的同一件事,就是goto xxx
所以你在调试的时候可能就跑到那个break了。没问题的。
页: [1]
查看完整版本: 状态机串口接收中断,switch&case语句,break后无法直接跳出?