/* modbus 从机实现*/ #include #include "crc.h" #include "modbus-s.h" #if !defined(LOG_TAG) #define LOG_TAG "main" #endif #include void ModbusSlaveInit(ModBusSlave_t * drv,uint8_t ID,uint8_t * data,uint16_t * reg,uint16_t max) { drv->ID = ID; drv->data = data ; drv->reg = reg; drv->regmax = max; } // 解析modbus 数据 //-1 地址错误 int ModbusSlaveHandle(ModBusSlave_t * drv,uint8_t * data,uint16_t length ) { uint16_t rcrc = 0,ccrc = 0 ; if( (data[0] != drv->ID) && (data[0] != 0x00)) { // 地址错误 return -1; } rcrc = ((uint16_t)data[length- 1] << 8) + (uint16_t)data[length- 2] ; ccrc = MX_CRC_CALC(data,length-2); if (rcrc != ccrc ) { log_e("rcrc:%04X,ccrc:%04X\r\n",rcrc,ccrc) ; return -2; } drv->func = data[1] ; switch (drv->func) { case 0x03 :// 读取保持寄存器地址 { drv->Addr = ((uint16_t)data[2] << 8) + data[3]; drv->length = ((uint16_t)data[4] << 8) + data[5]; break; } case 0x04: break; case 0x06: // 写入单个保持寄存器 drv->Addr = ((uint16_t)data[2] << 8) + data[3]; drv->data[0] = data[4]; drv->data[1] = data[5]; break; default: return -3 ; break; } return 0; // if() // 寄存器最大值 } // 从机数据应答 int ModbusSlavePacket(ModBusSlave_t * drv,uint8_t *data) { int tx_size = 0; uint16_t crc = 0; data[tx_size++] = drv->ID; data[tx_size++] = drv->func; char * p = (char *)&drv->reg[drv->Addr]; switch (drv->func) { case 0x03: data[tx_size++] = drv->length *2; for(int i =0;i < drv->length *2;i++) { data[tx_size++] = *p; p++; } break; case 0x06: // data[tx_size++] = (drv->Addr >> 8) & 0x00FF; data[tx_size++] = drv->Addr & 0x00FF; data[tx_size++] = drv->data[0]; data[tx_size++] = drv->data[1]; break; default : break; } crc = MX_CRC_CALC(data,tx_size); data[tx_size++] = crc & 0x00FF; data[tx_size++] = (crc >> 8) & 0x00FF; return tx_size; } //// 读取保持寄存器的值 //// addr 寄存器地址 //// id 丛机地址 //// length 读取丛机数据长度 //int modbus_m_read_regist(uint8_t id,uint16_t addr,uint16_t length,uint8_t * data) //{ // uint16_t index = 0,crc; // data[index++] = id; // data[index++] = 0x03; // data[index++] = (addr >> 8) & 0x00FF; // data[index++] = addr & 0x00FF; // data[index++] = (length >> 8) & 0x00FF; // data[index++] = length & 0x00FF; // crc = MX_CRC_CALC(data,index); // data[index++] = crc & 0x00FF; // data[index++] = (crc >> 8) & 0x00FF; // return index; //} //// 解析通过03 命令读取回来额寄存器数据 //int modbus_m_read_regist_ack(uint) //{ // //}