瀏覽代碼

完成4个功能码响应报文生成以及对应功能码操作模块

Modbus_RTU
zcn1123 4 年之前
父節點
當前提交
dea4cfd14f
共有 3 個檔案被更改,包括 189 行新增30 行删除
  1. +167
    -30
      Modbus_communication/Modbus_RTU_Salve/RTU_Salve.cpp
  2. +21
    -0
      Modbus_communication/Modbus_RTU_Salve/common.cpp
  3. +1
    -0
      Modbus_communication/Modbus_RTU_Salve/common.h

+ 167
- 30
Modbus_communication/Modbus_RTU_Salve/RTU_Salve.cpp 查看文件

@@ -5,54 +5,191 @@ char read_buf[MAX_NUMBER];
bitset<MAX_Address> Coil_date; //0-9999
UINT16 Register[MAX_Address]; // 0-9999


/*********************************************************************************************
* 功能     :  生成正常响应报文
* 描述    : 经过校验后请求报文可以正常响应
* 输入 : *Requst_Message 请求报文 *Normal_Response_Message 正常响应报文
* 返回值 :
* 功能     :  Bitset转UINT8类型
* 描述    : Bitset ==》UINT8
* 输入 : Bitset_Address Bitset的起始地址 Read_Number 要读取的位数
* 返回值 : Date 转换后的UNIT8数据
**********************************************************************************************/
void Create_Normal_Response_Message(UINT8 *Requst_Message, UINT8 *Normal_Response_Message)
UINT8 Bitset_to_Uint8(unsigned int Bitset_Address, unsigned int Read_Number)
{
UINT8 Date = 0x00;
if (Read_Number >= 8)
{
unsigned int len = Bitset_Address + 8;
for (int i = 0; i < 8; i++)
{
Date = Date << 1 | (int)Coil_date[len--];
}
}
else
{
unsigned int len = Bitset_Address + Read_Number-1;
for (int i = 0; i < Read_Number; i++)
{
Date = Date << 1 | (int)Coil_date[len--];
}
}
return Date;
}


/*********************************************************************************************
* 功能     :  生成0x01功能码响应报文
* 描述    : 通过判断地址范围生成0x01对应的响应报文
* 输入 : *Requst_Message 请求报文 *Response_Message响应报文
* 返回值 : 无
**********************************************************************************************/
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 Read_Number = Requst_Message[4] << 8 | Requst_Message[5];//要读取的位数
unsigned int Read_Len = Count_Read_date_number(Requst_Message[0], 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[0] = Device_ID;
Response_Message[1] = Requst_Message[1];
Response_Message[2] = Read_Len+2; //响应报文中的后续字节数
}
else //地址超限
{
Response_Message[0] = Device_ID;
Response_Message[1] = Requst_Message[1] + 0x80;
Response_Message[2] = 0x02;
}
}

/*********************************************************************************************
* 功能     :  生成异常响应报文
* 描述    : 经过校验后请求报文可以正常响应
* 输入 : *Requst_Message 请求报文 *Normal_Response_Message 异常响应报文
* 功能     :  生成0x03功能码响应报文
* 描述    : 通过判断地址范围生成0x03对应的响应报文
* 输入 : *Requst_Message 请求报文 *Response_Message响应报文
* 返回值 : 无
**********************************************************************************************/
void Create_Abnormal_Response_Message(UINT8 *Requst_Message, UINT8 *Abnormal_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 Read_Number = Requst_Message[4] << 8 | Requst_Message[5];//要读取的寄存器数量
unsigned int Read_Len = Count_Read_date_number(Requst_Message[0], 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[0] = Device_ID;
Response_Message[1] = Requst_Message[1];
Response_Message[2] = Read_Len + 2; //响应报文中的后续字节数
}
else //地址超限
{
Response_Message[0] = Device_ID;
Response_Message[1] = Requst_Message[1] + 0x80;
Response_Message[2] = 0x02;
}
}


