这是一段 MSP430 单片机中处理 DTU 模块串口数据的代码,代码片段使用了 switch(__even_in_range(UCA1IV,4)) 语句来处理 UART 模块的中断。UCA1IV 是中断向量寄存器,用于指示 UART 中断的类型。

这段代码主要实现以下功能:

  1. 接收前导字: 程序首先判断是否接收到了前导字 '0xff' '0x55' '0xFD' '0xAA',如果没有,则重新接收;如果接收到了前导字,则开始接收正文。
  2. 接收正文: 程序会先接收数据长度,再接收一些其他参数,最后接收数据内容并进行校验。
  3. 校验数据: 程序会使用 DTU_Check_Code 函数校验接收到的数据,并将结果与接收到的校验码进行比较,以确保数据的完整性。
  4. 响应上位机命令: 如果接收到了完整的数据包,程序会调用 DTU_Rx_judge_save 函数来判断接收数据是否正确,并保存修改数据。最后,会调用 DTU_Communicate 函数来响应上位机命令。

代码解析如下:

 switch(__even_in_range(UCA1IV,4))
  {
        case 0:break;                             
        case 2:   
          DTU_Rx_Data = UCA1RXBUF;
               /*接收前导字  0xff*/
          if(DTU_Pre_Received == 0)
          {
		
if(DTU_Pre_Num==0&&DTU_Rx_Data == 0x55)
		{
			DTU_Pre_Num++;
		}
		else
		{
			if((DTU_Pre_Num==1)&&(DTU_Rx_Data == 0xFD))//2
			{
				DTU_Pre_Num++;
			}
                        else if((DTU_Pre_Num==2)&&(DTU_Rx_Data == 0xAA))
                        {
                                DTU_Pre_Received = 1;
                                DTU_Rx_Data_Count = 0;					
                        }
			else
			{
			  /*接收前导字失败 重新接收*/
				DTU_Pre_Num = 0;
				DTU_Pre_Received = 0;
				DTU_Rceive_OK = 0;
                return;
			}
		}
          }
       /*接收正文*/
          else
          {
            if(DTU_Rx_Data_Count==0)
            {
                int_temp=(unsigned int)DTU_Rx_Data;
                DTU_length=int_temp<<8;
                DTU_Rx_Data_Count++;
            }
            else if(DTU_Rx_Data_Count==1)
            {
                int_temp=(unsigned int)DTU_Rx_Data;
                DTU_length=DTU_length|int_temp;
                DTU_Rx_Data_Count++;
                DTU_Receive_CMD_Count=DTU_length-2;
            }
            else if(DTU_Rx_Data_Count==2)
            {
                DTU_Common_Para=DTU_Rx_Data;
                DTU_Rx_Data_Buffer[DTU_Rx_Data_Count-2]=DTU_Common_Para;
                DTU_Rx_Data_Count++;
                if(DTU_Common_Para!=0x61)
                {
                    DTU_Pre_Received=0;
                    DTU_Pre_Num = 0;
                    return;
                }                
            }
            else if(DTU_Rx_Data_Count==3)
            {
                DTU_Reserve_Para=DTU_Rx_Data; 
                DTU_Rx_Data_Buffer[DTU_Rx_Data_Count-2]=DTU_Reserve_Para;
                DTU_Rx_Data_Count++;
            }
            else
            {
                switch(DTU_Reserve_Para)
                {
                    case 0x01:  
                    case 0x02:
                    case 0x03:
                    case 0x04:
                    case 0x05:
                    case 0x06:
                    case 0x07:
                    case 0x08: 
                    case 0x09:  
                    case 0xDA:    

                      if(DTU_Rx_Data_Count < 4)
                      {
                          DTU_Pre_Received=0;
                          DTU_Pre_Num = 0;
                          return;
                      }
                      else
                      {
                          if(DTU_Rx_Data_Count<4+DTU_Receive_CMD_Count)
                          {
                              DTU_Rx_Data_Buffer[DTU_Rx_Data_Count-2] = DTU_Rx_Data;//所有接收数据入数组
                              DTU_Rx_Data_Count++;
                          }
                          else
                          {
                              DTU_Receive_CheckCode = DTU_Rx_Data;//保存校验位
                              DTU_Check_Result = DTU_Check_Code(DTU_Rx_Data_Buffer, DTU_Receive_CMD_Count+2);//先校验,再与PC发来的校验码校验,则结果是0
                              if(DTU_Check_Result!=DTU_Receive_CheckCode)
                              {DTU_Communication_Error=0x01;} 
                              else {DTU_Communication_Error=0x0;}
                              DTU_Rceive_OK = 1;
                              DTU_Rx_Data_Count=0;
                          }
                      }
                      break;
                 
                  default:
                    break;
                } 
            }
  
          if(DTU_Rceive_OK == 1)//响应上位机命名
          {
                _EINT();  //允许中断嵌套
                asm("nop");
              DTU_Pre_Received=0;
              DTU_Pre_Num = 0;  
              DTU_Rx_judge_save();//判断接收数据是否正确、保存修改数据
              DTU_Communicate();
          }
          }
          break;
          case 4:break; 
          default: break;
  }

代码中的重要变量和函数:

  • UCA1IV: UART 中断向量寄存器,指示 UART 中断类型。
  • DTU_Rx_Data: 接收到的数据。
  • DTU_Pre_Received: 是否接收到了前导字,0 表示未接收,1 表示已接收。
  • DTU_Pre_Num: 前导字的接收计数。
  • DTU_Rx_Data_Count: 接收数据计数。
  • DTU_length: 接收到的数据长度。
  • DTU_Receive_CMD_Count: 接收数据命令个数。
  • DTU_Rx_Data_Buffer: 接收数据缓冲区。
  • DTU_Check_Code: 校验数据函数。
  • DTU_Check_Result: 校验结果。
  • DTU_Receive_CheckCode: 接收到的校验码。
  • DTU_Communication_Error: 通信错误标志。
  • DTU_Rceive_OK: 接收数据是否成功,1 表示成功,0 表示失败。
  • DTU_Rx_judge_save: 判断接收数据是否正确并保存修改数据的函数。
  • DTU_Communicate: 响应上位机命令的函数。

这段代码是 MSP430 单片机中 DTU 模块串口数据处理的典型代码,可以帮助开发者理解串口通信数据的接收、校验和处理过程。

MSP430 DTU模块串口数据处理代码解析 - switch(UCA1IV) 语句详解

原文地址: https://www.cveoy.top/t/topic/jkGg 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录