肛门坠胀用什么药| 圣是什么生肖| 1999年属兔的是什么命| 子宫内膜异位症有什么症状| 喊麦什么意思| 梦到活人死了是什么预兆| 感冒嗓子疼吃什么消炎药| 梦见自己坐火车是什么意思| 骨折不能吃什么东西| 七星伴月是什么意思| 人的运气跟什么有关| 肺部结节吃什么好| 乂是什么意思| 法令纹上的痣代表什么| 明矾和白矾有什么区别| 2月23日什么星座| 血糖高吃什么中药好| 奇门遁甲是什么意思| 竹勿念什么| 安徽有什么好吃的| 笃什么意思| 凶神宜忌是什么意思| 筷子掉地上是什么征兆| 什么是太岁| 石千读什么| 安徽的特产是什么| 什么是风湿| 无花果吃多了有什么坏处| 胶原蛋白是什么意思| gl小说是什么意思| 冠状沟是什么位置| 五月是什么月| 单核细胞是什么意思| ipa是什么意思| 外聘是什么意思| 皮肤长斑是什么原因引起的| ck是什么| 建成区是什么意思| 空气炸锅可以做什么| 妮是什么意思| 干邑是什么意思| 白带是什么意思| 孕妇吃维生素c有什么好处| 就寝是什么意思| 右胸上方隐痛什么原因| 入港是什么意思| 什么是阴阳人| 睡觉流鼻血是什么原因| 孕妇d2聚体高是什么原因| 低烧是什么原因引起的| 梦见上班迟到什么意思| 上日下立读什么| 农历5月25日是什么星座| 为什么会突然不爱了| 木耳和什么不能一起吃| 胃粘膜糜烂吃什么药| psd是什么意思| 什么时候立夏| 什么泡水喝可以降血糖| 什么是绿茶| 农家一碗香是什么菜| 小孩腹泻吃什么药好得快| 小代表什么生肖| 爆单是什么意思| 脾湿吃什么中成药| 微信英文名叫什么| 2022年是什么生肖年| 耷拉的近义词是什么| 屁股骨头疼是什么原因| 癌胚抗原偏高说明什么| 腔梗是什么意思| Valentino什么牌子| 十二月六号是什么星座| 为什么不建议光子嫩肤| 怀孕一个星期有什么症状| 什么卫什么海| 万马奔腾是什么生肖| 儿童细菌感染吃什么药| 肠道紊乱吃什么药| 双侧卵巢多囊性改变是什么意思| 慕斯蛋糕是什么意思| 女性更年期在什么年龄段| 鹰的天敌是什么动物| 借条和欠条有什么区别| 心脏吃什么药最好| 冯巩什么军衔| 沉积是什么意思| 喜欢绿色的女人是什么性格| 什么是质子| 做活检前要注意什么| 结肠憩室是什么意思| 血小板压积偏低是什么意思| 六爻小说讲的什么| 铁观音属于什么茶| 朵字五行属什么| 看乙肝挂什么科| 腋臭是什么原因引起的| 肚子疼去医院挂什么科| 今年24岁属什么生肖| 梦见打苍蝇是什么意思| 什么是电解质水| 酥油是什么做的| 白内障什么症状| 左眉上方有痣代表什么| 格格不入什么意思| 眼底筛查是检查什么| 大姨妈不能吃什么水果| 什么样的池塘| 腕管综合征吃什么药| 为什么无缘无故流鼻血| 衣原体感染吃什么药| 偷鸡不成蚀把米什么意思| 皮下出血是什么原因| 梦是什么意思| 什么家庭不宜挂八骏图| amh是什么意思| 中气下陷是什么意思| 老是打嗝什么原因| 通讯地址是什么意思| 热血病是什么病| tga是什么意思| 康养中心是做什么的| 羊肉炖什么补肾壮阳| 包干费用是什么意思| 白绫是什么意思| 腹痛拉稀什么原因| 讨好的笑是什么笑| 什么是地中海饮食| 什么王| ppm是什么单位| bid是什么意思| 十二生肖叫老大是什么生肖| 蛇的眼睛是什么颜色| 嫡孙是什么意思| 海马体是什么| hla一b27阳性是什么意思| 宫腔积液排出什么颜色| 下体有异味是什么原因| 怠工是什么意思| 势如破竹是什么意思| 什么秀丽| 缺镁吃什么食物补充最快| 保妇康栓是治疗什么的| 心口疼挂什么科| 肺炎吃什么药| 甲状腺分泌什么激素| 今天出生的男宝宝取什么名字好| 没主见是什么意思| 为什么十五的月亮十六圆| 鲑鱼是什么鱼| 喝断片了是什么意思| 荷叶配什么减肥效果好| 肌酐高吃什么药| 狗鼻子干是什么原因| 蛔虫是什么意思| 眼睛发涩是什么原因导致的| 咳嗽有白痰吃什么药最好| 区法院院长是什么级别| 介入医学科是什么科室| 头晕吃什么药效果好| 梦见床上有蛇什么预兆| 眼睛充血是什么原因造成的| 天秤座有什么特点| 吃螃蟹不能吃什么| 灵魂契合是什么意思| 妇科检查白细胞酯酶阳性是什么意思| 脑干堵塞什么症状| 19岁属什么的生肖| 虫至念什么| 高烧吃什么药退烧快| 守望相助是什么意思| 什么是风湿热| 癞蛤蟆吃什么| 海带与什么食物相克| 为什么兔子的眼睛是红色的| 左眼皮一直跳什么原因| 反刍什么意思| 省委组织部长是什么级别| 张信哲属什么生肖| 收缩压和舒张压是什么意思| 牙龈发紫是什么原因| 三焦是什么| 心脏彩超可以检查什么| 葫芦的寓意是什么| 四方草地是什么生肖| 银黑了用什么可以洗白| 右耳朵耳鸣是什么原因| 飞机杯有什么用| 男性尿道出血什么原因| 胎毒是什么意思| 尿酸高不能吃什么蔬菜| 人头什么动| 山西属于什么地区| 火命适合佩戴什么首饰| 阳虚是什么原因引起的| 肠梗阻有什么症状| 双子座男和什么座最配对| 玉米吃了有什么好处| 逆天改命是什么意思| dsa是什么| 脚后跟长痣有什么寓意| 椎间盘轻度膨出是什么意思| 小个子适合什么发型| 口臭是什么原因| 什么符号| 虾仁炒什么| 什么是玄关在哪个位置| 什么是坚果| 黄体不足吃什么补最快| 头孢曲松是什么药| 荷花五行属什么| 男人练臀桥有什么用| 虚劳病是什么病| 经血逆流的症状是什么| 云南白药草长什么样| 5公里25分钟什么水平| 尿酸高吃什么药最好| 为什么不能空腹喝牛奶| 陆家嘴为什么叫陆家嘴| 吐槽是什么意思啊| 乌龙茶是什么茶| 爱新觉罗是什么民族| 臭鼬是什么动物| 什么蛇有毒| 什么是九宫格| 肌酸什么时候喝比较好| 肝早期硬化身体有什么症状| 礽是什么意思| 龟苓膏不能和什么一起吃| 吊儿郎当是什么意思| 番薯是什么时候传入中国的| 脚上真菌感染用什么药| 什么时候可以查高考成绩| 打嗝是什么病的前兆| 这个表情什么意思| 唐氏筛查和无创有什么区别| petct是什么| 扁平足是什么样子图片| 5.20是什么星座| 拆线去医院挂什么科| 普字五行属什么| 生化流产是什么原因造成的| 带下病是什么病| 福德是什么意思| 腰椎退行性改变什么意思| 吃什么能消除脂肪瘤| 四肢无力是什么原因| 三焦不通吃什么中成药| 牛油果有什么功效| 梦见家里好多蛇是什么预兆| 湿疹吃什么食物| 丑是什么生肖| 眼睛充血用什么眼药水好| 肛门裂口是用什么药膏| 房水由什么产生| 乡试第一名叫什么| 颌下腺肿大是什么原因| 什么是间质瘤| 热泪盈眶的盈是什么意思| 什么矿泉水最好| adl是什么意思| 槟榔中间的膏是什么| 早上8点到9点是什么时辰| 628是什么星座| 百度
打印
[APM32F4]