void Create_0x01_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message, unsigned int Address_range)
/*********************************************************************************************
* 功能     :  写入线圈
* 描述    : 将数据写入线圈中
* 输入 : Write_date_Message 要写入的数据 Write_Number要写入的位数 Start_Address起始地址
* 返回值 : 无
**********************************************************************************************/
void Write_Coil_date(UINT8 Write_date_Message, unsigned int Write_Number, unsigned int Start_Address)
{
if (Address_range > MAX_Address)
if (Write_Number >= 8)
{
int Read_Number = Requst_Message[4] << 8 | Requst_Message[5];

for (unsigned int i = Start_Address; i < Start_Address+8; i++)
{
Coil_date[i] = Write_date_Message & 1;
Write_date_Message >> 1;
}
}
else
{

for (unsigned int i = Start_Address; i < Start_Address + Write_Number; i++)
{
Coil_date[i] = Write_date_Message & 1;
Write_date_Message >> 1;
}
}
}
void Create_0x03_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message, unsigned int Address_range)
{

}
void Create_0x0F_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message, unsigned int Address_range)
/*********************************************************************************************
* 功能     :  生成0x0F功能码响应报文
* 描述    : 通过判断地址范围生成0x0F对应的响应报文
* 输入 : *Requst_Message 请求报文 *Response_Message响应报文
* 返回值 : 无
**********************************************************************************************/
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 Write_Number = Requst_Message[4] << 8 | Requst_Message[5];//要写入的位数
for (unsigned 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;
}
Response_Message[0] = Device_ID;
Response_Message[1] = Requst_Message[1];
Response_Message[2] = Requst_Message[2];
Response_Message[3] = Requst_Message[3];
Response_Message[4] = Requst_Message[4];
Response_Message[5] = Requst_Message[5];
}
else //地址超限
{
Response_Message[0] = Device_ID;
Response_Message[1] = Requst_Message[1] + 0x80;
Response_Message[2] = 0x02;
}
}
void Create_0x10_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message, unsigned int Address_range)
{

/*********************************************************************************************
* 功能     :  生成0x10功能码响应报文
* 描述    : 通过判断地址范围生成0x10对应的响应报文
* 输入 : *Requst_Message 请求报文 *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 Write_Number = Requst_Message[4] << 8 | Requst_Message[5];//要写入的寄存器个数
for (unsigned int i = 7; i < Requst_Message[6] + 7; i = i + 2)//执行写入寄存器操作
{
Register[Start_Address] = Requst_Message[i] << 8 | Requst_Message[i+1];
Start_Address++;
}
Response_Message[0] = Device_ID;
Response_Message[1] = Requst_Message[1];
Response_Message[2] = Requst_Message[2];
Response_Message[3] = Requst_Message[3];
Response_Message[4] = Requst_Message[4];
Response_Message[5] = Requst_Message[5];
}
else //地址超限
{
Response_Message[0] = Device_ID;
Response_Message[1] = Requst_Message[1] + 0x80;
Response_Message[2] = 0x02;
}
}


@@ -67,13 +204,13 @@ bool Create_Response_Message(UINT8 *Requst_Message, UINT8 *Response_Message)
{
if (Requst_Message[0] != Device_ID) //检查设备ID一致
return false;
unsigned int Address_range = (Requst_Message[2] << 8 | Requst_Message[3]) + (Requst_Message[4] << 8 | Requst_Message[5]);
switch (Requst_Message[1])
{
case 0x01:Create_0x01_Response_Message(Requst_Message, Response_Message, Address_range); break;
case 0x03:Create_0x03_Response_Message(Requst_Message, Response_Message, Address_range); break;
case 0x0F:Create_0x0F_Response_Message(Requst_Message, Response_Message, Address_range); break;
case 0x10:Create_0x10_Response_Message(Requst_Message, Response_Message, Address_range); break;
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:
}
return true;


+ 21
- 0
Modbus_communication/Modbus_RTU_Salve/common.cpp 查看文件

@@ -303,5 +303,26 @@ BYTE Input_Parity(void)
}


/*********************************************************************************************
* 功能    : 计算写入数据的字节数
* 描述   : 通过对应的功能码和操作数量计算对应的数据字节数
* 输入 : Function_code 选择的功能码类型 Operations_Number对应功能码类型的操作数量
* 输出 : Write_date_number 写入数据的字节数
*********************************************************************************************/
unsigned int Count_Read_date_number(int Function_code, unsigned int Operations_Number)
{
unsigned int Read_date_number = 0;
if (Function_code == 0x01) //读线圈
{
Read_date_number = Operations_Number / 8;
if (Operations_Number % 8)
Read_date_number++;
}
if (Function_code == 0x03)
Read_date_number = Operations_Number * 2;
return Read_date_number;
}





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

@@ -8,5 +8,6 @@ using namespace std;

#define MAX_NUMBER 300

unsigned int Count_Read_date_number(int Function_code, unsigned int Operations_Number);

#endif

Loading…
取消
儲存