#include "proto_modbus_master_tdlas.h" #include "string.h" #include "stdio.h" #include "app.h" #include "os_timer.h" #include "bsp_Uart.h" #include "bsp_74HC4067.h" #include "bsp_Flash.h" #include "proto_print.h" #include "proto_modbus_lib.h" #define TDLAS_MODBUS_ID (0xe8) #define TDLAS_DATA_ENDIAN (LITTLE_ENDIAN) /*配置大小端序*/ #define PROTO_TDLAS_GET_CURR_DATA_START_ADDR (20000) #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_DataAnalysis = 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;isys[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;isys[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;isys[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;isys[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;isys[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 = Usr_Flash.FlashData.modbus_read_reg_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; u8 *p_rx_valid; 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 != 0x04 && 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]; } 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: { p_u16_temp = (u16 *)&(gas_data[p_sensor->sensor_index]); for(i=0;isys_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; } }