9 次程式碼提交

共有 7 個檔案被更改,包括 260 行新增72 行删除
分割檢視
  1. +1
    -0
      Modbus_communication/Modbus_RTU_Salve/Modbus_RTU_Salve.vcxproj
  2. +12
    -0
      Modbus_communication/Modbus_RTU_Salve/Modbus_TCP_log.txt
  3. +156
    -59
      Modbus_communication/Modbus_RTU_Salve/RTU_Salve.cpp
  4. +3
    -0
      Modbus_communication/Modbus_RTU_Salve/RTU_Salve.h
  5. +77
    -10
      Modbus_communication/Modbus_RTU_Salve/common.cpp
  6. +10
    -2
      Modbus_communication/Modbus_RTU_Salve/common.h
  7. +1
    -1
      Modbus_communication/Modbus_RTU_Salve/main.cpp

+ 1
- 0
Modbus_communication/Modbus_RTU_Salve/Modbus_RTU_Salve.vcxproj 查看文件

@@ -44,6 +44,7 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>


+ 12
- 0
Modbus_communication/Modbus_RTU_Salve/Modbus_TCP_log.txt 查看文件

@@ -0,0 +1,12 @@
2020-9-3 22:1:6 Recv:09 0F 00 00 07 B1 F6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 DB
2020-9-3 22:1:6 Send:09 8F 03 85 F3
2020-9-3 22:1:7 Recv:09 0F 00 00 07 B1 F6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 DB
2020-9-3 22:1:7 Send:09 8F 03 85 F3
2020-9-3 22:1:8 Recv:09 0F 00 00 07 B1 F6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 DB
2020-9-3 22:1:8 Send:09 8F 03 85 F3
2020-9-3 22:1:9 Recv:09 0F 00 00 07 B1 F6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 DB
2020-9-3 22:1:9 Send:09 8F 03 85 F3
2020-9-3 22:1:10 Recv:09 0F 00 00 07 B1 F6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 DB
2020-9-3 22:1:10 Send:09 8F 03 85 F3
2020-9-3 22:1:32 Recv:09 0F 00 00 07 B0 F6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 B8 78
2020-9-3 22:1:32 Send:09 0F 00 00 07 B0 57 07

+ 156
- 59
Modbus_communication/Modbus_RTU_Salve/RTU_Salve.cpp 查看文件

@@ -4,6 +4,7 @@ char read_buf[MAX_NUMBER];

bitset<MAX_Address> Coil_date; //0-9999
UINT16 Register[MAX_Address]; // 0-9999
unsigned int Response_Message_Len;

/*********************************************************************************************
* 功能     :  初始化线圈和寄存器
@@ -32,7 +33,7 @@ UINT8 Bitset_to_Uint8(unsigned int Bitset_Address, unsigned int Read_Number)
if (Read_Number >= 8)
{
unsigned int len = Bitset_Address + 8;
for (int i = 0; i < 8; i++)
for (unsigned int i = 0; i < 8; i++)
{
Date = Date << 1 | (int)Coil_date[len--];
}
@@ -40,7 +41,7 @@ UINT8 Bitset_to_Uint8(unsigned int Bitset_Address, unsigned int Read_Number)
else
{
unsigned int len = Bitset_Address + Read_Number-1;
for (int i = 0; i < Read_Number; i++)
for (unsigned int i = 0; i < Read_Number; i++)
{
Date = Date << 1 | (int)Coil_date[len--];
}
@@ -48,6 +49,24 @@ UINT8 Bitset_to_Uint8(unsigned int Bitset_Address, unsigned int Read_Number)
return Date;
}

/*********************************************************************************************
* 功能     :  生成异常码响应报文
* 描述    : 对不支持的功能码生成对应的异常响应报文
* 输入 : *Requst_Message 请求报文 *Response_Message响应报文
* 返回值 : 无
**********************************************************************************************/
void Create_Abnormal_Code_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message, UINT8 Abnormal_Code)
{
Response_Message[0] = Device_ID;
Response_Message[1] = Requst_Message[1] + 0x80;
Response_Message[2] = Abnormal_Code;
Response_Message_Len = 3;
UINT16 CRC_date = CRC_16(Response_Message, 3);
Response_Message[3] = CRC_date >> 8;//CRC_H
Response_Message[4] = (UINT8)CRC_date; //CRC_L
Response_Message_Len = 5;
}