·冯骥才谈传统节日的情怀:想给小学生编传统

[复制链接]
78|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 hbzjt2011 于 2025-8-2 14:11 编辑

1. 概述
本文将介绍如何在Geehy APM32F402R Micro-EVB开发板上,基于RT-Thread实时操作系统和Freemodbus开源库实现Modbus主机功能,并使用Modbus Slave工具进行通信测试。

1.1 硬件平台
  • 开发板: Geehy APM32F402R Micro-EVB
  • MCU: APM32F402RBT6 (Cortex-M4F, 128KB Flash, 32KB SRAM)
  • 通信接口: UART2


1.2 软件环境
  • 操作系统: RT-Thread 5.2.1
  • Modbus库: Freemodbus 1.6
  • 开发环境: Keil MDK
  • 测试工具: Modbus Slave


1.3 FreeModbus 简介
FreeModbus 是一个基于 BSD 协议的开源嵌入式 Modbus 协议栈,支持 RTU、ASCII 及 TCP 三种传输模式,具有高度可移植性和模块化设计。它可运行于裸机系统,也适用于集成 RTOS 的嵌入式平台,特别适合 STM32、AVR、ARM Cortex-M 等微控制器平台。FreeModbus 提供从站和主站功能接口,便于快速集成至工业控制、自动化设备中。我们将采用 RTU 从站模式与主机进行通信,结合 UART 作为物理接口。
标准Modbus功能:
  • 支持保持寄存器读写(功能码03/06/16)
  • 支持输入寄存器读取(功能码04)
  • 支持线圈读写(功能码01/05/15)
  • 支持离散输入读取(功能码02)
