Browse Source

调整RTU从站代码结构

master
zcn1123 4 years ago
parent
commit
54667d8bbb
7 changed files with 319 additions and 328 deletions
  1. +32
    -0
      Modbus_communication/Modbus_RTU_Salve/Modbus_TCP_log.txt
  2. +103
    -168
      Modbus_communication/Modbus_RTU_Salve/RTU_Salve.cpp
  3. +1
    -0
      Modbus_communication/Modbus_RTU_Salve/RTU_Salve.h
  4. +159
    -136
      Modbus_communication/Modbus_RTU_Salve/common.cpp
  5. +7
    -5
      Modbus_communication/Modbus_RTU_Salve/common.h
  6. +12
    -17
      Modbus_communication/Modbus_TCP/TCP_client.cpp
  7. +5
    -2
      Modbus_communication/Modbus_TCP/common.cpp

+ 32
- 0
Modbus_communication/Modbus_RTU_Salve/Modbus_TCP_log.txt View File

@@ -406,3 +406,35 @@
2020-9-10 15:53:22 Send:01 85 01 83 50
2020-9-10 15:53:24 Recv:01 01 00 11 00 01 AD CF
2020-9-10 15:53:24 Send:01 01 01 00 51 88
2020-9-16 19:2:31 Send:09 10 00 00 00 01 03 00 00 00 50 6C
2020-9-16 19:2:31 Recv:09 90 03 8D C3
2020-9-16 19:2:33 Send:09 10 00 00 00 01 03 00 00 00 50 6C
2020-9-16 19:2:33 Recv:09 90 03 8D C3
2020-9-16 19:2:33 Send:09 10 00 00 00 01 03 00 00 00 50 6C
2020-9-16 19:2:33 Recv:09 90 03 8D C3
2020-9-16 19:2:34 Send:09 10 00 00 00 01 03 00 00 00 50 6C
2020-9-16 19:2:34 Recv:09 90 03 8D C3
2020-9-16 19:2:35 Send:09 10 00 00 00 01 03 00 00 00 50 6C
2020-9-16 19:2:35 Recv:09 90 03 8D C3
2020-9-16 19:2:35 Send:09 10 00 00 00 01 03 00 00 00 50 6C
2020-9-16 19:2:35 Recv:09 90 03 8D C3
2020-9-16 19:2:37 Send:09 10 00 00 00 01 03 00 00 00 50 6C
2020-9-16 19:2:37 Recv:09 90 03 8D C3
2020-9-16 19:2:38 Send:09 10 00 00 00 01 03 00 00 00 50 6C
2020-9-16 19:2:38 Recv:09 90 03 8D C3
2020-9-16 19:2:38 Send:09 10 00 00 00 01 03 00 00 00 50 6C
2020-9-16 19:2:38 Recv:09 90 03 8D C3
2020-9-16 19:2:39 Send:09 10 00 00 00 01 03 00 00 00 50 6C
2020-9-16 19:2:39 Recv:09 90 03 8D C3
2020-9-16 19:2:39 Send:09 10 00 00 00 01 03 00 00 00 50 6C
2020-9-16 19:2:39 Recv:09 90 03 8D C3
2020-9-16 19:2:40 Send:09 10 00 00 00 01 03 00 00 00 50 6C
2020-9-16 19:2:40 Recv:09 90 03 8D C3
2020-9-16 19:3:14 Send:09 10 00 00 00 01 02 00 00 C1 90
2020-9-16 19:3:14 Recv:09 10 00 00 00 01 00 81
2020-9-16 19:3:15 Send:09 10 00 00 00 01 02 00 00 C1 90
2020-9-16 19:3:15 Recv:09 10 00 00 00 01 00 81
2020-9-16 19:3:34 Send:09 03 00 00 00 01 85 42
2020-9-16 19:3:34 Recv:09 03 02 00 00 59 85
2020-9-16 19:3:35 Send:09 03 00 00 00 01 85 42
2020-9-16 19:3:35 Recv:09 03 02 00 00 59 85

+ 103
- 168
Modbus_communication/Modbus_RTU_Salve/RTU_Salve.cpp View File

@@ -27,29 +27,29 @@ void Init_Coil_Register(void)
* 输入 : Bitset_Address Bitset的起始地址 Read_Number 要读取的位数
* 返回值 : Date 转换后的UNIT8数据
**********************************************************************************************/
UINT8 Bitset_to_Uint8(unsigned int Bitset_Address, unsigned int Read_Number)
UINT8 Bitset_to_Uint8(unsigned int bitset_address, unsigned int read_number)
{
UINT8 Date = 0x00;
UINT8 date = 0x00;
if (Read_Number >= 8)
if (read_number >= 8)
{
unsigned int len = Bitset_Address + 7;
unsigned int len = bitset_address + 7;
for (unsigned int i = 0; i < 8; i++)
{
Date = Date << 1;
Date = Date | (int)Coil_date[len--];
date = date << 1;
date = date | (int)Coil_date[len--];
}
}
else
{
unsigned int len = Bitset_Address + Read_Number-1;
for (unsigned int i = 0; i < Read_Number; i++)
unsigned int len = bitset_address + read_number - 1;
for (unsigned int i = 0; i < read_number; i++)
{
Date = Date << 1;
Date = Date | (int)Coil_date[len--];
date = date << 1;
date = date | (int)Coil_date[len--];
}
}
return Date;
return date;
}

