/** ************************************************************************************************ * @文件 : fly_modbus.c * @作者 : 樊春春 * @版本 : V1.0 * @时间 : 2022/05/30 22:46:49 * @邮箱 : fanchcho@gmail.com * @说明 : ************************************************************************************************ **/ #include "modbus.h" INT16U misc_info_buf[BUF_LEN_128] = {0}; INT16U cell_temp_buf[BUF_LEN_512] = {0}; INT16U samkoon_txbuf[BUF_LEN_128] = {0}; /**************************************************** * @函数 : crc_count * @作者 : 樊春春 * @功能 : 计算CRC数据 * @入参 : addr: 数据指针 num: 数量 * @说明 : 无 *****************************************************/ unsigned short crc_count(const INT8U *addr, int num) { unsigned short crc = 0xFFFF; int i; while (num--) { crc ^= *addr++; for (i = 0; i < 8; i++) { crc = (crc & 0x0001) ? ((crc >> 1) ^ 0xA001) : (crc >> 1); } } return crc; } /**************************************************** * @函数 : crc_write * @作者 : 樊春春 * @功能 : CRC写入 * @入参 : p: 数据指针 data: crc值 count: 写入位置 * @说明 : 无 *****************************************************/ void crc_write(INT8U *p, INT16U data, INT8U count) { p = p + (2 * count + 3); *p++ = (INT8U)data; *p++ = (INT8U)(data >> 8); } /**************************************************** * @函数 : little2big * @作者 : 樊春春 * @功能 : 小端转大端 * @入参 : buf: 数据指针 count: 个数 * @说明 : 无 *****************************************************/ void little2big(INT16U *buf, INT16U count) { INT8U i = 0; INT8U *p = (INT8U *)buf; INT8U *p_next = (INT8U *)buf + 1; char tmp; for (i = 0; i < 2 * count; i++) { tmp = *p; *p = *p_next; *p_next = tmp; p = p + 2; p_next = p_next + 2; } } /**************************************************** * @函数 : modbus_head * @作者 : 樊春春 * @功能 : Mosbus头拷贝 * @入参 : des_data: 目标数据指针 src_data: 源数据指针 * @说明 : 无 *****************************************************/ void modbus_head(INT8U *des_data, INT8U *src_data) { INT8U i = 0; for (i = 0; i < 2; i++) { *des_data++ = *src_data++; } src_data = src_data + 3; *des_data = (*src_data) * 2; } /*-------------------------------------------- ** func :ImportantData_TxGet ** brief:copy send data; soc 1th start from 0x4001; ** para : samkoon_txbuf\misc_info_buf for use --------------------------------------------*/ void ImportantData_TxGet(INT16U pos, INT16U cnt, INT8U *des_data, INT8U *src_data) { INT8U i = 0; pos = pos - 0x4001; // addr offset 4300 hex src_data = src_data + pos; des_data = des_data + 6; // cell txbuf offset:6 for (i = pos; i < cnt; i++) { *des_data++ = *src_data++; } } /*--------------------------------------- ** func :Cell_Info_ReadOut ** brief:copy cell data 1th start from 0x4301 ** para :none ---------------------------------------*/ void Cell_Info_ReadOut(INT16U *p) { INT8U i, j; for (i = 0; i < 6; i++) { for (j = 0; j < 6; j++) { *p++ = 3300; } } // for(i = 0;i < config_get_slave_num(); i++) // without offset // { // for(j = 0;j < bmu_get_cell_num(i); j++) // { // *p++ = 3300; //bmu_get_cell_vol(i,j); // } // } } /*--------------------------------------- ** func :Cell_Info_TxGet ** brief: none ** para :position \ cnt ---------------------------------------*/ void Cell_Info_TxGet(INT16U pos, INT16U cnt, INT8U *des_data, INT8U *src_data) { INT8U i = 0; pos = pos - 0x4300; // addr offset 4300 hex src_data = src_data + pos; des_data = des_data + 6; // cell txbuf offset:6 for (i = pos; i < cnt; i++) { *des_data++ = *src_data++; } } /*--------------------------------------- ** func :Temperature_ReadOut ** brief:copy temperature data, 1th start from 0x55C1 offset -40 ** para :none ---------------------------------------*/ void Temperature_ReadOut(INT16U *p) { INT8U i, j; for (i = 0; i < 6; i++) { for (j = 0; j < 6; j++) { *p++ = 20; } } // for(i = 0;i < config_get_slave_num(); i++) // without offset //PackNum = (total + (singleNum - 1))/singleNum // { // for(j = 0;j < bmu_get_temp_num(i); j++) // { // *p++ = bmu_get_cell_temp(i,j); // } // } } /*--------------------------------------- ** func :Cell_Info_TxGet ** brief: none ** para :position \ cnt ---------------------------------------*/ void Temperature_TxGet(INT16U pos, INT16U cnt, INT8U *des_data, INT8U *src_data) { INT8U i = 0; pos = pos - 0x55c0; // addr offset 55c0 hex src_data = src_data + pos; des_data = des_data + 6; // tmp txbuf offset:6 for (i = pos; i < cnt; i++) { *des_data++ = *src_data++; } } /*--------------------------------------- ** func :Rtu_TxData_Get() ** brief: none ** para :position \ cnt ---------------------------------------*/ void Rtu_TxData_Get(INT16U pos, INT16U cnt, INT16U addr_start, INT8U fotmat_offset, // fotmat_offset:3 INT8U *des_data, INT8U *src_data) { INT8U i = 0; if (pos < addr_start) return; pos = pos - addr_start; // addr offset 55c0 hex src_data = src_data + pos * 2; // des_data = des_data + fotmat_offset; des_data = (INT8U *)des_data + fotmat_offset; for (i = 2 * pos; i < 2 * cnt; i++) { *des_data++ = *src_data++; } } /*---------------------------------------------- ** @func : samkoon_com_work ** @brief : BMS with samkoon communication ** format : xx xx xx xx xx xx xx xx addr func -reg- -count- -crc- ans: xx xx xx xx xx....xx xx xx addr func count- --data-- -crc- crc:small other:big -----------------------------------------------*/ void samkoon_com_work(INT8U *rec_data, void (*tx_p)(const INT8U *buf, INT16U len)) { INT16U register_addr_hmi; INT16U tmp_crc; volatile INT16U register_count; volatile INT8U illegal_flag = 0; INT8U function_code = 0; register_addr_hmi = (rec_data[REGISTER_ADDR_H] << 8) + rec_data[REGISTER_ADDR_L]; register_count = (rec_data[COUNT_INDEX_H] << 8) + rec_data[COUNT_INDEX_L]; function_code = rec_data[FUNCTION_CODE_INDEX]; switch (function_code) { case FUNC_03: if ((register_addr_hmi >= MODBUS_ADDR_RACK_REMOTE) && (register_addr_hmi < MODBUS_ADDR_RACK_REMOTE_END)) { modbus_head((INT8U *)samkoon_txbuf, rec_data); // Important_Bin_ReadOut(misc_info_buf); little2big(misc_info_buf, register_count); Rtu_TxData_Get(register_addr_hmi, register_count, 0xc9, 3, (INT8U *)samkoon_txbuf, (INT8U *)misc_info_buf); tmp_crc = crc_count((INT8U *)samkoon_txbuf, 2 * register_count + 3); crc_write((INT8U *)samkoon_txbuf, tmp_crc, register_count); // samkoon_txbuf[register_count + 2] = tmp_crc; tx_p((INT8U *)samkoon_txbuf, (2 * register_count + 5)); } else if ((register_addr_hmi >= MODBUS_ADDR_SOC) && (register_addr_hmi < MODBUS_RACK_END)) { modbus_head((INT8U *)samkoon_txbuf, rec_data); // ImportantData_Readout(misc_info_buf); little2big(misc_info_buf, register_count); Rtu_TxData_Get(register_addr_hmi, register_count, 0x4101, 3, (INT8U *)samkoon_txbuf, (INT8U *)misc_info_buf); tmp_crc = crc_count((INT8U *)samkoon_txbuf, 2 * register_count + 3); crc_write((INT8U *)samkoon_txbuf, tmp_crc, register_count); // samkoon_txbuf[register_count + 2] = tmp_crc; tx_p((INT8U *)samkoon_txbuf, (2 * register_count + 5)); } else if ((register_addr_hmi >= MODBUS_ADDR_CELL) && (register_addr_hmi < MODBUS_CELL_END)) { modbus_head((INT8U *)samkoon_txbuf, rec_data); Cell_Info_ReadOut(cell_temp_buf); // read all cell data little2big(cell_temp_buf, register_count); Rtu_TxData_Get(register_addr_hmi, register_count, 0x4301, 3, (INT8U *)samkoon_txbuf, (INT8U *)cell_temp_buf); tmp_crc = crc_count((INT8U *)samkoon_txbuf, 2 * register_count + 3); crc_write((INT8U *)samkoon_txbuf, tmp_crc, register_count); // samkoon_txbuf[register_count + 2] = tmp_crc; tx_p((INT8U *)samkoon_txbuf, (2 * register_count + 5)); } else if ((register_addr_hmi >= MODBUS_ADDR_TEMP) && (register_addr_hmi < MODBUS_TEMP_END)) { modbus_head((INT8U *)samkoon_txbuf, rec_data); Temperature_ReadOut(cell_temp_buf); // read all temp data little2big(cell_temp_buf, register_count); Rtu_TxData_Get(register_addr_hmi, register_count, 0x55c1, 3, (INT8U *)samkoon_txbuf, (INT8U *)cell_temp_buf); tmp_crc = crc_count((INT8U *)samkoon_txbuf, 2 * register_count + 3); crc_write((INT8U *)samkoon_txbuf, tmp_crc, register_count); // samkoon_txbuf[register_count + 2] = tmp_crc; tx_p((INT8U *)samkoon_txbuf, (2 * register_count + 5)); } else if ((register_addr_hmi >= MODBUS_ADDR_READ_KA) && (register_addr_hmi < MODBUS_KA_END)) { modbus_head((INT8U *)samkoon_txbuf, rec_data); // Relay_Bin_Readout(misc_info_buf); little2big(misc_info_buf, register_count); Rtu_TxData_Get(register_addr_hmi, register_count, 0x1001, 3, (INT8U *)samkoon_txbuf, (INT8U *)misc_info_buf); tmp_crc = crc_count((INT8U *)samkoon_txbuf, 2 * register_count + 3); crc_write((INT8U *)samkoon_txbuf, tmp_crc, register_count); // samkoon_txbuf[register_count + 2] = tmp_crc; tx_p((INT8U *)samkoon_txbuf, (2 * register_count + 5)); } break; /* do other work... */ case FUNC_05: break; default: illegal_flag = 1; break; } } void modbus_slave_task(void) { INT8U err = 0; INT8U test_buf[20] = {0}; UartFrame_TypeDef *msg; while (1) { OSTimeDly(200); iwdg_feed(UART3_DOG); msg = (UartFrame_TypeDef *)OSMboxPend(uart3_mbox, 50, &err); if ((err == OS_ERR_NONE) && (msg->len >= 2)) { if ((msg->buf[0] == 0x00) && (msg->buf[1] == 0xAA) && (msg->buf[2] == 0xBB)) { test_buf[0] = 0x00; test_buf[1] = 0xBB; test_buf[2] = 0xAA; uart3_dma_send(test_buf, 3); } } } }