嵌入式技术论坛
直播中

李刚

7年用户 1320经验值
私信 关注
[经验]

RT-Thread中Agile Modbus软件包的使用

开发环境:野火的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的使用参考:参考
可以看到输出端口的打印更换了。
2.jpg



原作者:扬州开发区

更多回帖

发帖
×
20
完善资料,
赚取积分