/* Includes ------------------------------------------------------------------*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef CFG_DEV_TYPE_LAND_PD /* 标准C库头文件. */ #include /* 用户代码头文件. */ #include "hwgpio.h" #include "serial.h" #include "pd_modbus.h" /* Private variables ---------------------------------------------------------*/ modbus_t modbus; int32_t _modbus_tcp_transaction(uint16_t transaction_id, uint8_t unit_id, uint16_t start_addr, uint16_t data_num) { int txlen = 0; int rxlen = 0; modbus_tcp_t *frame = (modbus_tcp_t *)modbus.txbuf; uint8_t *pdata = NULL; uint8_t datalen = 0; frame->transaction_id = htons(transaction_id); frame->protocol_id = htons(0); // Modbus // 长度:unit_id(1字节) + 后续PDU(5字节:功能码1 + 起始地址2 + 数量2) frame->length = htons(6); frame->unit_id = unit_id; // PDU frame->function_code = 0x03; pdata = modbus.txbuf + sizeof(modbus_tcp_t); pdata[datalen++] = (start_addr >> 8) & 0xFF; // 起始地址高字节 pdata[datalen++] = start_addr & 0xFF; // 起始地址低字节 pdata[datalen++] = (data_num >> 8) & 0xFF; // 数据数量高字节 pdata[datalen++] = data_num & 0xFF; // 数据数量低字节 txlen = datalen + sizeof(modbus_tcp_t); // 发送请求帧 GPIO_485BUS(WRITE); if (serial_write(modbus.fd, modbus.txbuf, txlen) < 0) { DBG(DBG_M_PD_MODBUS_ERR, "Modbus write error\r\n"); return E_ERROR; } DBG(DBG_M_PD_MODBUS_ERR, "Modbus write len = %d\r\n", txlen); buf_print((char *)modbus.txbuf, txlen); // 等待传输完成 usleep(13000); // 13000 GPIO_485BUS(READ); rxlen = serial_read(modbus.fd, modbus.rxbuf, sizeof(modbus.rxbuf)); if (rxlen > 0) { DBG(DBG_M_PD_MODBUS_ERR, "Modbus read len = %d\r\n", rxlen); buf_print((char *)modbus.rxbuf, rxlen); } return E_NONE; } int32_t _modbus_rtu_transaction(void) { int sndlen = 0; int rcvlen = 0; uint8_t *ptxbuf = modbus.txbuf; ptxbuf[sndlen++] = 0x05; ptxbuf[sndlen++] = 0x03; ptxbuf[sndlen++] = 0x00; ptxbuf[sndlen++] = 0x34; ptxbuf[sndlen++] = 0x00; ptxbuf[sndlen++] = 0x02; ptxbuf[sndlen++] = 0x84; ptxbuf[sndlen++] = 0x41; // 发送请求帧 GPIO_485BUS(WRITE); if (serial_write(modbus.fd, ptxbuf, sndlen) < 0) { DBG(DBG_M_PD_MODBUS_ERR, "Modbus write error\r\n"); return E_ERROR; } usleep(10000); GPIO_485BUS(READ); rcvlen = serial_read(modbus.fd, modbus.rxbuf, sizeof(modbus.rxbuf)); if (rcvlen > 0) { DBG(DBG_M_PD_MODBUS_ERR, "Modbus read len = %d\r\n", rcvlen); buf_print((char *)modbus.rxbuf, rcvlen); } return E_NONE; } void *_modbus_send_handle() { while (1) { #if 0 for (int unit = 1; unit <= 6; unit++) { if (_modbus_tcp_transaction(0, unit, MODBUS_ADDR_CURRENT, MODBUS_CURRENT_LEN) > 0) { } if (_modbus_tcp_transaction(0, unit, MODBUS_ADDR_CURRENT, MODBUS_CURRENT_LEN) > 0) { } } #else //_modbus_rtu_transaction(); _modbus_tcp_transaction(5, MODBUS_UNIT_IR, MODBUS_IR_CURRENT_ADDR, MODBUS_IR_CURRENT_LEN); #endif sleep(2); } if (modbus.fd > 0) { close(modbus.fd); modbus.fd = -1; } } int32_t modbus_handle_init(void) { memset(&modbus, 0, sizeof(modbus)); modbus.fd = -1; return E_NONE; } int32_t modbus_handle_init_after(void) { int baud_rate = 9600; thread_param_t param = {0}; // 初始化串口 int fd = serial_open("/dev/ttyS0", baud_rate); if (fd < 0) { DBG(DBG_M_PD_MODBUS_ERR, "Failed to initialize serial port\n"); return E_ERROR; } modbus.fd = fd; DBG(DBG_M_PD_MODBUS, "fd=%d\n", modbus.fd); param.arg = NULL; param.priority = 80; param.log_module = LOG_MODBUS; snprintf(param.thread_name, THREAD_NAME_LEN, "MODBUS_SEND"); create_thread(_modbus_send_handle, ¶m); return E_NONE; } #endif