/*********************************************************************************************
@@ -58,15 +58,15 @@ UINT8 Bitset_to_Uint8(unsigned int Bitset_Address, unsigned int Read_Number)
* 输入 : *Requst_Message 请求报文 *Response_Message响应报文
* 返回值 : 无
**********************************************************************************************/
void Create_Abnormal_Code_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message, UINT8 Abnormal_Code)
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[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
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;
}

@@ -78,25 +78,25 @@ void Create_Abnormal_Code_Response_Message(UINT8 *Requst_Message, UINT8 *Respons
**********************************************************************************************/
void Create_0x01_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message)
{
unsigned int Start_Address = Requst_Message[2] << 8 | Requst_Message[3];
unsigned int Address_range = Start_Address + (Requst_Message[4] << 8 | Requst_Message[5]);
if (Address_range < MAX_Address)//判断地址是否超限
unsigned int start_Address = Requst_Message[2] << 8 | Requst_Message[3];
unsigned int address_range = start_Address + (Requst_Message[4] << 8 | Requst_Message[5]);
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[1], Read_Number); //要读取的字节数
for (unsigned int i = 3; i < Read_Len + 3; i++)
unsigned int read_number = Requst_Message[4] << 8 | Requst_Message[5];//要读取的位数
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);
Start_Address += 8;
Read_Number -= 8;
Response_Message[i] = Bitset_to_Uint8(start_Address, read_number);
start_Address += 8;
read_number -= 8;
}
Response_Message[0] = Device_ID;
Response_Message[1] = Requst_Message[1];
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
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
{
@@ -112,26 +112,25 @@ void Create_0x01_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message
**********************************************************************************************/
void Create_0x03_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message)
{
unsigned int Start_Address = Requst_Message[2] << 8 | Requst_Message[3];
unsigned int Address_range = Start_Address + (Requst_Message[4] << 8 | Requst_Message[5]);
if (Address_range < MAX_Address) //判断地址是否超限
unsigned int start_Address = Requst_Message[2] << 8 | Requst_Message[3];
unsigned int address_range = start_Address + (Requst_Message[4] << 8 | Requst_Message[5]);
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[1
], Read_Number); //要读取的字节数
for (unsigned int i = 3; i < Read_Len + 3; i= i + 2)
unsigned int read_number = Requst_Message[4] << 8 | Requst_Message[5];//要读取的寄存器数量
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;
Response_Message[i + 1] = (UINT8)Register[Start_Address];
Start_Address += 1;
Response_Message[i] = Register[start_Address] >> 8;
Response_Message[i + 1] = (UINT8)Register[start_Address];
start_Address += 1;
}
Response_Message[0] = Device_ID;
Response_Message[1] = Requst_Message[1];
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
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 //地址超限
{
@@ -145,22 +144,22 @@ void Create_0x03_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message
* 输入 : Write_date_Message 要写入的数据 Write_Number要写入的位数 Start_Address起始地址
* 返回值 : 无
**********************************************************************************************/
void Write_Coil_date(UINT8 Write_date_Message, unsigned int Write_Number, unsigned int Start_Address)
void Write_Coil_date(UINT8 write_date_message, unsigned int write_number, unsigned int start_address)
{
if (Write_Number >= 8)
if (write_number >= 8)
{
for (unsigned int i = Start_Address; i < Start_Address+8; i++)
for (unsigned int i = start_address; i < start_address + 8; i++)
{
Coil_date[i] = Write_date_Message & 1;
Write_date_Message = Write_date_Message >> 1;
Coil_date[i] = write_date_message & 1;
write_date_message = write_date_message >> 1;
}
}
else
{
for (unsigned int i = Start_Address; i < Start_Address + Write_Number; i++)
for (unsigned int i = start_address; i < start_address + write_number; i++)
{
Coil_date[i] = Write_date_Message & 1;
Write_date_Message = Write_date_Message >> 1;
Coil_date[i] = write_date_message & 1;
write_date_message = write_date_message >> 1;
}
}
}
@@ -173,16 +172,16 @@ void Write_Coil_date(UINT8 Write_date_Message, unsigned int Write_Number, unsign
**********************************************************************************************/
void Create_0x0F_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message)
{
unsigned int Start_Address = Requst_Message[2] << 8 | Requst_Message[3];
unsigned int Address_range = Start_Address + (Requst_Message[4] << 8 | Requst_Message[5]);
if (Address_range < MAX_Address)//判断地址是否超限
unsigned int start_Address = Requst_Message[2] << 8 | Requst_Message[3];
unsigned int address_range = start_Address + (Requst_Message[4] << 8 | Requst_Message[5]);
if (address_range < MAX_Address)//判断地址是否超限
{
unsigned int Write_Number = Requst_Message[4] << 8 | Requst_Message[5];//要写入的位数
unsigned int write_Number = Requst_Message[4] << 8 | Requst_Message[5];//要写入的位数
for (int i = 7; i < Requst_Message[6]+7; i++)//执行写入线圈操作
{
Write_Coil_date(Requst_Message[i], Write_Number, Start_Address);
Write_Number -= 8;
Start_Address += 8;
Write_Coil_date(Requst_Message[i], write_Number, start_Address);
write_Number -= 8;
start_Address += 8;
}
Response_Message[0] = Device_ID;
Response_Message[1] = Requst_Message[1];
@@ -190,11 +189,10 @@ 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
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 //地址超限
{
@@ -210,15 +208,14 @@ void Create_0x0F_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message
**********************************************************************************************/
void Create_0x10_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message)
{
unsigned int Start_Address = Requst_Message[2] << 8 | Requst_Message[3];
unsigned int Address_range = Start_Address + (Requst_Message[4] << 8 | Requst_Message[5]);
if (Address_range < MAX_Address)//判断地址是否超限
unsigned int start_Address = Requst_Message[2] << 8 | Requst_Message[3];
unsigned int address_range = start_Address + (Requst_Message[4] << 8 | Requst_Message[5]);
if (address_range < MAX_Address)//判断地址是否超限
{
unsigned int Write_Number = Requst_Message[4] << 8 | Requst_Message[5];//要写入的寄存器个数
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++;
Register[start_Address] = Requst_Message[i] << 8 | Requst_Message[i + 1];
start_Address++;
}
Response_Message[0] = Device_ID;
Response_Message[1] = Requst_Message[1];
@@ -226,9 +223,9 @@ 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
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 //地址超限
@@ -245,11 +242,11 @@ void Create_0x10_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message
* 返回值 : true CRC校验通过
* false CRC校验不通过
**********************************************************************************************/
bool Check_Requst_Message_CRC(UINT8 *Requst_Message, DWORD Read_len)
bool Check_Requst_Message_CRC(UINT8 *Requst_Message, DWORD read_len)
{
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)
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;
}
@@ -261,18 +258,18 @@ bool Check_Requst_Message_CRC(UINT8 *Requst_Message, DWORD Read_len)
* 返回值 : true 长度校验通过
* false 长度校验不通过
**********************************************************************************************/
bool Check_Requst_Message_Len(UINT8 *Requst_Message, DWORD Read_len)
bool Check_Requst_Message_Len(UINT8 *Requst_Message, DWORD read_len)
{
if (Requst_Message[1] == 0x01 || Requst_Message[1] == 0x03)
{
if (Read_len != 8)
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);
if (Requst_Message[6] != Count_len || Read_len != Count_len + 9)
unsigned int number = Requst_Message[4] << 8 | Requst_Message[5];
unsigned int count_len = Count_Read_date_number(Requst_Message[1], number);
if (Requst_Message[6] != count_len || read_len != count_len + 9)
return false;
}
return true;
@@ -287,25 +284,25 @@ bool Check_Requst_Message_Len(UINT8 *Requst_Message, DWORD Read_len)
**********************************************************************************************/
bool Check_Operation_Number_Requst_Message(UINT8 *Requst_Message)
{
unsigned int Operation_Number = Requst_Message[4] << 8 | Requst_Message[5];
unsigned int operation_number = Requst_Message[4] << 8 | Requst_Message[5];
if (Requst_Message[1] == 0x01)
{
if (Operation_Number == 0 || Operation_Number > 2000)
if (operation_number == 0 || operation_number > 2000)
return false;
}
if (Requst_Message[1] == 0x03)
{
if (Operation_Number == 0 || Operation_Number > 125)
if (operation_number == 0 || operation_number > 125)
return false;
}
if (Requst_Message[1] == 0x0F)
{
if (Operation_Number < 1 || Operation_Number > 1968)
if (operation_number < 1 || operation_number > 1968)
return false;
}
if (Requst_Message[1] == 0x10)
{
if (Operation_Number < 1 || Operation_Number > 123)
if (operation_number < 1 || operation_number > 123)
return false;
}
return true;
@@ -317,20 +314,20 @@ bool Check_Operation_Number_Requst_Message(UINT8 *Requst_Message)
* 返回值 : true 生成响应报文
* false 不生成响应报文
**********************************************************************************************/
bool Create_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message, DWORD Read_len)
bool Create_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message, DWORD read_len)
{
if (Requst_Message[0] != Device_ID) //检查设备ID一致
return false;
if (Read_len < 8 || Read_len > 256)
if (read_len < 8 || read_len > 256)
return false;
if (!Check_Requst_Message_CRC(Requst_Message, Read_len))//CRC校验报文是否正确
if (!Check_Requst_Message_CRC(Requst_Message, read_len))//CRC校验报文是否正确
return false;
if (RTU_Enable == 0)
{
Create_Abnormal_Code_Response_Message(Requst_Message, Response_Message, 0x04);
return true;
}
if (!Check_Requst_Message_Len(Requst_Message, Read_len) || !Check_Operation_Number_Requst_Message(Requst_Message))//检查请求报文长度是否正确
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;
@@ -347,97 +344,35 @@ bool Create_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message, DWO
}


HANDLE Input_Parameter()
{
HANDLE Handle_Com;
while (true)
{
GetComm_Name();
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();
Handle_Com = Init_COM((LPCTSTR)COMM.c_str(), Baud_Rate, Date_Bits, Stop_Bits, Parity);
if (Handle_Com == INVALID_HANDLE_VALUE)
{
cout << "初始化串口失败,请重新输入设备信息\n" << endl;
}
else
{
printf("初始化串口成功\n");
break;
}
}
return Handle_Com;
}

int Modbus_RTU_Salve(void)
{
UINT8 Requst_Message[MAX_NUMBER];
UINT8 Response_Message[MAX_NUMBER];
DWORD requst_message_len = 0;
HANDLE Handle_Com = Input_Parameter();
Init_Coil_Register();
DWORD Read_len;
int Count = 0;
while (true)
{
PurgeComm(Handle_Com, PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_TXABORT);//清除缓存
BOOL Read_flage = ReadFile(Handle_Com, Requst_Message, 300, &Read_len, NULL); //阻塞等待接收请求报文
if (Read_flage && (Read_len > 0))

if (!Recv_date(&Handle_Com, Requst_Message, &requst_message_len))//接收
{
if (Create_Response_Message(Requst_Message, Response_Message, Read_len))
{
while (!SendData(Handle_Com, (char*)Response_Message, Response_Message_Len))
{
Count++;
printf("发送失败,重新发送第%d次\n",Count);
if (Count > 4)
{
break;
}
}
printf("主站请求 :");
for (unsigned int i = 0; i < Read_len; i++)
{
printf("%02x ", Requst_Message[i]);
}
printf("\n");
printf("从站响应 :");
for (unsigned int i = 0; i < Response_Message_Len; i++)
{
printf("%02x ", Response_Message[i]);
}
printf("\n\n");
//Log_Note(Requst_Message, 0, Read_len);
//Log_Note(Response_Message, 1, Response_Message_Len);
}
else
continue;
break;//用户选择退出
}
else
if (requst_message_len == 0)
continue;//长度为0 重新连接了

if (Create_Response_Message(Requst_Message, Response_Message, requst_message_len))//解析
{
printf("设备端口异常,请检查设备连接状态\n");
printf("**************************** Press Enter To Contioun ****************************\n");
getchar();
system("cls");
printf("是否重新连接端口: 1 重新连接 0 关闭本软件\n");
int a = 0 ;
do
{
cin >> a;
cin.clear();
cin.sync();
} while (!(a == 0 || a == 1));
if (a == 1)
if(!SendData(Handle_Com, (char*)Response_Message, Response_Message_Len))//发送
{
CloseHandle(Handle_Com);
printf("发送响应报文失败\n");
continue;
}
else
break;

Handle_Com = Input_Parameter();
Printf_Message(Requst_Message, 1, requst_message_len);
Printf_Message(Response_Message, 0, Response_Message_Len);
}
else
continue;//无响应
}
CloseHandle(Handle_Com);
getchar();


+ 1
- 0
Modbus_communication/Modbus_RTU_Salve/RTU_Salve.h View File

@@ -6,6 +6,7 @@
#define MAX_Address 9999
#define MAX_NUMBER 300


int Modbus_RTU_Salve(void);
bool Create_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message, DWORD Read_len);
void Init_Coil_Register(void);


+ 159
- 136
Modbus_communication/Modbus_RTU_Salve/common.cpp View File

@@ -8,9 +8,9 @@
* stop_bit : 停止位
* parity   : 奇偶校验。默认为无校验。NOPARITY 0; ODDPARITY 1;EVENPARITY 2
********************************************************************************************/
HANDLE Init_COM(LPCTSTR Port, int baud_rate, BYTE date_bits, BYTE stop_bit, BYTE parity)
HANDLE Init_COM(LPCTSTR port, int baud_rate, BYTE date_bits, BYTE stop_bit, BYTE parity)
{
HANDLE Handle_Com = CreateFile(Port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);//同步方式打开串口
HANDLE Handle_Com = CreateFile(port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);//同步方式打开串口
if (INVALID_HANDLE_VALUE == Handle_Com)
{
return INVALID_HANDLE_VALUE;
@@ -41,7 +41,8 @@ HANDLE Init_COM(LPCTSTR Port, int baud_rate, BYTE date_bits, BYTE stop_bit, BYTE
dcb.fParity = TRUE; //奇偶校验开启
dcb.Parity = parity; //校验模式
}
cout << SetCommState(Handle_Com, &dcb) << endl;
if (!SetCommState(Handle_Com, &dcb))
return INVALID_HANDLE_VALUE;
PurgeComm(Handle_Com, PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_TXABORT);//清除缓存
//设置串口读写时间
COMMTIMEOUTS CommTimeOuts;
@@ -65,47 +66,21 @@ HANDLE Init_COM(LPCTSTR Port, int baud_rate, BYTE date_bits, BYTE stop_bit, BYTE
* data : 要写入的数据
* len : 写入数据的长度
**********************************************************************************************/
bool SendData(HANDLE m_hComm, char* data, int len)
bool SendData(HANDLE m_hcomm, char* data, int len)
{
if (m_hComm == INVALID_HANDLE_VALUE)
if (m_hcomm == INVALID_HANDLE_VALUE)
return FALSE;

//清空串口
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR);
//写串口
PurgeComm(m_hcomm, PURGE_RXCLEAR | PURGE_TXCLEAR);
DWORD dwWrite = 0;
DWORD dwRet = WriteFile(m_hComm, data, len, &dwWrite, NULL);
//清空串口
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR);
if (!dwRet)
return FALSE;
return TRUE;
}

/*********************************************************************************************
* 功能     :  Ms延时器
* 描述    : ms级准确延时
* 输入 : lTime 延时的ms数
* 返回值 : 无
**********************************************************************************************/
void MSleep(long lTime)
{
LARGE_INTEGER litmp;
LONGLONG QPart1, QPart2;
double dfMinus, dfFreq, dfTim, dfSpec;
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadPart;
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadPart;
dfSpec = 0.000001*lTime;

do
int count = 0;
while (!WriteFile(m_hcomm, data, len, &dwWrite, NULL))
{
QueryPerformanceCounter(&litmp);
QPart2 = litmp.QuadPart;
dfMinus = (double)(QPart2 - QPart1);
dfTim = dfMinus / dfFreq;
} while (dfTim<dfSpec);
count++;
if (count > 4)
return false;
}
return true;
}

/*********************************************************************************************
@@ -115,20 +90,20 @@ void MSleep(long lTime)
* 返回值 : true 端口名正确
* false 端口名错误
**********************************************************************************************/
bool Check_Input_COMM(string Comm)
bool Check_Input_COMM(string comm)
{
string compare1 = "com";
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)
if (comm[3] == 0x30)
return false;
for (unsigned int i = 4; i < Comm.length(); i++)
for (unsigned int i = 4; i < comm.length(); i++)
{
if (Comm[i] >= 0x30 && Comm[i] <= 0x39)
if (comm[i] >= 0x30 && comm[i] <= 0x39)
continue;
}
return true;
@@ -143,7 +118,7 @@ bool Check_Input_COMM(string Comm)
string Input_COMM(void)
{
int flage = 1;
string Comm;
string comm;
do
{
if (flage == 1)
@@ -153,11 +128,11 @@ string Input_COMM(void)
}
else
printf("请重新输入端口名称:");
cin >> Comm;
cin >> comm;
cin.clear();
cin.sync();
} while (!Check_Input_COMM(Comm));
return Comm;
} while (!Check_Input_COMM(comm));
return comm;
}

