You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

164 lines
4.1 KiB
C

/* Includes ------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef CFG_DEV_TYPE_LAND_PD
/* 标准C库头文件. */
#include <arpa/inet.h>
/* 用户代码头文件. */
#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_id1字节 + 后续PDU5字节功能码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, &param);
return E_NONE;
}
#endif