系统架构
应用层 (user_mb_app.c)
    ↓
Modbus协议栈 (mb.c, mbrtu.c等)
    ↓  
移植层 (mb_port_*.c)
    ↓
ThreadX RTOS
    ↓
APM32F402硬件层


2. 环境搭建2.1 RT-Thread配置在RT-Thread配置中启用以下组件:
RT-Thread Components → Device Drivers → Using Serial Device Drivers
RT-Thread Components → Device Drivers → Using Pin Device Drivers
RT-Thread online packages → IoT - internet of things → freemodbus


2.2 Freemodbus软件包配置
在RT-Thread配置菜单中设置:
使用pkgs --update更新组件
使用scons --target=mdk5更新工程


3. 软件实现
生成的Keil工程如下:

board.c
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date           Author       Notes
* 2025-08-04     Abbcc        first version
*/

#include "board.h"

void apm32_usart_init(void)
{
    GPIO_Config_T GPIO_ConfigStruct = {0U};

#ifdef BSP_USING_UART1
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_USART1);

    GPIO_ConfigStruct.mode = GPIO_MODE_AF_PP;
    GPIO_ConfigStruct.pin = GPIO_PIN_9;
    GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
    GPIO_Config(GPIOA, &GPIO_ConfigStruct);

    GPIO_ConfigStruct.mode = GPIO_MODE_IN_FLOATING;
    GPIO_ConfigStruct.pin = GPIO_PIN_10;
    GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
    GPIO_Config(GPIOA, &GPIO_ConfigStruct);
#endif

#ifdef BSP_USING_UART2
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);
    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_USART2);

    GPIO_ConfigStruct.mode = GPIO_MODE_AF_PP;
    GPIO_ConfigStruct.pin = GPIO_PIN_2;
    GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
    GPIO_Config(GPIOA, &GPIO_ConfigStruct);

    GPIO_ConfigStruct.mode = GPIO_MODE_IN_FLOATING;
    GPIO_ConfigStruct.pin = GPIO_PIN_3;
    GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
    GPIO_Config(GPIOA, &GPIO_ConfigStruct);