/*********************************************************************************************
* 功能     :  生成0x01功能码响应报文
* 描述    : 通过判断地址范围生成0x01对应的响应报文
@@ -61,7 +80,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);
@@ -70,13 +89,15 @@ void Create_0x01_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message
}
Response_Message[0] = Device_ID;
Response_Message[1] = Requst_Message[1];
Response_Message[2] = Read_Len+2; //响应报文中的后续字节数
Response_Message[2] = Read_Len; //响应报文中的后续字节数
UINT16 CRC_date = CRC_16(Response_Message, Read_Len+3);
Response_Message_Len = Read_Len + 2 + 3;
Response_Message[Response_Message_Len - 2] = CRC_date>>8;//CRC_H
Response_Message[Response_Message_Len - 1] = (UINT8)CRC_date; //CRC_L
}
else //地址超限
else
{
Response_Message[0] = Device_ID;
Response_Message[1] = Requst_Message[1] + 0x80;
Response_Message[2] = 0x02;
Create_Abnormal_Code_Response_Message(Requst_Message, Response_Message,0x02);
}
}

@@ -93,7 +114,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;
@@ -102,13 +124,15 @@ void Create_0x03_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message
}
Response_Message[0] = Device_ID;
Response_Message[1] = Requst_Message[1];
Response_Message[2] = Read_Len + 2; //响应报文中的后续字节数
Response_Message[2] = Read_Len; //响应报文中的后续字节数
UINT16 CRC_date = CRC_16(Response_Message, Read_Len + 3);
Response_Message_Len = Read_Len + 2 + 3;
Response_Message[Response_Message_Len - 2] = CRC_date >> 8;//CRC_H
Response_Message[Response_Message_Len - 1] = (UINT8)CRC_date; //CRC_L
}
else //地址超限
{
Response_Message[0] = Device_ID;
Response_Message[1] = Requst_Message[1] + 0x80;
Response_Message[2] = 0x02;
Create_Abnormal_Code_Response_Message(Requst_Message, Response_Message, 0x02);
}
}

@@ -125,7 +149,7 @@ void Write_Coil_date(UINT8 Write_date_Message, unsigned int Write_Number, unsign
for (unsigned int i = Start_Address; i < Start_Address+8; i++)
{
Coil_date[i] = Write_date_Message & 1;
Write_date_Message >> 1;
Write_date_Message = Write_date_Message >> 1;
}
}
else
@@ -133,7 +157,7 @@ void Write_Coil_date(UINT8 Write_date_Message, unsigned int Write_Number, unsign
for (unsigned int i = Start_Address; i < Start_Address + Write_Number; i++)
{
Coil_date[i] = Write_date_Message & 1;
Write_date_Message >> 1;
Write_date_Message = Write_date_Message >> 1;
}
}
}
@@ -151,7 +175,7 @@ void Create_0x0F_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message
if (Address_range < MAX_Address)//判断地址是否超限
{
unsigned int Write_Number = Requst_Message[4] << 8 | Requst_Message[5];//要写入的位数
for (unsigned int i = 7; i < Requst_Message[6]+7; i++)//执行写入线圈操作
for (int i = 7; i < Requst_Message[6]+7; i++)//执行写入线圈操作
{
Write_Coil_date(Requst_Message[i], Write_Number, Start_Address);
Write_Number -= 8;
@@ -163,12 +187,15 @@ void Create_0x0F_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message
Response_Message[3] = Requst_Message[3];
Response_Message[4] = Requst_Message[4];
Response_Message[5] = Requst_Message[5];
UINT16 CRC_date = CRC_16(Response_Message, 6);
Response_Message[6] = CRC_date >> 8;//CRC_H
Response_Message[7] = (UINT8)CRC_date; //CRC_L
Response_Message_Len = 8;

}
else //地址超限
{
Response_Message[0] = Device_ID;
Response_Message[1] = Requst_Message[1] + 0x80;
Response_Message[2] = 0x02;
Create_Abnormal_Code_Response_Message(Requst_Message, Response_Message, 0x02);
}
}

@@ -185,7 +212,7 @@ void Create_0x10_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message
if (Address_range < MAX_Address)//判断地址是否超限
{
unsigned int Write_Number = Requst_Message[4] << 8 | Requst_Message[5];//要写入的寄存器个数
for (unsigned int i = 7; i < Requst_Message[6] + 7; i = i + 2)//执行写入寄存器操作
for (int i = 7; i < Requst_Message[6] + 7; i = i + 2)//执行写入寄存器操作
{
Register[Start_Address] = Requst_Message[i] << 8 | Requst_Message[i+1];
Start_Address++;
@@ -196,26 +223,89 @@ void Create_0x10_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message
Response_Message[3] = Requst_Message[3];
Response_Message[4] = Requst_Message[4];
Response_Message[5] = Requst_Message[5];
UINT16 CRC_date = CRC_16(Response_Message, 6);
Response_Message[6] = CRC_date >> 8;//CRC_H
Response_Message[7] = (UINT8)CRC_date; //CRC_L
Response_Message_Len = 8;
}
else //地址超限
{
Response_Message[0] = Device_ID;
Response_Message[1] = Requst_Message[1] + 0x80;
Response_Message[2] = 0x02;
Create_Abnormal_Code_Response_Message(Requst_Message, Response_Message, 0x02);
}
}


/*********************************************************************************************
* 功能     :  生成异常功能码响应报文
* 描述    : 对不支持的功能码生成对应的异常响应报文
* 输入 : *Requst_Message 请求报文 *Response_Message响应报文
* 返回值 : 无
* 功能     :  CRC校验
* 描述    : 对请求报文中的数据进行CRC校验
* 输入 : *Requst_Message 请求报文 Read_len 接收到到的字节数
* 返回值 : true CRC校验通过
* false CRC校验不通过
**********************************************************************************************/
void Create_Abnormal_Function_Code_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message)
bool Check_Requst_Message_CRC(UINT8 *Requst_Message, DWORD Read_len)
{
Response_Message[0] = Device_ID;
Response_Message[1] = Requst_Message[1] + 0x80;
Response_Message[2] = 0x01;
UINT16 CRC_data = CRC_16(Requst_Message, Read_len-2);
UINT16 Message_CRC = Requst_Message[Read_len - 2] << 8 | Requst_Message[Read_len - 1];
if (CRC_data != Message_CRC)
return false;
return true;
}

