506 lines
16 KiB
C
506 lines
16 KiB
C
#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;
|
||
|
||
/*通道2:0x0004-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;
|
||
|
||
/*通道3:0x0008-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;
|
||
|
||
/* 通道4:0x000B-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;
|
||
}
|
||
}
|