Files
Leakage-Control/calib_board/usr/protocol/proto_modbus_slave_ex.c
2026-01-22 19:24:33 +08:00

363 lines
12 KiB
C

/*对外通讯 modbus从机*/
#include "proto_modbus_slave_ex.h"
#include "string.h"
#include "stdio.h"
#include "app.h"
#include "os_timer.h"
#include "bsp_Uart.h"
#include "bsp_Flash.h"
#include "proto_print.h"
#include "proto_modbus_master_tdlas.h"
static modbus_analysis_data_t modbus_analysis_data;//指令解析结构体
static modbus_communication_send_buf_t send_struct;//发送结构体
static void proto_modbus_communication_data_analysis(u8 *pData, u16 len, void *data);
static void proto_modbus_communication_data_send(u8 *pData, u16 len);
static void proto_modbus_init(void);
static void proto_modbus_task(void);
static modbus_error_code_e proto_modbus_data_write(u16 Addr, u16 Value);
static u16 proto_modbus_data_read(u16 Addr);
proto_Modbus_t modbus_slave_ex=
{
.id = 0x01,
.data_read = proto_modbus_data_read,
.data_write = proto_modbus_data_write,
.data_analysis = proto_modbus_communication_data_analysis,
.init = proto_modbus_init,
.task = proto_modbus_task,
};
static proto_Modbus_t *p_modbus = &modbus_slave_ex;
static bsp_Uart_t * rx_uart;
static void proto_modbus_communication_data_send(u8 *pData, u16 len)
{
if(&COM_Uart1 == rx_uart)
{
COM_Uart1.Send(&COM_Uart1,pData,len);
}
else if(&COM_Uart4 == rx_uart)
{
COM_Uart4.Send(&COM_Uart4,pData,len);
}
}
static void proto_modbus_init(void)
{
p_modbus->id = Usr_Flash.FlashData.modbus_id;
COM_Uart1.Rx_DataAnalysis = proto_modbus_communication_data_analysis;
COM_Uart4.Rx_DataAnalysis = proto_modbus_communication_data_analysis;
}
static void proto_modbus_task(void)
{
}
static void proto_modbus_communication_data_analysis(u8 *pData, u16 len,void *other_data)
{
modbus_error_code_e error_code;
u16 inx;
u16 TempAddr, TempData, crc_16;
if (0 == modbus_lib_analysis(&modbus_analysis_data, pData, len))//检查数据长度 校验是否正确
return;
if (p_modbus->id != modbus_analysis_data.id && modbus_analysis_data.id != 0xe8)//判断ID是否正确
return;
error_code = ModbusErrorCode_Success;
/* //检查地址是否超出范围
if ((modbus_analysis_data.start_addr >= MODBUS_REG_LEN) || (modbus_analysis_data.reg_number >= MODBUS_REG_LEN) ||
(modbus_analysis_data.start_addr + modbus_analysis_data.reg_number >= MODBUS_REG_LEN))
{
ErrorCode = ModbusErrorCode_IllegalAddr;
goto Error;
}
*/
rx_uart = (bsp_Uart_t*)other_data;
switch (modbus_analysis_data.func)
{
case 0x03:
case 0x04:
{
TempAddr = modbus_analysis_data.start_addr;
send_struct.send_buffer[0] = modbus_analysis_data.id;
send_struct.send_buffer[1] = modbus_analysis_data.func;
send_struct.send_buffer[2] = 2 * modbus_analysis_data.reg_number;
for (inx = 0; inx < modbus_analysis_data.reg_number; inx++)
{
TempData = proto_modbus_data_read(TempAddr);
send_struct.send_buffer[3 + 2 * inx] = (TempData >> 8) & 0xff;
send_struct.send_buffer[4 + 2 * inx] = TempData & 0xff;
TempAddr++;
}
crc_16 = modbus_lib_crc16(send_struct.send_buffer, 3 + send_struct.send_buffer[2]);
send_struct.send_buffer[3 + send_struct.send_buffer[2]] = crc_16 & 0xff;
send_struct.send_buffer[4 + send_struct.send_buffer[2]] = (crc_16 >> 8) & 0xff;
send_struct.len = 5 + send_struct.send_buffer[2];
}goto Success;
/*特殊协议*/
case 0x41:
{
TempAddr = modbus_analysis_data.start_addr;
send_struct.send_buffer[0] = modbus_analysis_data.id;
send_struct.send_buffer[1] = modbus_analysis_data.func;
send_struct.send_buffer[2] = modbus_analysis_data.start_addr >> 8;
send_struct.send_buffer[3] = modbus_analysis_data.start_addr & 0xff;
send_struct.send_buffer[4] = (2 * modbus_analysis_data.reg_number) >> 8;
send_struct.send_buffer[5] = (2 * modbus_analysis_data.reg_number) & 0xff;
for (inx = 0; inx < modbus_analysis_data.reg_number; inx++)
{
TempData = proto_modbus_data_read(TempAddr);
send_struct.send_buffer[6 + 2 * inx] = (TempData >> 8) & 0xff;
send_struct.send_buffer[7 + 2 * inx] = TempData & 0xff;
TempAddr++;
}
crc_16 = modbus_lib_crc16(send_struct.send_buffer, 6 + 2 * modbus_analysis_data.reg_number);
send_struct.send_buffer[6 + 2 * modbus_analysis_data.reg_number] = crc_16 & 0xff;
send_struct.send_buffer[7 + 2 * modbus_analysis_data.reg_number] = (crc_16 >> 8) & 0xff;
send_struct.len = 8 + 2 * modbus_analysis_data.reg_number;
}goto Success;
case 0x06:
{
TempAddr = modbus_analysis_data.start_addr;
TempData = (modbus_analysis_data.write_data_addr[0] << 8) | modbus_analysis_data.write_data_addr[1];
error_code = proto_modbus_data_write(TempAddr, TempData);
if (error_code)
{
goto Error;
}
send_struct.len = 8;
send_struct.send_buffer[0] = modbus_analysis_data.id;
send_struct.send_buffer[1] = modbus_analysis_data.func;
send_struct.send_buffer[2] = modbus_analysis_data.start_addr >> 8;
send_struct.send_buffer[3] = modbus_analysis_data.start_addr & 0xff;
send_struct.send_buffer[4] = modbus_analysis_data.write_data_addr[0];
send_struct.send_buffer[5] = modbus_analysis_data.write_data_addr[1];
crc_16 = modbus_lib_crc16(send_struct.send_buffer, 6);
send_struct.send_buffer[6] = crc_16 & 0xff;
send_struct.send_buffer[7] = (crc_16 >> 8) & 0xff;
}break;
case 0x10:
{
TempAddr = modbus_analysis_data.start_addr;
for (inx = 0; inx < modbus_analysis_data.reg_number; inx++)
{
TempData = modbus_analysis_data.write_data_addr[2 * inx];
TempData = (TempData << 8) | modbus_analysis_data.write_data_addr[2 * inx + 1];
error_code = proto_modbus_data_write(TempAddr, TempData);
TempAddr++;
if (error_code)
{
goto Error;
}
}
send_struct.len = 8;
send_struct.send_buffer[0] = modbus_analysis_data.id;
send_struct.send_buffer[1] = modbus_analysis_data.func;
send_struct.send_buffer[2] = modbus_analysis_data.start_addr >> 8;
send_struct.send_buffer[3] = modbus_analysis_data.start_addr & 0xff;
send_struct.send_buffer[4] = modbus_analysis_data.reg_number >> 8;
send_struct.send_buffer[5] = modbus_analysis_data.reg_number & 0xff;
crc_16 = modbus_lib_crc16(send_struct.send_buffer, 6);
send_struct.send_buffer[6] = crc_16 & 0xff;
send_struct.send_buffer[7] = (crc_16 >> 8) & 0xff;
}
break;
default:
{
error_code = ModbusErrorCode_IllegalFunction;
}
goto Error;
}
Success:
proto_modbus_communication_data_send(send_struct.send_buffer, send_struct.len);
return;
Error:
send_struct.len = 5;
send_struct.send_buffer[0] = modbus_analysis_data.id;
send_struct.send_buffer[1] = modbus_analysis_data.func | 0x80;
send_struct.send_buffer[2] = error_code;
crc_16 = modbus_lib_crc16(send_struct.send_buffer, 3);
send_struct.send_buffer[3] = crc_16 & 0xff;
send_struct.send_buffer[4] = (crc_16 >> 8) & 0xff;
proto_modbus_communication_data_send(send_struct.send_buffer, send_struct.len);
}
/******************************************
* 函数: proto_modbus_data_write
* 功能: Modbus写寄存器
* 参数: Addr: 地址
Value:数据
* 返回: 无
* 描述: 无
******************************************/
static modbus_error_code_e proto_modbus_data_write(u16 addr, u16 data)
{
modbus_error_code_e error_code;
u8 temp_point,cali_point;
error_code = ModbusErrorCode_Success;
switch(addr)
{
/*温度 压力 湿度*/
case 11000:
{
tdlas.control.fac_calib_para_set(*((u16 *)(&data)),0xffff,0xffff);
}break;
case 11001:
{
tdlas.control.fac_calib_para_set(0xffff,data,0xffff);
}break;
case 11002:
{
tdlas.control.fac_calib_para_set(0xffff,0xffff,data);
}break;
/*零点校准*/
case 11003:
{
tdlas.control.zero_calib(0);
}break;
/*量程点校准*/
case 11004:
{
tdlas.control.span_calib(data);
}break;
/*厂家标定*/
case 11010 ... 11109:
{
temp_point = (addr - 11010) / 10;
cali_point = (addr - 11010) % 10;
tdlas.control.fac_calib(data,cali_point,temp_point);
}break;
/*转发传感器标定信息*/
case 11200:
{
tdlas.control.fac_calib_data_get(data);
}break;
/*sn*/
case 20000 ... 20004:
{
Usr_Flash.FlashData.sn[addr - 20000] = data;
Usr_Flash.Write();
}break;
/*modbus_id*/
case 20005:
{
Usr_Flash.FlashData.modbus_id = data;
modbus_slave_ex.id = Usr_Flash.FlashData.modbus_id;
Usr_Flash.Write();
}break;
/*modbus_read_reg_num*/
case 20006:
{
if(data > 1000)
{
error_code = ModbusErrorCode_IllegalData;
}
else
{
Usr_Flash.FlashData.modbus_read_reg_num = data;
Usr_Flash.Write();
}
}break;
case 20007:
{
if(data > 16)
{
error_code = ModbusErrorCode_IllegalData;
}
else
{
Usr_Flash.FlashData.modbus_read_sensor_num = data;
Usr_Flash.Write();
}
}break;
/*FC打印相关数据*/
case 252:
{
print.set(data);
}break;
}
return error_code;
}
/******************************************
* 函数: proto_modbus_data_read
* 功能: Modbus读寄存器数据
* 参数: Addr: 地址
* 返回: 地址对应的数据
* 描述: 无
******************************************/
static u16 proto_modbus_data_read(u16 addr)
{
u16 data = 0;
u16 *p_data;
u16 num,offset;
switch(addr)
{
/*实时数据*/
case 0 ... 639:
{
u16 size;
size = sizeof(gas_data_t);
/* TDLAS默认读取*/
if( size== (2 * Usr_Flash.FlashData.modbus_read_reg_num))
{
p_data = (u16 *)&gas_data;
data = p_data[addr];
}
else if((2 * Usr_Flash.FlashData.modbus_read_reg_num )< sizeof(gas_data_t))/*其他传感器*/
{
num = addr / Usr_Flash.FlashData.modbus_read_reg_num;
offset = addr % Usr_Flash.FlashData.modbus_read_reg_num;
p_data = (u16 *)&gas_data[num];
data = p_data[offset];
}
}break;
/*sn*/
case 20000 ... 20004:
{
data = Usr_Flash.FlashData.sn[addr - 20000];
}break;
/*modbus_id*/
case 20005:
{
data = Usr_Flash.FlashData.modbus_id;
}break;
/*modbus_read_reg_num*/
case 20006:
{
data = Usr_Flash.FlashData.modbus_read_reg_num;
}break;
case 20007:
{
data = Usr_Flash.FlashData.modbus_read_sensor_num;
}break;
default:data = 0;
}
return data;
}