/*********************************************************************************************
@@ -167,12 +142,12 @@ string Input_COMM(void)
* 返回值 : true 波特率正确
* false 波特率错误
**********************************************************************************************/
bool Check_Input_Baud_Rate(unsigned int Baud_Rate)
bool Check_Input_Baud_Rate(unsigned int baud_rate)
{
unsigned int Compare_Baud_Rate[9] = {300,600,1200,2400,4800,9600,14400,19200,38400};
unsigned int compare_baud_rate[9] = {300,600,1200,2400,4800,9600,14400,19200,38400};
for (int i = 0; i < 9; i++)
{
if (Baud_Rate == Compare_Baud_Rate[i])
if (baud_rate == compare_baud_rate[i])
return true;
}
return false;
@@ -186,7 +161,7 @@ bool Check_Input_Baud_Rate(unsigned int Baud_Rate)
**********************************************************************************************/
unsigned int Input_Baud_Rate(void)
{
unsigned int Baud_Rate;
unsigned int baud_rate;
int flage = 1;
printf("支持的波特率有:300,600,1200,2400,4800,9600,14400,19200,38400 \n");
do
@@ -198,11 +173,11 @@ unsigned int Input_Baud_Rate(void)
}
else
printf("请重新输入串口波特率:");
cin >> Baud_Rate;
cin >> baud_rate;
cin.clear();
cin.sync();
} while (!Check_Input_Baud_Rate(Baud_Rate));
return Baud_Rate;
} while (!Check_Input_Baud_Rate(baud_rate));
return baud_rate;
}


