RTT小师弟 · 2021年04月23日

RT-Thread 应用笔记 - freemodbus RTU RS485 从机

RT-Thread 应用笔记 - 不正确使用LOG也会引发hard fault

RT-Thread 应用笔记 - RTC Alarm 组件的使用

RT-Thread 应用笔记 - freemodbus RTU RS485 从机

RT-Thread 应用笔记 - freemodbus RTU RS485 主机

RT-Thread 应用笔记 - libmodbus RTU RS485 从机

RT-Thread 应用笔记 - libmodbus RTU RS485 主机

RT-Thread 应用笔记 - STM32 CAN 通信双机

RT-Thread USB学习实践系列

背景

  • modbus协议,简单,实用,一些小数据通信控制场合,用的比较多。
  • 部分用户使用起来,并不是想象中那么的顺利。
  • freemodbus,官方提供从机的程序,代码比较易懂,易于学习协议的实现。
  • 基于rt-thread,已经有freemodbus的主从机软件包。

前言

  • 嵌入式软件工程师,需要了解原理图,获取到引脚定义,如串口、RS485控制引脚、等等。
  • 我的板子,MCU 为STM32F103C8T6, Flash与SRAM都相对不大。
  • UART1用于rt-thread MSH串口。
  • UART3用于RS485,用于modbus rtu串口。

原理图


2020-12-01_224823.png


2020-12-01_225141.png


  • 估计有些工程师,原理图不用看的,直接调代码。
  • 后来发现,原来用的是RS485,不是RS232,
  • 用的是串口3不是串口2
  • 原来RS485的方向控制引脚,低电平是输入,高电平是输出,平时默认输入
  • RS485是半双工串行通讯。
  • 这里,我使用UART3, PB10 PB11,方向控制引脚PA8,rt-thread引脚编号为8。

代码移植

测试的demo如下,目前实现裸机freemodbus与基于rt-thread freemodbus rtu 从机功能。

https://gitee.com/zhangsz0516/rtt_stm32_freemodbus
  • 可以先移植RT-Thread到STM32F103C8T6上,使用源码包里的类似STM32F1系列的BSP,修改过来。
  • 实现RT-Thead最小系统,串口使用uart1。
  • UART3 引脚配置(不要以为rt-thread已经适配好了,板级驱动,没有的,不用问,自己实现就好)
  • 修改 stm32f1xx_hal_msp.c 文件,修改HAL_UART_MspInit。

    void HAL_UART_MspInit(UART_HandleTypeDef* huart)
    {
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    if(huart->Instance==USART1)
    {
    /* USER CODE BEGIN USART1_MspInit 0 */
    
    /* USER CODE END USART1_MspInit 0 */
      /* Peripheral clock enable */
      __HAL_RCC_USART1_CLK_ENABLE();
    
      __HAL_RCC_GPIOA_CLK_ENABLE();
      /**USART1 GPIO Configuration    
      PA9     ------> USART1_TX
      PA10     ------> USART1_RX 
      */
      GPIO_InitStruct.Pin = GPIO_PIN_9;
      GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
      HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
      GPIO_InitStruct.Pin = GPIO_PIN_10;
      GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
    /* USER CODE BEGIN USART1_MspInit 1 */
    
    /* USER CODE END USART1_MspInit 1 */
    }
    else if (huart->Instance==USART3)
    {
      __HAL_RCC_USART3_CLK_ENABLE();
    
      __HAL_RCC_GPIOB_CLK_ENABLE();
      /**USART3 GPIO Configuration    
      PB10     ------> USART3_TX
      PB11     ------> USART3_RX 
      */
      GPIO_InitStruct.Pin = GPIO_PIN_10;
      GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
      HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
      GPIO_InitStruct.Pin = GPIO_PIN_11;
      GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    }
    }
    
    void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
    {
    if(huart->Instance==USART1)
    {
      __HAL_RCC_USART1_CLK_DISABLE();
    
      HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
    }
    else if(huart->Instance==USART3)
    {
          __HAL_RCC_USART3_CLK_DISABLE();
        HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_11);
    }
    }
  • 修改board下的Kconfig,增加uart3

      menuconfig BSP_USING_UART
          bool "Enable UART"
          default y
          select RT_USING_SERIAL
          if BSP_USING_UART
              config BSP_USING_UART1
                  bool "Enable UART1"
                  default y
    
              config BSP_UART1_RX_USING_DMA
                  bool "Enable UART1 RX DMA"
                  depends on BSP_USING_UART1 && RT_SERIAL_USING_DMA
                  default n
    
              config BSP_USING_UART2
                  bool "Enable UART2"
                  default n
                  
              config BSP_USING_UART3 /* 使能UART3 */
                  bool "Enable UART3"
                  default y
          endif

2020-12-01_230303.png

  • 获取freemodbus软件包,通过ENV : menuconfig

2020-12-01_230424.png

2020-12-01_230452.png

2020-12-01_230541.png

  • 使用 rt-thread ENV工具:pkgs --update,下载freemodbus软件包。
$ pkgs --update
Cloning into 'E:\Gitee\other\rtt_stm32_freemodbus\master_rtu\packages\freemodbus-latest'...
remote: Enumerating objects: 9, done.
remote: Counting objects: 100% (9/9), done. 
remote: Compressing objects: 100% (6/6), done. 
remote: Total 83 (delta 3), reused 8 (delta 3), pack-reused 74 
Receiving objects: 100% (83/83), 191.63 KiB | 191.00 KiB/s, done.
Resolving deltas: 100% (23/23), done. 
==============================>  FREEMODBUS latest is downloaded successfully.

==============================>  freemodbus update done 

Operation completed successfully. 
  • 代码编译运行,打开串口中端,输入 mb_slave_samlpe 命令,开启从机功能
  • RS485主从机接线,【A+】-> 【A+】, 【B-】 -> 【B-】,主机与从机要共地【GND】。
  • modbus调试工具,可以使用 Modbus Poll。

2020-12-01_231040.png

2020-12-01_231124.png

2020-12-01_231154.png

2020-12-01_231207.png

2020-12-01_231255.png

总结

  • 如果RS485不通,连接失败,首先确认串口引脚配置与RS485引脚的配置。
  • 从机地址的设置,默认是1,可以改。
  • 通信波特率设置,可以改,115200或更高速率。
  • 寄存器,根据实际情况添加,注意个数,在读写测试时,不要超出范围。
  • 我遇到通信后,马上hardfault的问题!!最终确认是SRAM剩余空间太小引起,因此关闭了一些无用的占用内存较大的组件。
  • 如果RT-Thread上跑不通,建议裸机跑下。
  • 如果要熟练掌握modbus协议,还是要多应用。
推荐阅读
关注数
8071
内容数
181
小而美的物联网操作系统,经过14年的累积发展,RT-Thread 已经拥有一个国内最大的嵌入式开源社区,同时被广泛应用于能源、车载、医疗、消费电子等多个行业,累积装机量超过4亿台,成为国人自主开发、国内最成熟稳定和装机量最大的开源 RTOS。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息