Browse Source

整合功能模块,添加日志模块,添加响应报文解析模块

Modbus_TCP
zcn1123 4 years ago
parent
commit
740d52c585
5 changed files with 102 additions and 14 deletions
  1. +3
    -1
      Modbus_communication/Modbus_TCP/Modbus_TCP.vcxproj
  2. +2
    -0
      Modbus_communication/Modbus_TCP/Modbus_TCP_log.txt
  3. +51
    -11
      Modbus_communication/Modbus_TCP/TCP_client.cpp
  4. +43
    -1
      Modbus_communication/Modbus_TCP/common.cpp
  5. +3
    -1
      Modbus_communication/Modbus_TCP/common.h

+ 3
- 1
Modbus_communication/Modbus_TCP/Modbus_TCP.vcxproj View File

@@ -43,7 +43,9 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<SDLCheck>false</SDLCheck>
<BufferSecurityCheck>false</BufferSecurityCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>


+ 2
- 0
Modbus_communication/Modbus_TCP/Modbus_TCP_log.txt View File

@@ -0,0 +1,2 @@
2020-9-1 14:23:15 Send:00 00 00 00 00 06 09 01 00 00 00 09
2020-9-1 14:23:17 Recv:00 00 00 00 00 05 10 01 02 FF 01

+ 51
- 11
Modbus_communication/Modbus_TCP/TCP_client.cpp View File

@@ -101,10 +101,10 @@ SOCKET Init_client(string IP, unsigned int Port_number)
cout << "尝试连接TCP从站失败" << endl;
}
cout << "连接TCP从站成功" << endl;
TIMEVAL timeout;
timeout.tv_sec = 2000; //ms
timeout.tv_usec = 0; //us
setsockopt(ClientSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval));//设置接收超时时间
//TIMEVAL timeout;
//timeout.tv_sec = 2000; //ms
//timeout.tv_usec = 0; //us
//setsockopt(ClientSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval));//设置接收超时时间
return ClientSocket;
}

@@ -134,33 +134,69 @@ void Clear_recv_buf(SOCKET clientSocket)
}
}

void Printf_Coil_date(UINT8 *Response_Message)
void Printf_Coil_date(UINT8 *Response_Message, UINT8 *Request_Message)
{

printf("从站设备ID %02X 功能码为 %02X\n", Response_Message[6], Response_Message[7]);
unsigned int temp1 = ((Request_Message[8] << 8) | Request_Message[9])+1;
unsigned int Number = ((Request_Message[10] << 8) | Request_Message[11]);
printf("线圈起始地址为%d \n",temp1);
unsigned int temp = temp1;
for (int i = 0; i < Response_Message[8]; i++)
{
unsigned int temp2 = temp + 7;
if (temp2 > temp1 + Number - 1)
temp2 = temp1 + Number - 1;
printf("线圈第%d --- %d的状态为:%02X \n", temp2, temp, Response_Message[9+i]);
temp = temp + 8;
}
}

void Printf_Register_date(UINT8 *Response_Message)
void Printf_Register_date(UINT8 *Response_Message, UINT8 *Request_Message)
{
printf("从站设备ID %02X 功能码为 %02X\n", Response_Message[6], Response_Message[7]);
unsigned int temp1 = ((Request_Message[8] << 8) | Request_Message[9]) + 1;
unsigned int Number = ((Request_Message[10] << 8) | Request_Message[11]);
printf("寄存器起始地址为%d \n", temp1);
for (int i = 0; i < Response_Message[8]; i = i + 2)
{
printf("寄存器第%d的值为:%02X %02X \n", temp1++, Response_Message[9 + i], Response_Message[10+i]);
}

}
void Printf_Anomaly_date(UINT8 *Response_Message)
{

UINT8 a = Response_Message[8];
printf("从站设备ID %02X 功能码为 %02X\n", Response_Message[6], Response_Message[7]);
switch (a)
{
case 0x01: printf("%02X : 从站设备不支持此功能码",a); break;
case 0x02: printf("%02X : 指定的数据地址在从站设备中不存在",a); break;
case 0x03: printf("%02X : 指定的数据超过范围或者不允许使用",a); break;
case 0x04: printf("%02X : 从站设备处理响应的过程中,出现未知错误等",a); break;
default: printf("Unkown Other Error!!!!!");
}
}

k


bool Analysis_Response_Message(UINT8 *Response_Message, UINT8 *Request_Message, int Response_Message_len)
{
if (Response_Message[7] == Request_Message[7] + 0x80 && Response_Message_len == 9)//先处理异常响应
{
Printf_Anomaly_date(Response_Message);
return true;
}
else if (Response_Message[6] == Request_Message[6] && Response_Message_len - 5 == Response_Message[5]) //判断是否是正常响应帧
{

if (Response_Message[7] == 0x01)
Printf_Coil_date(Response_Message, Request_Message);
if (Response_Message[7] == 0x03)
Printf_Register_date(Response_Message, Request_Message);
if (Response_Message[7] == 0x10)
printf("成功写入从站线圈%d个", ((Request_Message[10] << 8) | Request_Message[11]));
if (Response_Message[7] == 0x0F)
printf("成功写入从站寄存器%d个" ,((Request_Message[10] << 8) | Request_Message[11]));
return true;
}
return false;
@@ -197,18 +233,22 @@ bool Tcp_client(string IP, unsigned int Port_number)
printf("%02x ", Request_Message[i]);
}
printf("\n");
Log_Note(Request_Message, 1, Message_len);
Clear_recv_buf(ClientSocket);
send(ClientSocket, (char*)Request_Message, Message_len, 0);
memset(Response_Message, 0, 260);
int ret = recv(ClientSocket, (char*)Response_Message, 260, 0);
if (ret > 0)
{
Log_Note(Response_Message, 0, ret);
printf("从站响应 :");
for (int i = 0; i < ret; i++)
{
printf("%02x ", Response_Message[i]);
}
printf("\n");
if (Analysis_Response_Message(Response_Message, Request_Message, ret))
printf("响应报文异常\n\n");
}
else
cout << "响应超时" << endl;


+ 43
- 1
Modbus_communication/Modbus_TCP/common.cpp View File

@@ -228,7 +228,7 @@ int HexStringtoByte(UINT8 *Message, string Write_date, int Message_len)
if (Write_date.length() == 0)
return Message_len;
const char *b = Write_date.c_str();
for (int i = 0; i + 3 < Write_date.length(); i = i + 3)
for (unsigned int i = 0; i + 3 < Write_date.length(); i = i + 3)
{
sscanf_s(b + i, "%02X", (int *)(Message + Message_len));
Message_len++;
@@ -257,3 +257,45 @@ int Crate_TCP_Message(UINT8 *Message, int Function_code, unsigned int Operations
return HexStringtoByte(Message, Write_date, 12);
}

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;
}

+ 3
- 1
Modbus_communication/Modbus_TCP/common.h View File

@@ -7,10 +7,11 @@
#include <vector>
#include <string>
#include <iostream>
#include <time.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;

#define DEVICE_ID 0x10 //É豸ID
#define DEVICE_ID 0x09 //É豸ID



@@ -23,6 +24,7 @@ string Input_Write_date(int Function_code, unsigned int Operations_Number);
void Crate_MBAP(UINT8 *Message, int Function_code, unsigned int Operations_Number);
int HexStringtoByte(UINT8 *Message, string Write_date, int Message_len);
int Crate_TCP_Message(UINT8 *Message, int Function_code, unsigned int Operations_Number, unsigned int Starting_address, string Write_date);
void Log_Note(UINT8 *Message, int flage, int Message_len);


#endif

Loading…
Cancel
Save