@@ -214,9 +189,9 @@ unsigned int Input_Baud_Rate(void)
**********************************************************************************************/
BYTE Input_Date_Bits(void)
{
BYTE Date_Bits;
BYTE date_bits;
int flage = 1;
unsigned int data_bits = 0;
unsigned int data_bits_temp = 0;
printf("支持的数据位有:5,6,7,8 \n");
do
{
@@ -227,12 +202,12 @@ BYTE Input_Date_Bits(void)
}
else
printf("请重新输入有效数据位:");
cin >> data_bits;
cin >> data_bits_temp;
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;
} while (!(data_bits_temp == 5 || data_bits_temp == 6 || data_bits_temp == 7 || data_bits_temp == 8));
date_bits = (BYTE)data_bits_temp;
return date_bits;
}

/*********************************************************************************************
@@ -243,13 +218,13 @@ BYTE Input_Date_Bits(void)
* 返回值 : true 停止位正确
* false 停止位错误
**********************************************************************************************/
bool Check_Input_Stop_Bits(BYTE Date_Bits, BYTE Stop_Bits)
bool Check_Input_Stop_Bits(BYTE date_bits, BYTE stop_bits)
{
if (Stop_Bits == 0 || Stop_Bits == 1 || Stop_Bits == 2)
if (stop_bits == 0 || stop_bits == 1 || stop_bits == 2)
{
if (Stop_Bits == 1 && (Date_Bits == 6 || Date_Bits == 7 || Date_Bits == 8))
if (stop_bits == 1 && (date_bits == 6 || date_bits == 7 || date_bits == 8))
return false;
if (Stop_Bits == 2 && Date_Bits == 5)
if (stop_bits == 2 && date_bits == 5)
return false;
}
else
@@ -266,11 +241,11 @@ bool Check_Input_Stop_Bits(BYTE Date_Bits, BYTE Stop_Bits)
* Date_Bits=5时 Stop_Bits不能为2
* 返回值 : Stop_Bits 数据位
**********************************************************************************************/
BYTE Input_Stop_Bits(BYTE Date_Bits)
BYTE Input_Stop_Bits(BYTE date_bits)
{
BYTE Stop_Bits;
BYTE stop_bits;
int flage = 1;
unsigned int stop_bits = 0;
unsigned int temp = 0;
printf("支持的停止位有:0,1,2 \n");
do
{
@@ -281,12 +256,12 @@ BYTE Input_Stop_Bits(BYTE Date_Bits)
}
else
printf("请重新输入停止位:");
cin >> stop_bits;
cin >> temp;
cin.clear();
cin.sync();
} while (!Check_Input_Stop_Bits(Date_Bits, (BYTE)stop_bits));
Stop_Bits = (BYTE)stop_bits;
return Stop_Bits;
} while (!Check_Input_Stop_Bits(date_bits, (BYTE)temp));
stop_bits = (BYTE)temp;
return stop_bits;
}