/*********************************************************************************************
* 功能     :  异常码03判定--请求报文长度校验
* 描述    : 对请求报文的字节长度进行计算校验
* 输入 : *Requst_Message 请求报文 Read_len 接收到到的字节数
* 返回值 : true 长度校验通过
* false 长度校验不通过
**********************************************************************************************/
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;
}

/*********************************************************************************************
* 功能     :  异常码03判定--请求报文中的操作数量判定
* 描述    : 对请求报文中的操作数量进行判定
* 输入 : *Requst_Message 请求报文 Read_len 接收到到的字节数
* 返回值 : true 校验通过
* false 校验不通过
**********************************************************************************************/
bool Check_Operation_Number_Requst_Message(UINT8 *Requst_Message)
{
unsigned int Operation_Number = Requst_Message[4] << 8 | Requst_Message[5];
if (Requst_Message[1] == 0x01)
{
if (Operation_Number == 0 || Operation_Number > 2000)
return false;
}
if (Requst_Message[1] == 0x03)
{
if (Operation_Number == 0 || Operation_Number > 125)
return false;
}
if (Requst_Message[1] == 0x0F)
{
if (Operation_Number < 2 || Operation_Number > 1968)
return false;
}
if (Requst_Message[1] == 0x10)
{
if (Operation_Number < 2 || Operation_Number > 123)
return false;
}
return true;
}
/*********************************************************************************************
* 功能     :  生成响应报文
@@ -224,62 +314,69 @@ void Create_Abnormal_Function_Code_Response_Message(UINT8 *Requst_Message, UINT8
* 返回值 : true 生成响应报文
* false 不生成响应报文
**********************************************************************************************/
bool Create_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message)
bool Create_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message, DWORD Read_len)
{
if (Requst_Message[0] != Device_ID) //检查设备ID一致
return false;
if (!Check_Requst_Message_CRC(Requst_Message, Read_len))//CRC校验报文是否正确
return false;
if (!Check_Requst_Message_Len(Requst_Message, Read_len) || !Check_Operation_Number_Requst_Message(Requst_Message))//检查请求报文长度是否正确
{
Create_Abnormal_Code_Response_Message(Requst_Message, Response_Message, 0x03);
return true;
}
switch (Requst_Message[1])
{
case 0x01:Create_0x01_Response_Message(Requst_Message, Response_Message); break;
case 0x03:Create_0x03_Response_Message(Requst_Message, Response_Message); break;
case 0x0F:Create_0x0F_Response_Message(Requst_Message, Response_Message); break;
case 0x10:Create_0x10_Response_Message(Requst_Message, Response_Message); break;
default: Create_Abnormal_Function_Code_Response_Message(Requst_Message, Response_Message);
default: Create_Abnormal_Code_Response_Message(Requst_Message, Response_Message,0x01);
}
return true;
}



