Files
Leakage-Control/calib_board/usr/protocol/proto_modbus_master_tdlas.c
2026-02-09 17:55:33 +08:00

506 lines
16 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "proto_modbus_master_tdlas.h"
#include "string.h"
#include "stdio.h"
#include "app.h"
#include "app_timer.h"
#include "bsp_Uart.h"
#include "bsp_74HC4067.h"
#include "bsp_Flash.h"
#include "app_leakage.h"
#include "proto_print.h"
#include "proto_modbus_lib.h"
#define TDLAS_MODBUS_ID (0xe8)
#define TDLAS_DATA_ENDIAN (LITTLE_ENDIAN) /*配置大小端序*/
#define PROTO_LEAKAGE_READ_DATA_NUM (14) /*读取一个设备寄存器数量*/
#define PROTO_TDLAS_GET_CURR_DATA_START_ADDR (0x0000)
#define PROTO_TDLAS_SET_ZERO_CALIB_START_ADDR (12)
#define PROTO_TDLAS_SET_SPAN_CALIB_START_ADDR (13)
#define PROTO_TDLAS_GET_RESET_START_ADDR (0x0000)
#define PROTO_TDLAS_GET_FAC_CALIB_START_ADDR (11010)
#define PROTO_TDLAS_GET_FAC_CALIB_PARA_SET_START_ADDR (11000)
#define PROTO_TDLAS_GET_FAC_CALIB_DATA_START_ADDR (250)
static void proto_tdlas_init(void);
static void proto_tdlas_control_zero_calib(u16 calib_value);
static void proto_tdlas_control_span_calib(u16 CalibValue);
static void proto_tdlas_control_reset(void);
static void proto_tdlas_control_fac_calib(u16 calib_value,u8 calib_point,u8 temp_point);
static void proto_tdlas_control_fac_calib_para_set(s16 temp,u16 press,u16 humidity);
static void proto_tdlas_tx_task(void);
static void proto_tdlas_rx_task(u8 *p_data,u16 len,void *other_data);
static void proto_tdlas_control_fac_calib_data_get(u8 ch);
/*是哪个串口接收的数据*/
static bsp_uart_t *rx_uart = NULL;
proto_tdlas_t tdlas=
{
.modbus_id = TDLAS_MODBUS_ID,
.init = proto_tdlas_init,
.tx_task = proto_tdlas_tx_task,
.rx_task = proto_tdlas_rx_task,
// .print = proto_tdlas_print_debug_data,
.control.zero_calib = proto_tdlas_control_zero_calib,
.control.span_calib = proto_tdlas_control_span_calib,
.control.reset = proto_tdlas_control_reset,
.control.fac_calib = proto_tdlas_control_fac_calib,
.control.fac_calib_para_set = proto_tdlas_control_fac_calib_para_set,
.control.fac_calib_data_get = proto_tdlas_control_fac_calib_data_get,
};
proto_tdlas_t *p_sensor = &tdlas;
bsp_uart_t *p_use_uart = &com_uart4;
static void proto_tdlas_init(void)
{
com_uart4.rx_data_analysis = p_sensor->rx_task;
}
static void proto_tdlas_send(u8 *p_data,u16 len)
{
com_uart4.send(&com_uart4,p_data,len);
}
static void proto_sensor_switch(u8 ch)
{
UartCH_Config.ch_set(ch);
}
/*零点校准*/
static void proto_tdlas_control_zero_calib(u16 calib_value)
{
u8 i;
for(i=0;i<Usr_Flash.FlashData.modbus_read_sensor_num;i++)
{
p_sensor->sys[i].sys_state = PROTO_TDLAS_SYS_STATE_ZERO_CALIB;
p_sensor->set_data.calib_value = calib_value;
}
}
/*量程校准 */
static void proto_tdlas_control_span_calib(u16 CalibValue)
{
u8 i;
for(i=0;i<Usr_Flash.FlashData.modbus_read_sensor_num;i++)
{
p_sensor->sys[i].sys_state = PROTO_TDLAS_SYS_STATE_SPAN_CALIB;
p_sensor->set_data.calib_value = CalibValue;
}
}
/*恢复出厂设置 */
static void proto_tdlas_control_reset(void)
{
u8 i;
for(i=0;i<Usr_Flash.FlashData.modbus_read_sensor_num;i++)
{
p_sensor->sys[i].sys_state = PROTO_TDLAS_SYS_STATE_RESET;
}
}
/*厂家标定*/
static void proto_tdlas_control_fac_calib(u16 calib_value,u8 calib_point,u8 temp_point)
{
u8 i;
for(i=0;i<Usr_Flash.FlashData.modbus_read_sensor_num;i++)
{
p_sensor->sys[i].sys_state = PROTO_TDLAS_SYS_STATE_FAC_CALIB;
p_sensor->set_data.calib_value = calib_value;
p_sensor->set_data.calib_point = calib_point;
p_sensor->set_data.temp_point = temp_point;
}
}
/*环境参数设置*/
static void proto_tdlas_control_fac_calib_para_set(s16 temp,u16 press,u16 humidity)
{
u8 i;
for(i=0;i<Usr_Flash.FlashData.modbus_read_sensor_num;i++)
{
p_sensor->sys[i].sys_state = PROTO_TDLAS_SYS_STATE_FAC_CALIB_PARA_SET;
p_sensor->set_data.temp = (-1 == temp) ? p_sensor->set_data.temp : temp;
p_sensor->set_data.humidity = (0xffff == humidity) ? p_sensor->set_data.humidity : humidity;
p_sensor->set_data.press = (0xffff == press) ? p_sensor->set_data.press : press;
}
}
/*获取标定数据*/
static void proto_tdlas_control_fac_calib_data_get(u8 ch)
{
if(Usr_Flash.FlashData.modbus_read_sensor_num > ch)
{
p_sensor->sensor_index = ch;
p_sensor->sys[ch].sys_state = PROTO_TDLAS_SYS_STATE_FAC_CALIB_DATA_GET;
proto_sensor_switch(ch);
}
}
/********发送***********/
static void proto_tdlas_tx_curr_data_get(void)
{
u16 addr = PROTO_TDLAS_GET_CURR_DATA_START_ADDR;
u8 len = PROTO_LEAKAGE_READ_DATA_NUM;
modbus_lib_data_read(p_sensor->modbus_id,addr,len,proto_tdlas_send);
}
static void proto_tdlas_tx_zero_calib(void)
{
u16 addr = PROTO_TDLAS_SET_ZERO_CALIB_START_ADDR;
u8 len = 1;
u16 data[1];
data[0] = 0;
modbus_lib_multiple_data_write(p_sensor->modbus_id,addr,len,data,proto_tdlas_send);
}
static void proto_tdlas_tx_span_calib(void)
{
u16 addr = PROTO_TDLAS_SET_SPAN_CALIB_START_ADDR;
u8 len = 1;
u16 data[1];
data[0] = p_sensor->set_data.calib_value;
modbus_lib_multiple_data_write(p_sensor->modbus_id,addr,len,data,proto_tdlas_send);
}
static void proto_tdlas_tx_Reset(void)
{
u16 addr = PROTO_TDLAS_GET_RESET_START_ADDR;
u8 len = 1;
u16 data[1];
data[0] = 0x00FE;
//modbus_lib_multiple_data_write(p_sensor->modbus_id,addr,len,data,proto_tdlas_send);
}
static void proto_tdlas_tx_fac_calib(void)
{
u16 addr = PROTO_TDLAS_GET_FAC_CALIB_START_ADDR;
u8 len = 1;
u16 data[1];
data[0] = p_sensor->set_data.calib_value;
addr = addr + p_sensor->set_data.temp_point * 10 + p_sensor->set_data.calib_point;
modbus_lib_multiple_data_write(p_sensor->modbus_id,addr,len,data,proto_tdlas_send);
}
static void proto_tdlas_tx_fac_calib_para_set(void)
{
u16 addr = PROTO_TDLAS_GET_FAC_CALIB_PARA_SET_START_ADDR;
u8 len = 3;
u16 data[3];
data[0] = *((u16 *)(&p_sensor->set_data.temp)); /*温度*/
data[1] = p_sensor->set_data.press; /*压力*/
data[2] = p_sensor->set_data.humidity; /*湿度*/
modbus_lib_multiple_data_write(p_sensor->modbus_id,addr,len,data,proto_tdlas_send);
}
static void proto_tdlas_tx_fac_calib_data_get(void)
{
u16 addr = PROTO_TDLAS_GET_FAC_CALIB_DATA_START_ADDR;
u8 len = 1;
u16 data[1];
data[0] = 3; /*温度*/
modbus_lib_multiple_data_write(p_sensor->modbus_id,addr,len,data,proto_tdlas_send);
}
static void proto_tdlas_tx_task(void)
{
u8 SendFlag = 0;
proto_tdlas_sys_t *p_sensor_sys;
p_sensor_sys = &p_sensor->sys[p_sensor->sensor_index];
if(0 == (p_sensor_sys->state_error_flag & (0x00000001 << PROTO_TDLAS_ERROR_FLAG_TIME_OUT)))
{
if((++p_sensor_sys->tx_time_out_count) > 8)/*通讯超时*/
{
p_sensor_sys->state_error_flag |= (0x00000001 << PROTO_TDLAS_ERROR_FLAG_TIME_OUT);
/*清除数据*/
memset(&gas_data[p_sensor->sensor_index],0,sizeof(gas_data_t));
}
}
switch(p_sensor_sys->sys_state)
{
case PROTO_TDLAS_SYS_STATE_INIT:
{
}break;
case PROTO_TDLAS_SYS_STATE_CURR_DATA_GET:
{
proto_tdlas_tx_curr_data_get();
}break;
case PROTO_TDLAS_SYS_STATE_ZERO_CALIB:
{
proto_tdlas_tx_zero_calib();
}break;
case PROTO_TDLAS_SYS_STATE_SPAN_CALIB:
{
proto_tdlas_tx_span_calib();
}break;
case PROTO_TDLAS_SYS_STATE_RESET:
{
proto_tdlas_tx_Reset();
}break;
case PROTO_TDLAS_SYS_STATE_FAC_CALIB:
{
proto_tdlas_tx_fac_calib();
}break;
case PROTO_TDLAS_SYS_STATE_FAC_CALIB_PARA_SET:
{
proto_tdlas_tx_fac_calib_para_set();
}break;
case PROTO_TDLAS_SYS_STATE_FAC_CALIB_DATA_GET:
{
if(0 == p_sensor_sys->send_time)
{
p_use_uart->relay.flag = 1;
proto_tdlas_tx_fac_calib_data_get();
}
p_sensor_sys->send_time++;
if(p_sensor_sys->send_time > 50)
{
p_use_uart->relay.flag = 0;
p_sensor_sys->send_time = 0;
p_sensor_sys->sys_state = PROTO_TDLAS_SYS_STATE_CURR_DATA_GET;
p_sensor->sensor_index++;
if(p_sensor->sensor_index >= Usr_Flash.FlashData.modbus_read_sensor_num)
{
p_sensor->sensor_index = 0;
}
proto_sensor_switch(p_sensor->sensor_index);
}
SendFlag = 1;
}break;
default:
{
}break;
}
if(SendFlag)
{
return ;
}
else
{
p_sensor_sys->send_time++;
if(p_sensor_sys->send_time >= 3) /*进入异常*/
{
p_sensor_sys->state_error_flag |= (0x00000001 << p_sensor_sys->sys_state);/*记录异常状态*/
p_sensor_sys->send_time = 0;
p_sensor_sys->sys_state = PROTO_TDLAS_SYS_STATE_CURR_DATA_GET;
p_sensor->sensor_index++;
if(p_sensor->sensor_index >= Usr_Flash.FlashData.modbus_read_sensor_num)
{
p_sensor->sensor_index = 0;
}
proto_sensor_switch(p_sensor->sensor_index);
}
}
}
static void proto_tdlas_rx_task(u8 *p_data,u16 len,void *other_data)
{
u8 send_time_flag = 0;
u8 modbus_id,cmd;
u16 check_crc16,modbus_crc16;
u16 *p_u16_temp;
u16 i,ch;
u8 *p_rx_valid,temp_value;
proto_tdlas_sys_t *p_sensor_sys;
p_sensor_sys = &p_sensor->sys[p_sensor->sensor_index];
if( p_use_uart->relay.flag == 1)
{
p_use_uart->relay.uart->send(p_use_uart->relay.uart,p_data,len);
}
if(p_sensor->modbus_id != p_data[0])
{
p_data = &p_data[1];
len -= 1;
}
modbus_id = *p_data;
cmd = *(p_data+1);
check_crc16 = p_data[len-2] << 8 | p_data[len-1];
if(modbus_id != p_sensor->modbus_id) return ;
if(cmd != 0x03 && cmd != 0x06 && cmd != 0x10 && cmd != 0x41) return ;
modbus_crc16 = modbus_lib_crc16(p_data,len-2);
modbus_crc16 = (modbus_crc16 >> 8) | (modbus_crc16 << 8);
if(check_crc16 != modbus_crc16) return ;
if(cmd == 0x41)
{
p_rx_valid = &p_data[6];
}
u8 byte_count = p_data[3];
p_rx_valid = &p_data[3];
rx_uart = (bsp_uart_t *)other_data;
p_sensor_sys->tx_time_out_count = 0;
p_sensor_sys->state_error_flag &= (~(0x00000001 << PROTO_TDLAS_ERROR_FLAG_TIME_OUT));
switch(p_sensor_sys->sys_state)
{
case PROTO_TDLAS_SYS_STATE_INIT:
{
}break;
case PROTO_TDLAS_SYS_STATE_CURR_DATA_GET:
{
/*计算当前设备索引*/
u8 device_global_idx = p_sensor->sensor_index;
if(device_global_idx >= APP_LEAKAGE_SUB_DEVICE_NUM)
{
break;
}
/*通道数据重置*/
for(ch = 0;ch < APP_LEAKAGE_SUB_DEVICE_CH_NUM;ch++)
{
p_leakage->sub_device_data[device_global_idx].ch_data[ch].state = 0;
p_leakage->sub_device_data[device_global_idx].ch_data[ch].state = 0;
}
if(byte_count >=28)
{
ch = 0;
temp_value = (p_rx_valid[0] << 8) | p_rx_valid[1];
if(temp_value == 1) {
p_leakage->sub_device_data[device_global_idx].ch_data[ch].state |=
APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE;
}
temp_value = (p_rx_valid[2] << 8) | p_rx_valid[3];
if(temp_value == 1) {
p_leakage->sub_device_data[device_global_idx].ch_data[ch].state |=
APP_LEAKAGE_SUB_DEVICE_STATE_OPEN;
}
temp_value = (p_rx_valid[4] << 8) | p_rx_valid[5];
p_leakage->sub_device_data[device_global_idx].ch_data[ch].distance = temp_value *0.01;
/* 心跳包0x0003*/
temp_value = (p_rx_valid[6] << 8) | p_rx_valid[7];
p_leakage->sub_device_data[device_global_idx].heartbeat = temp_value & 0xFF;
/*通道20x0004-0x0006*/
ch = 1;
temp_value = (p_rx_valid[8] << 8) | p_rx_valid[9];
if(temp_value == 1) {
p_leakage->sub_device_data[device_global_idx].ch_data[ch].state |=
APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE;
}
temp_value = (p_rx_valid[10] << 8) | p_rx_valid[11];
if(temp_value == 1) {
p_leakage->sub_device_data[device_global_idx].ch_data[ch].state |=
APP_LEAKAGE_SUB_DEVICE_STATE_OPEN;
}
temp_value = (p_rx_valid[12] << 8) | p_rx_valid[13];
p_leakage->sub_device_data[device_global_idx].ch_data[ch].distance = temp_value *0.01;
/*测试模式0x0007*/
temp_value = (p_rx_valid[14] << 8) | p_rx_valid[15];
p_leakage->sub_device_data[device_global_idx].test_mode = temp_value & 0xFF;
/*通道30x0008-0x000A*/
ch = 2;
temp_value = (p_rx_valid[16] << 8) | p_rx_valid[17];
if(temp_value == 1) {
p_leakage->sub_device_data[device_global_idx].ch_data[ch].state |=
APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE;
}
temp_value = (p_rx_valid[18] << 8) | p_rx_valid[19];
if(temp_value == 1) {
p_leakage->sub_device_data[device_global_idx].ch_data[ch].state |=
APP_LEAKAGE_SUB_DEVICE_STATE_OPEN;
}
temp_value = (p_rx_valid[20] << 8) | p_rx_valid[21];
p_leakage->sub_device_data[device_global_idx].ch_data[ch].distance = temp_value *0.01;
/* 通道40x000B-0x000D*/
ch = 3;
temp_value = (p_rx_valid[22] << 8) | p_rx_valid[23];
if(temp_value == 1) {
p_leakage->sub_device_data[device_global_idx].ch_data[ch].state |=
APP_LEAKAGE_SUB_DEVICE_STATE_LEAKAGE;
}
temp_value = (p_rx_valid[24] << 8) | p_rx_valid[25];
if(temp_value == 1) {
p_leakage->sub_device_data[device_global_idx].ch_data[ch].state |=
APP_LEAKAGE_SUB_DEVICE_STATE_OPEN;
}
temp_value = (p_rx_valid[26] << 8) | p_rx_valid[27];
p_leakage->sub_device_data[device_global_idx].ch_data[ch].distance = temp_value *0.01;
}
}break;
case PROTO_TDLAS_SYS_STATE_ZERO_CALIB:
{
}break;
case PROTO_TDLAS_SYS_STATE_SPAN_CALIB:
{
}break;
case PROTO_TDLAS_SYS_STATE_RESET:
{
}break;
case PROTO_TDLAS_SYS_STATE_FAC_CALIB:
{
}break;
case PROTO_TDLAS_SYS_STATE_FAC_CALIB_PARA_SET:
{
}break;
case PROTO_TDLAS_SYS_STATE_FAC_CALIB_DATA_GET:
{
}break;
}
if(send_time_flag)
{
return;
}
else
{
p_sensor_sys->sys_state = PROTO_TDLAS_SYS_STATE_CURR_DATA_GET;
p_sensor_sys->state_error_flag &= (~(0x00000001 << p_sensor_sys->sys_state));/*消除异常状态*/
p_sensor_sys->send_time = 0;
p_sensor->sensor_index++;
if(p_sensor->sensor_index >= Usr_Flash.FlashData.modbus_read_sensor_num)
{
p_sensor->sensor_index = 0;
}
proto_sensor_switch(p_sensor->sensor_index);
return;
}
}