#endif
}

void apm32_msp_can_init(void *Instance)
{
#if defined(BSP_USING_CAN1) || defined(BSP_USING_CAN2)
    GPIO_Config_T  GPIO_InitStructure;
    CAN_T *CANx = (CAN_T *)Instance;

    if (CAN1 == CANx)
    {
        RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_CAN1);

        RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);

        /* PB8: CAN1_RX, PB9: CAN1_TX */
        GPIO_InitStructure.pin = GPIO_PIN_8 | GPIO_PIN_9;
        GPIO_InitStructure.mode = GPIO_MODE_AF;
        GPIO_InitStructure.otype = GPIO_OTYPE_PP;
        GPIO_InitStructure.speed = GPIO_SPEED_100MHz;
        GPIO_InitStructure.pupd = GPIO_PUPD_UP;
        GPIO_Config(GPIOB, &GPIO_InitStructure);

        GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_8, GPIO_AF_CAN1);
        GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_9, GPIO_AF_CAN1);
    }
    else if (CAN2 == CANx)
    {
        /* When using the CAN2 peripheral, the CAN1 clock must be turned on */
        RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_CAN1);
        RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_CAN2);

        RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);

        /* PB12: CAN2_RX, PB13: CAN2_TX */
        GPIO_InitStructure.pin = GPIO_PIN_12 | GPIO_PIN_13;
        GPIO_InitStructure.mode = GPIO_MODE_AF;
        GPIO_InitStructure.otype = GPIO_OTYPE_PP;
        GPIO_InitStructure.speed = GPIO_SPEED_100MHz;
        GPIO_InitStructure.pupd = GPIO_PUPD_UP;
        GPIO_Config(GPIOB, &GPIO_InitStructure);

        GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_12, GPIO_AF_CAN2);
        GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_13, GPIO_AF_CAN2);
    }
#endif
}
Modbus主机轮询程序:
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date           Author       Notes
* 2025-08-04     flybreak     first version
*/

#include <rtthread.h>

#include "mb.h"
#include "mb_m.h"

#ifdef PKG_MODBUS_MASTER_SAMPLE
#define SLAVE_ADDR      MB_SAMPLE_TEST_SLAVE_ADDR
#define PORT_NUM        MB_MASTER_USING_PORT_NUM
#define PORT_BAUDRATE   MB_MASTER_USING_PORT_BAUDRATE
#else
#define SLAVE_ADDR      0x01
#define PORT_NUM        3
#define PORT_BAUDRATE   115200
#endif
#define PORT_PARITY     MB_PAR_EVEN

#define MB_POLL_THREAD_PRIORITY  10
#define MB_SEND_THREAD_PRIORITY  RT_THREAD_PRIORITY_MAX - 1

#define MB_SEND_REG_START  2
#define MB_SEND_REG_NUM    2

#define MB_POLL_CYCLE_MS   500

static void send_thread_entry(void *parameter)
{
    eMBMasterReqErrCode error_code = MB_MRE_NO_ERR;
    rt_uint16_t error_count = 0;
    USHORT data[MB_SEND_REG_NUM] = {0};

    while (1)
    {
        /* Test Modbus Master */
        data[0] = (USHORT)(rt_tick_get() / 10);
        data[1] = (USHORT)(rt_tick_get() % 10);

        error_code = eMBMasterReqWriteMultipleHoldingRegister(SLAVE_ADDR,          /* salve address */
                                                              MB_SEND_REG_START,   /* register start address */
                                                              MB_SEND_REG_NUM,     /* register total number */
                                                              data,                /* data to be written */
                                                              RT_WAITING_FOREVER); /* timeout */

        /* Record the number of errors */
        if (error_code != MB_MRE_NO_ERR)
        {
            error_count++;
        }
    }
}

static void mb_master_poll(void *parameter)
{
    eMBMasterInit(MB_RTU, PORT_NUM, PORT_BAUDRATE, PORT_PARITY);
    eMBMasterEnable();

    while (1)
    {
        eMBMasterPoll();
        rt_thread_mdelay(MB_POLL_CYCLE_MS);
    }
}

