开发环境:野火的STM32f407,rt-thread studio版本为版本: 2.2.6,stm32f4的资源包为0.2.2,Agile Modbus软件包版本为v1.1.2。工程使用上一个中帖RS-Thread4 RT-Thread Modbus Slave模拟站为。。。单片机作为主站模拟。。打开工程模拟包站 文档介绍, * 主机: * 1.agile_modbus_rtu_init / agile_modbus_tcp_init 初始化 RTU/TCP 环境 * 2.agile_modbus_set_slave 设置从机地址 * 3.清空接收缓存 * 4.agile_modbus_serialize_xxx 打包请求数据 * 5.发送数据 * 6.等待数据接收结束 * 7.agile_modbus_deserialize_xxx 解析响应数据 * 8.用户处理得到的数据 参考网址,参考代码为 #include 《rtthread.h》 #include 《rtdevice.h》 #include “rs485.h” #include 《agile_modbus.h》 #define DBG_TAG “rtu_master” #define DBG_LVL DBG_INFO #include 《rtdbg.h》 int main(void) { rs485_init(); uint8_t ctx_send_buf[AGILE_MODBUS_MAX_ADU_LENGTH]; uint8_t ctx_read_buf[AGILE_MODBUS_MAX_ADU_LENGTH]; uint16_t hold_register[10]; agile_modbus_rtu_t ctx_rtu; agile_modbus_t *ctx = &ctx_rtu._ctx; agile_modbus_rtu_init(&ctx_rtu, ctx_send_buf, sizeof(ctx_send_buf), ctx_read_buf, sizeof(ctx_read_buf)); agile_modbus_set_slave(ctx, 1); LOG_I(“Running.”); while (1) { rt_thread_mdelay(100); int send_len = agile_modbus_serialize_read_registers(ctx, 0, 10); rs485_send(ctx-》send_buf, send_len); int read_len = rs485_receive(ctx-》read_buf, ctx-》read_bufsz, 1000, 20); if (read_len == 0) { LOG_W(“Receive timeout.”); continue; } int rc = agile_modbus_deserialize_read_registers(ctx, read_len, hold_register); if (rc 《 0) { LOG_W(“Receive failed.”); if (rc != -1) LOG_W(“Error code:%d”, -128 - rc); continue; } LOG_I(“Hold Registers:”); for (int i = 0; i 《 10; i++) LOG_I(“Register [%d]: 0x%04X”, i, hold_register[i]); rt_kprintf(“rnrnrn”); } } 因为我们使用的是rs485驱动包,根据示例,我们知道需要增加几个函数,如下: static int Bsp_Rs485_init(void); //Rs485初始化+设置超时时间 static int Bsp_Rs485_Tx(uint8_t *buf,int size); //Rs485 发送 static int Bsp_Rs485_Rx(uint8_t *buf,int size); //Rs485接受 根据示例程序,修改主函数modbus后的代码如下: #include 《rtthread.h》 #include 《rtdevice.h》 #include “rs485.h” #include 《agile_modbus.h》 #define DBG_TAG “rtu_master” #define DBG_LVL DBG_INFO #include 《rtdbg.h》 int main(void) { Bsp_Rs485_init();// uint8_t ctx_send_buf[AGILE_MODBUS_MAX_ADU_LENGTH]; uint8_t ctx_read_buf[AGILE_MODBUS_MAX_ADU_LENGTH]; uint16_t hold_register[10]; agile_modbus_rtu_t ctx_rtu; agile_modbus_t *ctx = &ctx_rtu._ctx; agile_modbus_rtu_init(&ctx_rtu, ctx_send_buf, sizeof(ctx_send_buf), ctx_read_buf, sizeof(ctx_read_buf)); agile_modbus_set_slave(ctx, 1); LOG_I(“Running.”); while (1) { rt_thread_mdelay(100); int send_len = agile_modbus_serialize_read_registers(ctx, 0, 10); Bsp_Rs485_Tx(ctx-》send_buf, send_len);// int read_len = Bsp_Rs485_Rx(ctx-》read_buf, ctx-》read_bufsz);// if (read_len == 0) { LOG_W(“Receive timeout.”); continue; } int rc = agile_modbus_deserialize_read_registers(ctx, read_len, hold_register); if (rc 《 0) { LOG_W(“Receive failed.”); if (rc != -1) LOG_W(“Error code:%d”, -128 - rc); continue; } LOG_I(“Hold Registers:”); for (int i = 0; i 《 10; i++) LOG_I(“Register [%d]: 0x%04X”, i, hold_register[i]); rt_kprintf(“rnrnrn”); } } 打开模拟软件Modbus Slave,设置基本参数。Modbus Slave的使用参考:参考 可以看到输出端口的打印更换了。 |