/*********************************************************************************************
@@ -297,9 +272,9 @@ BYTE Input_Stop_Bits(BYTE Date_Bits)
**********************************************************************************************/
BYTE Input_Parity(void)
{
BYTE Parity;
BYTE parity;
int flage = 1;
unsigned int parity = 0;
unsigned int temp = 0;
printf("支持的校验位有:0- 无校验 1- 奇校验 2- 偶校验 \n");
do
{
@@ -310,40 +285,14 @@ BYTE Input_Parity(void)
}
else
printf("请重新输入校验位:");
cin >> parity;
cin >> temp;
cin.clear();
cin.sync();
} while (!(parity == 1 || parity == 0 || parity == 2));
Parity = (BYTE)parity;
return Parity;
} while (!(temp == 1 || temp == 0 || temp == 2));
parity = (BYTE)temp;
return parity;
}

/*********************************************************************************************
* 功能     :  选择校验位
* 描述    : 获取串口通信的校验位
* 输入 : 无
* 返回值 : Parity 校验位
**********************************************************************************************/
unsigned int Input_RTU_Enable(void)
{
unsigned int RTU_Enable;
int flage = 1;
printf("请选择设备是否故障 0: 故障 1:未故障\n");
do
{
if (flage == 1)
{
printf("请输入故障码:");
flage = 0;
}
else
printf("请重新输入故障码:");
cin >> RTU_Enable;
cin.clear();
cin.sync();
} while (!(RTU_Enable == 1 || RTU_Enable == 0));
return RTU_Enable;
}