static int mb_master_sample(int argc, char **argv)
{
    static rt_uint8_t is_init = 0;
    rt_thread_t tid1 = RT_NULL, tid2 = RT_NULL;

    if (is_init > 0)
    {
        rt_kprintf("sample is running\n");
        return -RT_ERROR;
    }
    tid1 = rt_thread_create("md_m_poll", mb_master_poll, RT_NULL, 512, MB_POLL_THREAD_PRIORITY, 10);
    if (tid1 != RT_NULL)
    {
        rt_thread_startup(tid1);
    }
    else
    {
        goto __exit;
    }

    tid2 = rt_thread_create("md_m_send", send_thread_entry, RT_NULL, 512, MB_SEND_THREAD_PRIORITY - 2, 10);
    if (tid2 != RT_NULL)
    {
        rt_thread_startup(tid2);
    }
    else
    {
        goto __exit;
    }

    is_init = 1;
    return RT_EOK;

__exit:
    if (tid1)
        rt_thread_delete(tid1);
    if (tid2)
        rt_thread_delete(tid2);

    return -RT_ERROR;
}
MSH_CMD_EXPORT(mb_master_sample, run a modbus master sample);
编译下载程序,在rt-thread的finsh命令中运行mb_master_sample程序


4. 使用Modbus Slave进行测试
4.1 Modbus Slave设置
  • 下载并安装Modbus Slave工具
  • 配置串口参数:
    • 端口:选择对应的COM口
    • 波特率:115200
    • 数据位:8
    • 停止位:1
    • 校验位:None
    • 从站地址:1


4.2 Modbus Slave测试
可以对保持寄存器进行读取和设置


5. 总结
本文介绍了在Geehy APM32F402R Micro-EVB开发板上基于RT-Thread和Freemodbus实现Modbus主机的过程:
  • 掌握RT-Thread下Freemodbus的配置和使用
  • 理解Modbus主机的工作原理和实现方法
  • 学会使用Modbus Slave工具进行通信测试
  • 具备扩展更多Modbus功能的能力


发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:欢迎参与LabVIEW版块的讨论学习! 点我一键即达

256

主题

2828

帖子

44

粉丝
墓志铭什么意思 菩提什么意思 淋巴结肿大是什么引起的 cg是什么 老白茶属于什么茶
低筋面粉可以用什么代替 为什么睡觉出虚汗 冠心病什么症状 检查肝肾功能挂什么科 孕妇嗓子疼可以吃什么药
金达莱花是什么花 摆摊卖什么好 什么是年金 戒备心是什么意思 什么是音爆
什么是备孕 县长属于什么级别 检测hpv挂什么科 杨桃什么季节成熟 四物汤是什么
属龙的和什么属相最配hcv9jop6ns7r.cn 看病人买什么水果hcv8jop9ns6r.cn AD是什么意思啊jiuxinfghf.com 夏天适合吃什么水果hcv8jop4ns8r.cn 宇五行属什么hcv8jop0ns5r.cn
豚鼠吃什么食物0735v.com b超和阴超有什么区别clwhiglsz.com 什么时候浇花最好hcv8jop2ns2r.cn 神奇的近义词是什么hcv7jop6ns1r.cn ne医学上是什么意思hcv8jop2ns9r.cn
吃什么排铅hcv9jop4ns9r.cn 一天什么时候血压最高hcv8jop7ns2r.cn 化痰止咳吃什么药最好hcv9jop8ns2r.cn 菜心是什么菜的心shenchushe.com 喰种是什么意思hcv9jop3ns9r.cn
转机是什么意思hcv8jop3ns2r.cn 1973年是什么年hcv8jop7ns6r.cn 熊猫血有什么好处hcv8jop3ns5r.cn 竣字五行属什么hcv8jop1ns2r.cn 众叛亲离是什么意思hcv8jop3ns1r.cn
百度