#ifndef APP_RS485_1_H #define APP_RS485_1_H #define CONFIG_TX_BUFF_SIZE 256 #define CONFIG_RX_BUFF_SIZE 256 #define CONFIG_UART_GOOD 12 #define CONFIG_UART_TIMEOUT 100 #define CONFIG_UART_POLL_DELAY 500 enum { OP_NONE, OP_BOND, OP_WRITE_SN, OP_PAIR, OP_UPDATE_PAIR, OP_READ_INFO, OP_ALARM_TIMES, OP_CELL_VOL,//0x07 OP_TEMP_OTHER,//0x08 OP_OPEN_FET = 0x0B, OP_CLEAR_PAIR = OP_TEMP_OTHER + 1, OP_UPDATE_SOFTWARE_REQ = 0x0E, OP_UPDATE_SOFTWARE = 0x0F, OP_MAX }; typedef struct { uint8_t operate; uint8_t op_result; uint16_t resver; uint32_t param; }SUB_BMS_CMD; #define RS485_COM_TIMEOUT (150) #define RS485_COM_ERROR (3) #define RS485_COM_UPDATE_TIMEOUT (1500) /*******************************************通用帧头-start*********************************************************/ #pragma pack (push,1) typedef struct { //整个包大小 uint8_t size; //命令设备 uint8_t type; //协议类型 uint8_t protocol; //命令类型 uint8_t cmd; //命令校验 uint16_t checksum; //命令处理调用 uint8_t dir; //命令返回状态 uint8_t bStatus; //命令数据部分 }COMMAND_BODY; #pragma pack(pop) // #define BMS_STA_BOND (0x01) #define BMS_STA_D_OPEN (0x02) #define BMS_STA_C_OPEN (0x04) #define BMS_STA_S_OPEN (0x08) #define BMS_STA_C_FULL (0x10) #define BMS_STA_S_BAHU (0x20) #define BMS_STA_JIAO_YAN (0x40) #define BMS_POWER_FULL (BMS_STA_D_OPEN | BMS_STA_C_OPEN) #define BMS_POWER_SMALL (BMS_STA_S_OPEN) #define BMS_POWER_ALL (BMS_POWER_FULL | BMS_POWER_SMALL) /*******************************************通用帧头-end*********************************************************/ /*******************************************BMS帧头-start*********************************************************/ #define SBU_BMS_ADDRESS (0x30) #define SUB_BMS_ADDRESS_0 (SBU_BMS_ADDRESS) #define SUB_BMS_ADDRESS_1 (SBU_BMS_ADDRESS + 1) #define SUB_BMS_ADDRESS_2 (SBU_BMS_ADDRESS + 1) #define BMS_DIR (0x16) #define SET_COMMAND (0x10) #define GET_COMMAND (0x20) #define ACK_COMMAND (0x30) #define ENG_COMMAND (0x40) /*******************************************BMS帧头-end*********************************************************/ typedef enum { SHARK_BMS_VGS_ACC2 = 1 << 0, SHARK_BMS_VGS_FV = 1 << 1, SHARK_BMS_VGS_ALL = 0xFF } shark_bms_vgs_t; typedef enum { SHARK_BATT_POWER_FAULT, SHARK_BATT_POWER_ANY, SHARK_BATT_POWER_OFF, SHARK_BATT_POWER_SMALL, SHARK_BATT_POWER_FULL, SHARK_BATT_POWER_ALL, } shark_battery_power_t; typedef enum { SHARK_BATT_EXIT_SUCCESS, SHARK_BATT_EXIT_UPGRADE, SHARK_BATT_EXIT_POWER, SHARK_BATT_EXIT_SHAKE, SHARK_BATT_EXIT_ERROR, SHARK_BATT_EXIT_SOAK, SHARK_BATT_EXIT_485, } shark_battery_exit_t; typedef enum { SHARK_BATT_MASK_NONE = 0, SHARK_BATT_MASK_BAT1 = 1 << 0, SHARK_BATT_MASK_BAT2 = 1 << 1, SHARK_BATT_MASK_BOTH = SHARK_BATT_MASK_BAT1 | SHARK_BATT_MASK_BAT2 } shark_battery_mask_t; #pragma pack (push,1) typedef struct { uint8_t yjkxslc; uint8_t m_percent; uint8_t yjcdwcsj; uint8_t charge_flag; int32_t m_current; uint32_t m_total_vol; uint8_t bms_temp; uint16_t work_status; uint32_t banlance_cell; uint8_t bms_status; uint8_t operate_result; }PACKET_COMMON; #define SERIAL_NUM_SIZE 18 #define SOFTWARE_SIZE 20 typedef struct { uint8_t sn[SERIAL_NUM_SIZE]; uint8_t soft_ver[SOFTWARE_SIZE]; }BATTERY_DEV_INFO; typedef struct { uint16_t dcsmxs; uint32_t charge_times; uint32_t charge_over_vol_times; uint32_t discharge_under_vol_times; uint32_t charge_over_cur_times; uint32_t discharge_under_cur_times; uint32_t short_times; uint32_t charge_under_temp_times; uint32_t discharge_under_temp_times; uint32_t charge_over_temp_times; uint32_t discharge_over_temp_times; }BATTERY_TIMES; #define CELL_NUM_MAX (15u) typedef struct { uint8_t cv_cell_num; uint16_t cv_cell_vol[CELL_NUM_MAX]; }CELL_VOL; #define THERMISTOR_NUM_MAX (4u) typedef struct { int8_t to_temp_num[THERMISTOR_NUM_MAX]; uint8_t to_fet; }TEMP_OTHER; #pragma pack(pop) typedef enum { SHARK_SEND_IDLE, SHARK_SEND_PENDING, SHARK_SEND_SUCCESS, SHARK_SEND_TIMEOUT, } shark_send_state_t; typedef struct { PACKET_COMMON packet_common; BATTERY_DEV_INFO bat_dev_info; BATTERY_TIMES bat_times; CELL_VOL cell_vol; TEMP_OTHER temp_other; SUB_BMS_CMD sub_bms_cmd; u32 uart; u8 address; u8 connected; u8 err_times; shark_bool used; shark_send_state_t send_state; shark_battery_exit_t exit_code; u8 rx_buff[CONFIG_RX_BUFF_SIZE]; u8 tx_buff[CONFIG_TX_BUFF_SIZE]; u16 rx_length; u16 tx_length; u16 tx_index; shark_bool rx_pending; shark_bool tx_pending; u8 rx_busy; u8 tx_busy; u8 define_error; u8 test_error; u8 send_times; }SUB_BMS_INFO; extern SUB_BMS_INFO sub_bms_info_1; extern SUB_BMS_INFO sub_bms_info_2; typedef struct { uint8_t set; uint16_t count; uint8_t com_err_flag; uint32_t com_err_count; }SUB_BMS_COM; #if 0 _inline void Sub_BMS_1_RS485_Com_Time_Out(void) { if(sub_rs485_time_out_1.set) { if(++sub_rs485_time_out_1.count >= RS485_COM_TIMEOUT) { RS485_busy_1 = 0; sub_rs485_time_out_1.set = 0; sub_rs485_time_out_1.count = 0; if(sub_rs485_time_out_1.com_err_flag == 0) { sub_rs485_time_out_1.com_err_flag = 1; sub_rs485_time_out_1.com_err_count = 1; } else { if(++sub_rs485_time_out_1.com_err_count >= 5) { sub_rs485_time_out_1.com_err_count = 0; g_event |= SUB_BMS_1_RS485_DISC_EVENT; } } } } } __inline void Sub_BMS_2_RS485_Com_Time_Out(void) { if(sub_rs485_time_out_2.set) { if(++sub_rs485_time_out_2.count >= RS485_COM_TIMEOUT) { RS485_busy_2 = 0; sub_rs485_time_out_2.set = 0; sub_rs485_time_out_2.count = 0; if(sub_rs485_time_out_2.com_err_flag == 0) { sub_rs485_time_out_2.com_err_flag = 1; sub_rs485_time_out_2.com_err_count = 1; } else { if(++sub_rs485_time_out_2.com_err_count >= 5) { sub_rs485_time_out_2.com_err_count = 0; g_event |= SUB_BMS_2_RS485_DISC_EVENT; } } } } } #endif enum { CW_NONE, CW_CHONG_DIAN_ZUO, CW_CHE_SHANG_CHARGER, CW_CHE_SHANG_NO_CHARGER, CW_MAX }; extern uint8_t cang_wei; typedef struct { uint32_t bms_err_timeout_cnt; uint16_t bms_err_cnt; uint16_t bms_err_num; }BMS_ERROR; #define TI_VALID_FLAG_KEY (0x0327) typedef struct { uint16_t ti_flag; uint16_t ti_set; BMS_ERROR ti_bms_1; BMS_ERROR ti_bms_2; }TEST_INFO; extern TEST_INFO test_info; int8_t Handle_RS485_1_Data(void); int8_t Handle_RS485_2_Data(void); void Sub_BMS_1_Initial(void); shark_battery_exit_t Is_Sub_BMS_1_Normal(void); shark_battery_exit_t Is_Sub_BMS_2_Normal(void); void Initial_Test_Info(void); void Save_Test_Info(void); void Ca_Chu_Test_Info(void); void Check_Enable_Test_Info(void); shark_battery_exit_t shark_battery_is_normal(SUB_BMS_INFO *info, shark_battery_power_t power); void shark_bms_set_vgs(shark_bms_vgs_t vgs, shark_bool enable); void shark_bms_set_mos(shark_bool ss, shark_bool s11, shark_bool s21); shark_battery_mask_t shark_battery_set_power(shark_battery_power_t power1, shark_battery_power_t power2, shark_battery_mask_t mask); shark_battery_power_t shark_battery_get_power(SUB_BMS_INFO *info); shark_bool shark_battery_check_power(SUB_BMS_INFO *info, shark_battery_power_t power); shark_battery_mask_t shark_battery_detect(u8 times); shark_bool shark_battery_ping(u8 times); u32 shark_battery_get_voltage(SUB_BMS_INFO *info); u32 shark_battery_get_voltage_delta(void); u32 shark_battery_get_voltage_min(void); u32 shark_battery_get_voltage_max(void); void shark_battery_clear(SUB_BMS_INFO *info); shark_bool shark_battery_process(SUB_BMS_INFO *info, const u8 *buff, u8 length); shark_bool shark_battery_send_command(SUB_BMS_INFO *info); static inline void shark_bms_set_mos_close(void) { shark_bms_set_mos(shark_false, shark_false, shark_false); } static inline void shark_bms_set_mos_bat1(void) { shark_bms_set_mos(shark_false, shark_false, shark_true); } static inline void shark_bms_set_mos_bat2(void) { shark_bms_set_mos(shark_false, shark_true, shark_false); } static inline void shark_bms_set_mos_series(void) { shark_bms_set_mos(shark_true, shark_false, shark_false); } static inline void shark_bms_set_mos_parrallel(void) { shark_bms_set_mos(shark_false, shark_true, shark_true); } static inline shark_battery_exit_t shark_battery_is_normal_power_on(SUB_BMS_INFO *info) { return shark_battery_is_normal(info, SHARK_BATT_POWER_FULL); } static inline u32 shark_battery_get_voltage1(void) { return shark_battery_get_voltage(&sub_bms_info_1); } static inline u32 shark_battery_get_voltage2(void) { return shark_battery_get_voltage(&sub_bms_info_2); } static inline shark_bool shark_battery_send_pending(SUB_BMS_INFO *info) { return info->send_state == SHARK_SEND_PENDING; } static inline shark_bool shark_battery_send_success(SUB_BMS_INFO *info) { return info->send_state == SHARK_SEND_SUCCESS; } static inline u8 shark_battery_get_rs485_state(SUB_BMS_INFO *info) { return info->connected ? 3 : 2; } #endif