/*********************************************************************************************
* 功能    : 计算写入数据的字节数
@@ -351,18 +300,18 @@ unsigned int Input_RTU_Enable(void)
* 输入 : Function_code 选择的功能码类型 Operations_Number对应功能码类型的操作数量
* 输出 : Read_date_number 写入数据的字节数
*********************************************************************************************/
unsigned int Count_Read_date_number(int Function_code, unsigned int Operations_Number)
unsigned int Count_Read_date_number(int function_code, unsigned int operations_number)
{
unsigned int Read_date_number = 0;
if (Function_code == 0x01 || Function_code == 0x0F) //读线圈
unsigned int read_date_number = 0;
if (function_code == 0x01 || function_code == 0x0F) //读线圈
{
Read_date_number = Operations_Number / 8;
if (Operations_Number % 8)
Read_date_number++;
read_date_number = operations_number / 8;
if (operations_number % 8)
read_date_number++;
}
if (Function_code == 0x03 || Function_code == 0x10)//读寄存器
Read_date_number = Operations_Number * 2;
return Read_date_number;
if (function_code == 0x03 || function_code == 0x10)//读寄存器
read_date_number = operations_number * 2;
return read_date_number;
}


@@ -372,32 +321,32 @@ unsigned int Count_Read_date_number(int Function_code, unsigned int Operations_N
* 输入 : *Data 计算校验数据 CRC_Len 数据长度
* 返回值 : Ret_CRC_date CRC校验结果
**********************************************************************************************/
UINT16 CRC_16(UINT8 *Data, unsigned int CRC_Len)
UINT16 CRC_16(UINT8 *data, unsigned int crc_len)
{
UINT16 CRC_date = 0XFFFF;//16位crc寄存器预置
UINT16 crc_date = 0XFFFF;//16位crc寄存器预置
UINT16 temp;
unsigned int i = 0, j = 0;
for (i = 0; i < CRC_Len; i++)
for (i = 0; i < crc_len; i++)
{
temp = *Data & 0X00FF;//将八位数据与CRC寄存器亦或
Data++;
CRC_date ^= temp;
temp = *data & 0X00FF;//将八位数据与CRC寄存器亦或
data++;
crc_date ^= temp;
for (j = 0; j < 8; j++)
{
if (CRC_date & 0X0001)//判断右移出的是不是1,如果是1则与多项式进行异或。
if (crc_date & 0X0001)//判断右移出的是不是1,如果是1则与多项式进行异或。
{
CRC_date >>= 1;
CRC_date ^= 0XA001;
crc_date >>= 1;
crc_date ^= 0XA001;
}
else
{
CRC_date >>= 1;
crc_date >>= 1;
}
}
}
UINT16 Ret_CRC_date = CRC_date >> 8;
Ret_CRC_date = Ret_CRC_date | CRC_date << 8;
return Ret_CRC_date;
UINT16 ret_crc_date = crc_date >> 8;
ret_crc_date = ret_crc_date | crc_date << 8;
return ret_crc_date;
}

/*********************************************************************************************
@@ -407,17 +356,16 @@ UINT16 CRC_16(UINT8 *Data, unsigned int CRC_Len)
* Message_len 报文数据长度
* 输出 : 无
*********************************************************************************************/

void Log_Note(UINT8 *Message, int flage, int 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)
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)
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:";

