From 44db6146ce048f60170aa5fec66a0ef3df1ee19f Mon Sep 17 00:00:00 2001 From: zcn1123 <2363211205@qq.com> Date: Thu, 3 Sep 2020 14:30:38 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9bug=20=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E6=8A=A5=E6=96=87=E9=95=BF=E5=BA=A6=E4=B8=8D=E5=8C=B9=E9=85=8D?= =?UTF-8?q?=20=E5=AF=BC=E8=87=B4=E8=BF=94=E5=9B=9E=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E7=A0=8101=E5=93=8D=E5=BA=94=E6=8A=A5?= =?UTF-8?q?=E6=96=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Modbus_RTU_Salve/RTU_Salve.cpp | 57 +++++++++++++++---- .../Modbus_RTU_Salve/common.cpp | 30 +++++++--- 2 files changed, 69 insertions(+), 18 deletions(-) diff --git a/Modbus_communication/Modbus_RTU_Salve/RTU_Salve.cpp b/Modbus_communication/Modbus_RTU_Salve/RTU_Salve.cpp index d4ab135..d5514c6 100644 --- a/Modbus_communication/Modbus_RTU_Salve/RTU_Salve.cpp +++ b/Modbus_communication/Modbus_RTU_Salve/RTU_Salve.cpp @@ -62,7 +62,7 @@ void Create_0x01_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message if (Address_range < MAX_Address)//判断地址是否超限 { unsigned int Read_Number = Requst_Message[4] << 8 | Requst_Message[5];//要读取的位数 - unsigned int Read_Len = Count_Read_date_number(Requst_Message[0], Read_Number); //要读取的字节数 + unsigned int Read_Len = Count_Read_date_number(Requst_Message[1], Read_Number); //要读取的字节数 for (unsigned int i = 3; i < Read_Len + 3; i++) { Response_Message[i] = Bitset_to_Uint8(Start_Address, Read_Number); @@ -102,7 +102,8 @@ void Create_0x03_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message if (Address_range < MAX_Address) //判断地址是否超限 { unsigned int Read_Number = Requst_Message[4] << 8 | Requst_Message[5];//要读取的寄存器数量 - unsigned int Read_Len = Count_Read_date_number(Requst_Message[0], Read_Number); //要读取的字节数 + unsigned int Read_Len = Count_Read_date_number(Requst_Message[1 + ], Read_Number); //要读取的字节数 for (unsigned int i = 3; i < Read_Len + 3; i= i + 2) { Response_Message[i] = Register[Start_Address] >> 8; @@ -240,7 +241,7 @@ void Create_0x10_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message } /********************************************************************************************* -* 功能     :  生成异常功能码响应报文 +* 功能     :  生成异常码01响应报文 * 描述    : 对不支持的功能码生成对应的异常响应报文 * 输入 : *Requst_Message 请求报文 *Response_Message响应报文 * 返回值 : 无 @@ -251,14 +252,14 @@ void Create_Abnormal_Function_Code_Response_Message(UINT8 *Requst_Message, UINT8 Response_Message[1] = Requst_Message[1] + 0x80; Response_Message[2] = 0x01; } + /********************************************************************************************* -* 功能     :  生成响应报文 -* 描述    : 检查设备请求报文来生成对应功能的响应报文 -* 输入 : *Requst_Message 请求报文 *Response_Message响应报文 -* 返回值 : true 生成响应报文 -* false 不生成响应报文 +* 功能     :  CRC校验 +* 描述    : 对请求报文中的数据进行CRC校验 +* 输入 : *Requst_Message 请求报文 Read_len 接收到到的字节数 +* 返回值 : true CRC校验通过 +* false CRC校验不通过 **********************************************************************************************/ - bool Check_Requst_Message_CRC(UINT8 *Requst_Message, DWORD Read_len) { UINT16 CRC_data = CRC_16(Requst_Message, Read_len-2); @@ -267,8 +268,42 @@ bool Check_Requst_Message_CRC(UINT8 *Requst_Message, DWORD Read_len) return false; return true; } + +/********************************************************************************************* +* 功能     :  CRC校验 +* 描述    : 对请求报文中的数据进行CRC校验 +* 输入 : *Requst_Message 请求报文 Read_len 接收到到的字节数 +* 返回值 : true CRC校验通过 +* false CRC校验不通过 +**********************************************************************************************/ +bool Check_Requst_Message_Len(UINT8 *Requst_Message, DWORD Read_len) +{ + if (Requst_Message[1] == 0x01 || Requst_Message[1] == 0x03) + { + if (Read_len != 8) + return false; + } + if (Requst_Message[1] == 0x0F || Requst_Message[1] == 0x10) + { + unsigned int Number = Requst_Message[4] << 8 | Requst_Message[5]; + unsigned int Count_len = Count_Read_date_number(Requst_Message[1], Number) + 9; + if (Read_len != Count_len) + return false; + } + return true; +} + +/********************************************************************************************* +* 功能     :  生成响应报文 +* 描述    : 检查设备请求报文来生成对应功能的响应报文 +* 输入 : *Requst_Message 请求报文 *Response_Message响应报文 +* 返回值 : true 生成响应报文 +* false 不生成响应报文 +**********************************************************************************************/ bool Create_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message, DWORD Read_len) { + if (!Check_Requst_Message_Len(Requst_Message, Read_len))//检查请求报文长度是否正确 + return false; if (!Check_Requst_Message_CRC(Requst_Message, Read_len))//CRC校验报文是否正确 return false; if (Requst_Message[0] != Device_ID) //检查设备ID一致 @@ -303,6 +338,8 @@ int Modbus_RTU_Salve(void) getchar(); return 0; } + else + printf("初始化串口成功"); Init_Coil_Register(); DWORD Read_len; while (true) @@ -313,7 +350,7 @@ int Modbus_RTU_Salve(void) { if (Create_Response_Message(Requst_Message, Response_Message, Read_len)) { - while (SendData(Handle_Com, (char*)Response_Message, Response_Message_Len)) + while (!SendData(Handle_Com, (char*)Response_Message, Response_Message_Len)) { printf("发送失败,重新发送"); } diff --git a/Modbus_communication/Modbus_RTU_Salve/common.cpp b/Modbus_communication/Modbus_RTU_Salve/common.cpp index e23a5bb..a32df01 100644 --- a/Modbus_communication/Modbus_RTU_Salve/common.cpp +++ b/Modbus_communication/Modbus_RTU_Salve/common.cpp @@ -154,6 +154,8 @@ string Input_COMM(void) else printf("请重新输入端口名称:"); cin >> Comm; + cin.clear(); + cin.sync(); } while (!Check_Input_COMM(Comm)); return Comm; } @@ -197,6 +199,8 @@ unsigned int Input_Baud_Rate(void) else printf("请重新输入串口波特率:"); cin >> Baud_Rate; + cin.clear(); + cin.sync(); } while (!Check_Input_Baud_Rate(Baud_Rate)); return Baud_Rate; } @@ -212,10 +216,10 @@ BYTE Input_Date_Bits(void) { BYTE Date_Bits; int flage = 1; + unsigned int data_bits = 0; printf("支持的数据位有:5,6,7,8 \n"); do { - cin >> hex; if (flage == 1) { printf("请输入有效数据位:"); @@ -223,9 +227,11 @@ BYTE Input_Date_Bits(void) } else printf("请重新输入有效数据位:"); - cin >> Date_Bits; - - } while (!(Date_Bits == 5 || Date_Bits == 6 || Date_Bits == 7 || Date_Bits == 8)); + cin >> data_bits; + cin.clear(); + cin.sync(); + } while (!(data_bits == 5 || data_bits == 6 || data_bits == 7 || data_bits == 8)); + Date_Bits = (BYTE)data_bits; return Date_Bits; } @@ -264,6 +270,7 @@ BYTE Input_Stop_Bits(BYTE Date_Bits) { BYTE Stop_Bits; int flage = 1; + unsigned int stop_bits = 0; printf("支持的停止位有:0,1,2 \n"); do { @@ -274,8 +281,11 @@ BYTE Input_Stop_Bits(BYTE Date_Bits) } else printf("请重新输入停止位:"); - cin >> Stop_Bits; - } while (!Check_Input_Stop_Bits(Date_Bits, Stop_Bits)); + cin >> stop_bits; + cin.clear(); + cin.sync(); + } while (!Check_Input_Stop_Bits(Date_Bits, (BYTE)stop_bits)); + Stop_Bits = (BYTE)stop_bits; return Stop_Bits; } @@ -289,6 +299,7 @@ BYTE Input_Parity(void) { BYTE Parity; int flage = 1; + unsigned int parity = 0; printf("支持的校验位有:0- 无校验 1- 奇校验 2- 偶校验 \n"); do { @@ -299,8 +310,11 @@ BYTE Input_Parity(void) } else printf("请重新输入校验位:"); - cin >> Parity; - } while (!(Parity == 1 || Parity == 0 || Parity == 2)); + cin >> parity; + cin.clear(); + cin.sync(); + } while (!(parity == 1 || parity == 0 || parity == 2)); + Parity = (BYTE)parity; return Parity; }