#include "modbus_rtu_master.h" MODBUS_MASTER mod_master; void modbus_rtu_master_init(void) { mod_master.target_id = 0x00; mod_master.command_code = 0x00; mod_master.start_address = 0x0000; mod_master.register_num = 0x0000; mod_master.crc16 = 0x0000; mod_master.byte_num = 0; memset(mod_master.data_tx_value8, 0, TX_DATA_MAX); memset(mod_master.data_tx_value16, 0, TX_DATA_MAX); memset(mod_master.data_tx, 0, TX_BUFF_MAX); memset(mod_master.data_rx, 0, RX_BUFF_MAX); mod_master.data_tx_len = 0; mod_master.data_rx_len = 0; mod_master.rx_error_message = RX_ERROR_NONE; mod_master.tx_error_message = TX_ERROR_NONE; mod_master.timeout = 1000; mod_master.rx_flag = RX_NONE; mod_master.tx_flag = TX_NONE; } void modbus_rtu_master_load(void) { mod_master.data_tx[0] = mod_master.target_id; mod_master.data_tx[1] = mod_master.command_code; memset(mod_master.data_rx, 0, sizeof(mod_master.data_rx)); switch (mod_master.data_tx[1]) { //读四种寄存器的格式一致 case ReadCoilState: { //注释break,直接向下穿透 } //break; case ReadDisInputState: { //注释break,直接向下穿透 } //break; case ReadHoldReg: { //注释break,直接向下穿透 } //break; case ReadInputReg: { mod_master.data_tx[2] = (uint8_t)(mod_master.start_address >> 8); mod_master.data_tx[3] = (uint8_t)(mod_master.start_address & 0x00FF); mod_master.data_tx[4] = (uint8_t)(mod_master.register_num >> 8); mod_master.data_tx[5] = (uint8_t)(mod_master.register_num & 0x00FF); mod_master.crc16 = ModbusCRC16(mod_master.data_tx, 6); mod_master.data_tx[6] = (uint8_t)(mod_master.crc16 & 0x00FF); mod_master.data_tx[7] = (uint8_t)(mod_master.crc16 >> 8); mod_master.data_tx_len = 8; } break; case WriteSingleCoil: { mod_master.data_tx[2] = (uint8_t)(mod_master.start_address >> 8); mod_master.data_tx[3] = (uint8_t)(mod_master.start_address & 0x00FF); mod_master.data_tx[4] = (uint8_t)(mod_master.data_tx_value8[0] >> 8); mod_master.data_tx[5] = (uint8_t)(mod_master.data_tx_value8[0] & 0x00FF); mod_master.crc16 = ModbusCRC16(mod_master.data_tx, 6); mod_master.data_tx[6] = (uint8_t)(mod_master.crc16 & 0x00FF); mod_master.data_tx[7] = (uint8_t)(mod_master.crc16 >> 8); mod_master.data_tx_len = 8; } break; case WriteSingleReg: { mod_master.data_tx[2] = (uint8_t)(mod_master.start_address >> 8); mod_master.data_tx[3] = (uint8_t)(mod_master.start_address & 0x00FF); mod_master.data_tx[4] = (uint8_t)(mod_master.data_tx_value16[0] >> 8); mod_master.data_tx[5] = (uint8_t)(mod_master.data_tx_value16[0] & 0x00FF); mod_master.crc16 = ModbusCRC16(mod_master.data_tx, 6); mod_master.data_tx[6] = (uint8_t)(mod_master.crc16 & 0x00FF); mod_master.data_tx[7] = (uint8_t)(mod_master.crc16 >> 8); mod_master.data_tx_len = 8; } break; case WriteMultiCoil: { if( mod_master.register_num % 8 ) { //线圈数量不为8的倍数时,字节数 == (线圈数量/8 + 1) if( (mod_master.register_num/8 + 1) != mod_master.byte_num ) { mod_master.tx_error_message = TX_ERROR_COIL_NUM; return; } } else { //线圈数量为8的倍数时,字节数 == 线圈数量/8 if( (mod_master.register_num/8) != mod_master.byte_num ) { mod_master.tx_error_message = TX_ERROR_COIL_NUM; return; } } mod_master.data_tx[2] = (uint8_t)(mod_master.start_address >> 8); mod_master.data_tx[3] = (uint8_t)(mod_master.start_address & 0x00FF); mod_master.data_tx[4] = (uint8_t)(mod_master.register_num >> 8); mod_master.data_tx[5] = (uint8_t)(mod_master.register_num & 0x00FF); mod_master.data_tx[6] = mod_master.byte_num; for(uint8_t i = 1; i <= mod_master.byte_num; i++ ) { mod_master.data_tx[6 + i] = mod_master.data_tx_value8[i - 1]; } mod_master.crc16 = ModbusCRC16(mod_master.data_tx, 7 + mod_master.byte_num); mod_master.data_tx[7 + mod_master.byte_num] = (uint8_t)(mod_master.crc16 & 0x00FF); mod_master.data_tx[8 + mod_master.byte_num] = (uint8_t)(mod_master.crc16 >> 8); mod_master.data_tx_len = 8 + mod_master.byte_num + 1; } break; case WriteMultiReg: { if( (mod_master.register_num * 2) != mod_master.byte_num ) { //字节数 == (寄存器数量*2) mod_master.tx_error_message = TX_ERROR_HOLDREG_NUM; return; } mod_master.data_tx[2] = (uint8_t)(mod_master.start_address >> 8); mod_master.data_tx[3] = (uint8_t)(mod_master.start_address & 0x00FF); mod_master.data_tx[4] = (uint8_t)(mod_master.register_num >> 8); mod_master.data_tx[5] = (uint8_t)(mod_master.register_num & 0x00FF); mod_master.data_tx[6] = mod_master.byte_num; for(uint8_t i = 1; i <= mod_master.byte_num; i++ ) { mod_master.data_tx[6 + i] = mod_master.data_tx_value16[ (i - 1)/2 ] >> ( 8*(i%2) ); } mod_master.crc16 = ModbusCRC16(mod_master.data_tx, 7 + mod_master.byte_num); mod_master.data_tx[7 + mod_master.byte_num] = (uint8_t)(mod_master.crc16 & 0x00FF); mod_master.data_tx[8 + mod_master.byte_num] = (uint8_t)(mod_master.crc16 >> 8); mod_master.data_tx_len = 8 + mod_master.byte_num + 1; } break; default: { mod_master.tx_error_message = TX_ERROR_WRONG_CMD; } break; } } void modbus_rtu_master_send(void) { if(mod_master.tx_error_message == TX_ERROR_NONE) { mod_master.rx_flag = TX_WAITING; //将准备好的数据发送至从设备 memcpy(scom2_rs485.tx_buff, mod_master.data_tx, mod_master.data_tx_len); scom2_rs485.tx_len = mod_master.data_tx_len; scom2_rs485.tx_flag = TRUE; if(scom2_rs485.tx_flag == TRUE) { scom2_rs485.tx_flag = FALSE; //将数据发送至上位机 HAL_UART_Transmit_DMA(&huart2, scom2_rs485.tx_buff, scom2_rs485.tx_len); } //在发送回调中判断发送是否完成 sig_trans = TRANS_MODBUS_SIG_TO_SLAVE; } } void modbus_rtu_master_analysis(void) { if(scom2_rs485.rx_len > RX_BUFF_MAX) { mod_master.rx_error_message = RX_ERROR_OVERFLOW; return; } mod_master.data_rx_len = scom2_rs485.rx_len; memcpy(mod_master.data_rx, scom2_rs485.rx_buff, mod_master.data_rx_len); if(mod_master.data_rx[0] != mod_master.target_id) { mod_master.rx_error_message = RX_ERROR_WRONG_ID; return; } if(mod_master.data_rx[1] <= 0x80) { //收到的是正常响应 } else { //收到的是异常响应 ex_message = (eMBException)mod_master.data_rx[2]; } mod_master.rx_flag = RX_OK; }