/* 打开文件用于读写 */
@@ -430,8 +378,8 @@ void Log_Note(UINT8 *Message, int flage, int Message_len)

if (flage == 1)
{
fwrite(Send_str.c_str(), Send_str.length(), 1, fp);
for (int i = 0; i < Message_len; i++)
fwrite(send_str.c_str(), send_str.length(), 1, fp);
for (int i = 0; i < message_len; i++)
{
fprintf(fp, "%02X ", Message[i]);
}
@@ -439,8 +387,8 @@ void Log_Note(UINT8 *Message, int flage, int Message_len)
}
else
{
fwrite(Recv_str.c_str(), Recv_str.length(), 1, fp);
for (int i = 0; i < Message_len; i++)
fwrite(recv_str.c_str(), recv_str.length(), 1, fp);
for (int i = 0; i < message_len; i++)
{
fprintf(fp, "%02X ", Message[i]);
}
@@ -459,7 +407,6 @@ bool cmp(string s1, string s2)
return false;
}

//获取串口号
void GetComList_Reg(std::vector<string>& comList)
{
HKEY hkey;
@@ -501,10 +448,86 @@ void GetComm_Name(void)
GetComList_Reg(comList);
sort(comList.begin(), comList.end(), cmp);
printf("当前可用端口:");
for (int i = 0; i < comList.size(); i++)
for (unsigned int i = 0; i < comList.size(); i++)
{
cout << comList[i] << " ";
}
printf("\n");
}

HANDLE Input_Parameter()
{
HANDLE handle_com;
while (true)
{
GetComm_Name();
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();
handle_com = Init_COM((LPCTSTR)COMM.c_str(), baud_rate, date_bits, stop_bits, parity);
if (handle_com == INVALID_HANDLE_VALUE)
{
cout << "初始化串口失败,请重新输入设备信息\n" << endl;
}
else
{
printf("初始化串口成功\n");
break;
}
}
return handle_com;
}

void Printf_Message(UINT8 *Message, int flage, int message_len)
{
if (flage == 1)
printf("主站请求 :");
else
printf("从站响应 :");
for (int i = 0; i < message_len; i++)
{
printf("%02X ", Message[i]);
}
printf("\n");
if (LOG_NOTE_SWITCH)
Log_Note(Message, flage, message_len);
}

