搜索
bottom↓
回复: 2

状态机串口接收中断,switch&case语句,break后无法直接跳出?

[复制链接]

出0入0汤圆

发表于 2014-10-26 17:47:27 | 显示全部楼层 |阅读模式
写了个状态机接收中断的程序。 但是在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[USART_Rx_ptr_in++]=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;
                 }
                                                       
                                       
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入4汤圆

发表于 2014-10-26 18:41:02 | 显示全部楼层
先不管问题在哪,先改成这样再试试:

   case  xx:
   {
        .......
        break;
   }

出0入54汤圆

发表于 2014-10-26 18:53:00 | 显示全部楼层
应该是优化问题,因为所有的break都是做的同一件事,就是goto xxx
所以你在调试的时候可能就跑到那个break了。没问题的。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 03:44

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表