int test(void)
int Modbus_RTU_Salve(void)
{
string COMM;
cin >> COMM;
HANDLE Handle_Com = Init_COM((LPCTSTR)COMM.c_str(), 9600, 8, 0, 1);
string COMM = Input_COMM();
unsigned int Baud_Rate = Input_Baud_Rate();
BYTE Date_Bits = Input_Date_Bits();
BYTE Stop_Bits = Input_Stop_Bits(Date_Bits);
BYTE Parity = Input_Parity();

UINT8 Requst_Message[MAX_NUMBER];
UINT8 Response_Message[MAX_NUMBER];
HANDLE Handle_Com = Init_COM((LPCTSTR)COMM.c_str(), Baud_Rate, Date_Bits, Stop_Bits, Parity);
if (Handle_Com == INVALID_HANDLE_VALUE)
{
cout << "初始化串口失败" << endl;
getchar();
return 0;
}
char write_buf[MAX_NUMBER];
memset(write_buf, 0, MAX_NUMBER);
DWORD dwRead;
else
printf("初始化串口成功");
Init_Coil_Register();
DWORD Read_len;
while (true)
{
//RTU主站,生成并发送请求,计时,读取响应报文,先发送后接收
//生成请求报文
//发送请求报文

PurgeComm(Handle_Com, PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_TXABORT);//清除缓存
while (1)
BOOL Read_flage = ReadFile(Handle_Com, Requst_Message, 256, &Read_len, NULL); //阻塞等待接收请求报文
if (Read_flage && (Read_len > 0))
{
if (true == SendData(Handle_Com, "ok", 2))
if (Create_Response_Message(Requst_Message, Response_Message, Read_len))
{
cout << "发送请求报文成功" << endl;
break;
while (!SendData(Handle_Com, (char*)Response_Message, Response_Message_Len))
{
printf("发送失败,重新发送");
}
Log_Note(Requst_Message, 0, Read_len);
Log_Note(Response_Message, 1, Response_Message_Len);
}
else
continue;
}
BOOL bReadOK = ReadFile(Handle_Com, read_buf, 256, &dwRead, NULL);
if (bReadOK && (dwRead > 0))
{
read_buf[dwRead] = '\0';
printf("收到响应:%s \r\n", read_buf);
}
else
cout << "loss" << endl;

}
CloseHandle(Handle_Com);
getchar();


+ 3
- 0
Modbus_communication/Modbus_RTU_Salve/RTU_Salve.h 查看文件

@@ -4,5 +4,8 @@
#include "common.h"
#define Device_ID 0x09
#define MAX_Address 9999
#define MAX_NUMBER 256

int Modbus_RTU_Salve(void);

#endif

+ 77
- 10
Modbus_communication/Modbus_RTU_Salve/common.cpp 查看文件

@@ -47,7 +47,7 @@ HANDLE Init_COM(LPCTSTR Port, int baud_rate, BYTE date_bits, BYTE stop_bit, BYTE
COMMTIMEOUTS CommTimeOuts;
GetCommTimeouts(Handle_Com, &CommTimeOuts);
CommTimeOuts.ReadIntervalTimeout = 5;
CommTimeOuts.ReadTotalTimeoutMultiplier = 1;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 10;
CommTimeOuts.WriteTotalTimeoutConstant = 1000;
@@ -121,7 +121,7 @@ bool Check_Input_COMM(string Comm)
string compare2 = "COM";
for (unsigned int i = 0; i < 3; i++)
{
if (Comm[i] != compare1[i] || Comm[i] != compare2[i])
if (Comm[i] != compare1[i] && Comm[i] != compare2[i])
return false;
}
if (Comm[3] == 0x30)
@@ -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,6 +216,7 @@ BYTE Input_Date_Bits(void)
{
BYTE Date_Bits;
int flage = 1;
unsigned int data_bits = 0;
printf("支持的数据位有:5,6,7,8 \n");
do
{
@@ -222,8 +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;
}

@@ -262,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
{
@@ -272,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;
}

@@ -287,6 +299,7 @@ BYTE Input_Parity(void)
{
BYTE Parity;
int flage = 1;
unsigned int parity = 0;
printf("支持的校验位有:0- 无校验 1- 奇校验 2- 偶校验 \n");
do
{
@@ -297,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;
}

@@ -312,13 +328,13 @@ BYTE Input_Parity(void)
unsigned int Count_Read_date_number(int Function_code, unsigned int Operations_Number)
{
unsigned int Read_date_number = 0;
if (Function_code == 0x01) //读线圈
if (Function_code == 0x01 || Function_code == 0x0F) //读线圈
{
Read_date_number = Operations_Number / 8;
if (Operations_Number % 8)
Read_date_number++;
}
if (Function_code == 0x03)
if (Function_code == 0x03 || Function_code == 0x10)//读寄存器
Read_date_number = Operations_Number * 2;
return Read_date_number;
}
@@ -358,3 +374,54 @@ UINT16 CRC_16(UINT8 *Data, unsigned int CRC_Len)
return Ret_CRC_date;
}

/*********************************************************************************************
* 功能    : 日志记录
* 描述   : 记录每次通信的请求和响应报文
* 输入 : *Message 消息帧存放的数组 flage = 1 请求报文 flage = 其他 响应报文
* Message_len 报文数据长度
* 输出 : 无
*********************************************************************************************/

void Log_Note(UINT8 *Message, int flage, int Message_len)
{
FILE *fp = NULL;
time_t timep;
struct tm *p;
time(&timep);
p = gmtime(&timep);
string Recv_str = to_string(1900 + p->tm_year) + "-" + to_string(1 + p->tm_mon) + "-" + to_string(p->tm_mday)
+ " " + to_string(8 + p->tm_hour) + ":" + to_string(p->tm_min) + ":" + to_string(p->tm_sec) + " Recv:";
string Send_str = to_string(1900 + p->tm_year) + "-" + to_string(1 + p->tm_mon) + "-" + to_string(p->tm_mday)
+ " " + to_string(8 + p->tm_hour) + ":" + to_string(p->tm_min) + ":" + to_string(p->tm_sec) + " Send:";

/* 打开文件用于读写 */
if ((fp = fopen("Modbus_TCP_log.txt", "a+")) == NULL)
{
printf("打开文件失败");
return;
}


if (flage == 1)
{
fwrite(Send_str.c_str(), Send_str.length(), 1, fp);
for (int i = 0; i < Message_len; i++)
{
fprintf(fp, "%02X ", Message[i]);
}
fprintf(fp, "\n");
}
else
{
fwrite(Recv_str.c_str(), Recv_str.length(), 1, fp);
for (int i = 0; i < Message_len; i++)
{
fprintf(fp, "%02X ", Message[i]);
}
fprintf(fp, "\n");
}
fclose(fp);
fp = NULL;
}



+ 10
- 2
Modbus_communication/Modbus_RTU_Salve/common.h 查看文件

@@ -4,10 +4,18 @@
#include <Windows.h>
#include <string>
#include <iostream>
#include <time.h>
using namespace std;

#define MAX_NUMBER 300

unsigned int Count_Read_date_number(int Function_code, unsigned int Operations_Number);
HANDLE Init_COM(LPCTSTR Port, int baud_rate, BYTE date_bits, BYTE stop_bit, BYTE parity);
bool SendData(HANDLE m_hComm, char* data, int len);
string Input_COMM(void);
unsigned int Input_Baud_Rate(void);
BYTE Input_Date_Bits(void);
BYTE Input_Stop_Bits(BYTE Date_Bits);
BYTE Input_Parity(void);
UINT16 CRC_16(UINT8 *Data, unsigned int CRC_Len);
void Log_Note(UINT8 *Message, int flage, int Message_len);

#endif

+ 1
- 1
Modbus_communication/Modbus_RTU_Salve/main.cpp 查看文件

@@ -2,7 +2,7 @@

int main()
{
test();
Modbus_RTU_Salve();
getchar();
return 0;
}

Loading…
取消
儲存