bool Abnormal_Connection(HANDLE *handle_com)
{
printf("设备端口异常,请检查设备连接状态\n");
printf("**************************** Press Enter To Contioun ****************************\n");
getchar();
system("cls");
printf("是否重新连接端口: 1 重新连接 0 关闭本软件\n");
int flage = 0;
do
{
cin >> flage;
cin.clear();
cin.sync();
} while (!(flage == 0 || flage == 1));
if (flage == 0)
{
return false;
}
CloseHandle(*handle_com);
*handle_com = Input_Parameter();
return true;
}

bool Recv_date(HANDLE *handle_com, UINT8 *Requst_Message, DWORD *read_len)
{
PurgeComm(*handle_com, PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_TXABORT);//清除缓存
BOOL read_flage = ReadFile(*handle_com, Requst_Message, 300, &(*read_len), NULL); //阻塞等待接收请求报文
if (read_flage && (*read_len > 0))
{
return true;
}
if (!Abnormal_Connection(handle_com))
return false;
return true;
}


+ 7
- 5
Modbus_communication/Modbus_RTU_Salve/common.h View File

@@ -12,17 +12,19 @@
#include <tchar.h>
using namespace std;

unsigned int Count_Read_date_number(int Function_code, unsigned int Operations_Number);
#define LOG_NOTE_SWITCH 1

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);
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_Stop_Bits(BYTE date_bits);
BYTE Input_Parity(void);
unsigned int Input_RTU_Enable(void);
UINT16 CRC_16(UINT8 *Data, unsigned int CRC_Len);
void Log_Note(UINT8 *Message, int flage, int Message_len);
UINT16 CRC_16(UINT8 *data, unsigned int crc_Len);
void Log_Note(UINT8 *Message, int flage, int message_len);
void GetComm_Name(void);

#endif

+ 12
- 17
Modbus_communication/Modbus_TCP/TCP_client.cpp View File

@@ -303,7 +303,7 @@ bool Send_date(SOCKET clientSocket, UINT8 *Request_Message, int request_message_
return true;
}

bool Abnormal_Fisconnection(SOCKET *clientSocket)
bool Abnormal_Connection(SOCKET *clientSocket)
{
printf("连接异常,请检查连接状态。\n");
printf("**************************** Press Enter To Contioun ****************************\n");
@@ -311,7 +311,7 @@ bool Abnormal_Fisconnection(SOCKET *clientSocket)
system("cls");
closesocket(*clientSocket);
WSACleanup();
printf("是否重新连接服务器: 1 重新连接 0 关闭本软件");
printf("是否重新连接服务器: 1 重新连接 0 关闭本软件\n");
int flage = 0;
do
{
@@ -375,39 +375,34 @@ int Tcp_Client()

while (true)
{
int function_code = Input_Function_code();
int function_code = Input_Function_code();//交互
unsigned int operations_Number = Input_Operations_number(function_code);
unsigned int starting_address = Input_Starting_address();
string write_date = Input_Write_date(function_code, operations_Number);
//生成
int request_message_len = Create_TCP_Message(Request_Message, function_code, operations_Number, starting_address, write_date);

int request_message_len = Create_TCP_Message(Request_Message, function_code, operations_Number, starting_address, write_date);//生成
if (!Send_date(clientSocket, Request_Message, request_message_len)) //发送
{
if (Abnormal_Fisconnection(&clientSocket))
if (Abnormal_Connection(&clientSocket))
continue;
else
break;
}

int Response_Message_len = Recv_date(clientSocket, Response_Message);//接收
if (Response_Message_len)
{
if (!Analysis_Response_Message(Response_Message, Request_Message, Response_Message_len))
printf("响应报文数据异常\n");
}
else
else if(!Test_Connection_status(clientSocket))
{
if (!Test_Connection_status(clientSocket))
{
if (Abnormal_Fisconnection(&clientSocket))
continue;
else
break;
}
if (Abnormal_Connection(&clientSocket))
continue;
else
printf("响应超时\n");
break;
}
else
printf("响应超时\n");

printf("**************************** Press Enter To Contioun ****************************\n");
getchar();
system("cls");


+ 5
- 2
Modbus_communication/Modbus_TCP/common.cpp View File

@@ -259,12 +259,15 @@ int HexStringtoByte(UINT8 *Message, string write_date, int message_len, int func
Message[message_len] = Count_Write_date_number(function_code, operations_Number);
message_len++;
const char *b = write_date.c_str();
int temp = 0;
for (unsigned int i = 0; i + 3 < write_date.length(); i = i + 3)
{
sscanf_s(b + i, "%02X", (int *)(Message + message_len));
sscanf_s(b + i, "%02X", &temp);
Message[message_len] = (UINT8)temp;
message_len++;
}
sscanf_s(b + write_date.length() - 2, "%02X", (int *)(Message + message_len));
sscanf_s(b + write_date.length() - 2, "%02X",&temp);
Message[message_len] = (UINT8)temp;
return ++message_len;
}



Loading…
Cancel
Save