diff --git a/Modbus_communication/Modbus_RTU_Salve/Modbus_TCP_log.txt b/Modbus_communication/Modbus_RTU_Salve/Modbus_TCP_log.txt index 35c9aff..a62e81a 100644 --- a/Modbus_communication/Modbus_RTU_Salve/Modbus_TCP_log.txt +++ b/Modbus_communication/Modbus_RTU_Salve/Modbus_TCP_log.txt @@ -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 diff --git a/Modbus_communication/Modbus_RTU_Salve/RTU_Salve.cpp b/Modbus_communication/Modbus_RTU_Salve/RTU_Salve.cpp index 326fa7e..7f07125 100644 --- a/Modbus_communication/Modbus_RTU_Salve/RTU_Salve.cpp +++ b/Modbus_communication/Modbus_RTU_Salve/RTU_Salve.cpp @@ -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(); diff --git a/Modbus_communication/Modbus_RTU_Salve/RTU_Salve.h b/Modbus_communication/Modbus_RTU_Salve/RTU_Salve.h index e1007fe..6683473 100644 --- a/Modbus_communication/Modbus_RTU_Salve/RTU_Salve.h +++ b/Modbus_communication/Modbus_RTU_Salve/RTU_Salve.h @@ -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); diff --git a/Modbus_communication/Modbus_RTU_Salve/common.cpp b/Modbus_communication/Modbus_RTU_Salve/common.cpp index d457ce6..159a6b7 100644 --- a/Modbus_communication/Modbus_RTU_Salve/common.cpp +++ b/Modbus_communication/Modbus_RTU_Salve/common.cpp @@ -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 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& 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; +} + diff --git a/Modbus_communication/Modbus_RTU_Salve/common.h b/Modbus_communication/Modbus_RTU_Salve/common.h index bd24071..7e5d743 100644 --- a/Modbus_communication/Modbus_RTU_Salve/common.h +++ b/Modbus_communication/Modbus_RTU_Salve/common.h @@ -12,17 +12,19 @@ #include 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 \ No newline at end of file diff --git a/Modbus_communication/Modbus_TCP/TCP_client.cpp b/Modbus_communication/Modbus_TCP/TCP_client.cpp index e37eb2b..7149df4 100644 --- a/Modbus_communication/Modbus_TCP/TCP_client.cpp +++ b/Modbus_communication/Modbus_TCP/TCP_client.cpp @@ -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"); diff --git a/Modbus_communication/Modbus_TCP/common.cpp b/Modbus_communication/Modbus_TCP/common.cpp index 858732d..bc874ad 100644 --- a/Modbus_communication/Modbus_TCP/common.cpp +++ b/Modbus_communication/Modbus_TCP/common.cpp @@ -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; }