瀏覽代碼

修改bug 请求报文长度不匹配 导致返回异常功能码01响应报文

Modbus_RTU
zcn1123 4 年之前
父節點
當前提交
44db6146ce
共有 2 個文件被更改,包括 69 次插入18 次删除
  1. +47
    -10
      Modbus_communication/Modbus_RTU_Salve/RTU_Salve.cpp
  2. +22
    -8
      Modbus_communication/Modbus_RTU_Salve/common.cpp

+ 47
- 10
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("发送失败,重新发送");
}


+ 22
- 8
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;
}



Loading…
取消
儲存