1654|9

32

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

【极海APM32F407 Tiny Board】4通道MODBUS测试 [复制链接]

  本帖最后由 aple0807 于 2023-5-23 21:13 编辑

4通道MODBUS测试

本人从事仪表开发工作,MODBUS是最常用的对外通信协议,主站和从站均经常使用。
APM32共有6个串口,本测试开通4路MODBUS,两路主站和两路从站:
USART2: 主站,9600,8N2
USART3: 主站,115200,8N2
UART4: 从站,9600,8N2
UART6: 从站,115200,8N2

4路串口IO配置如下:

    // UART1-PA9:TX-PA10:RX
    {GPIOA, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_PUPD_NOPULL, GPIO_AF_USART1, GPIO_SPEED_50MHz, 1, GPIO_PIN_9 | GPIO_PIN_10},
    // UART2-PD5-TX:-PD6:RX
    {GPIOD, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_PUPD_NOPULL, GPIO_AF_USART2, GPIO_SPEED_50MHz, 1, GPIO_PIN_5 | GPIO_PIN_6},
    // UART3-PD8-TX:-PD9:RX
    {GPIOD, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_PUPD_NOPULL, GPIO_AF_USART3, GPIO_SPEED_50MHz, 1, GPIO_PIN_8 | GPIO_PIN_9},
    // UART4-PC10:TX-PC11:RX
    {GPIOC, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_PUPD_NOPULL, GPIO_AF_UART4, GPIO_SPEED_50MHz, 1, GPIO_PIN_10 | GPIO_PIN_11},
    // UART6-PC6-TX:-PC7:RX
    {GPIOC, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_PUPD_NOPULL, GPIO_AF_USART6, GPIO_SPEED_50MHz, 1, GPIO_PIN_6 | GPIO_PIN_7},

由于APM32完全兼容STM32,寄存器排列一摸一样,知识寄存器名字和位名字有变化,拿STM32上面的程序移植十分方便。仅仅修改创建MODBUS端口的文件即可开始测试。对于串口MODBUS,底层最关键的就是串口初始化和串口中断。代码较多,这里仅贴出最关键的部分(中断)加以说明,感兴趣的小伙伴可以下载贴尾的代码进行测试。

/*****************************************************************************
 * @brief   UART interrupt routine.
 * @param   none
 * @return    none
 *****************************************************************************/
void qc_isr()
{
    volatile uint32_t IntSt;
    volatile uint8_t Data;

    IntSt = qc_port->STS;

    if (IntSt & (BIT(5) | BIT(3))) // RE ORE
    {
        Data = UART_RCV_DAT();

        if ((IntSt & UART_RX_ERR_FLAG) != 0)
        {
            if (qc_obj.rx_cnt >= 1)
            {
                qc_obj.err_hal = 1;
            }
            UART_RX_ERR_CLR();
        }

        qc_data_rcv(&qc_obj, Data);
    }
    else if ((qc_obj.tx_size <= qc_obj.tx_cnt) && (IntSt & BIT(6))) // TC
    {
        qc_send_end(&qc_obj);
        qc_tx1_rx0_enable(0);
        UART_TX_TC_CLR();
    }
    else if (IntSt & BIT(7)) // TE
    {
        if (qc_data_send(&qc_obj, qc_rtu_byte_send, 1))
        {
            UART_TX_TC_EN();
        }
    }
    else
    {
    }
}

中断主要处理三种状态:
a、接受中断:保存数据到BUFF
b、发送空闲中断:继续发送下一个数据
c、发送完成中断:从机结束或主机进入等待。
吐槽一下:APM32的寄存器位操作仅支持位域操作,不像STM32那样有位定义的宏。用官方寄存器定义的话,同一寄存器的多个位也要分开操作,效率较低;并且对于UART状态寄存器中的错误标记位,这些位读自动清除,需要多次使用的话很不方便。上面的程序就很无奈,只好用了BIT(X)宏看着手册编了。好在需要多此判断的地方不多,不然这程序就狗血了。

应用层如下配置,两主两从,主机随意添加两条命令:

void qc_task(const void *argv)
{
    qc_cmd_type mcmd;
    uu8 bdone;

    // master config
    qc02_Init(QC_MODE_MASTER, 115200, MB_PAR_NONE);
    mb.qc02.os_event_send = mb_os_send;
    
    // master config
    qc03_Init(QC_MODE_MASTER, 9600, MB_PAR_NONE);
    mb.qc03.os_event_send = mb_os_send;
    
    // slave config
    qc04_Init(QC_MODE_SLAVE, 115200, MB_PAR_NONE);
    mb.qc04.os_event_send = mb_os_send;
    
    // slave config
    qc06_Init(QC_MODE_SLAVE, 9600, MB_PAR_NONE);
    mb.qc06.os_event_send = mb_os_send;

    // cmd config
    mcmd.id = 1;
    mcmd.wdat = mb_tst.pv_w;
    mcmd.rdat = mb_tst.pv_r;
    mcmd.wa = word_make(0xF, 5);
    mcmd.wn = 4;
    mcmd.ra = word_make(0x00, 0x10);
    mcmd.rn = 6;
    mcmd.callback = qc_callback;
    mcmd.attr = QC_MB_ATTR_HOLD_RW;
    mqc_stc_cmd_req(&mb.qc03, 0, &mcmd);
    mqc_stc_cmd_req(&mb.qc02, 0, &mcmd);
    mqc_stc_cmd_req(&mb.qc04, 0, &mcmd);
    mqc_stc_cmd_req(&mb.qc06, 0, &mcmd);

    mcmd.wa = word_make(0x10, 12);
    mcmd.wn = 0;
    mqc_stc_cmd_req(&mb.qc03, 1, &mcmd);
    mqc_stc_cmd_req(&mb.qc02, 1, &mcmd);
    mqc_stc_cmd_req(&mb.qc04, 1, &mcmd);
    mqc_stc_cmd_req(&mb.qc06, 1, &mcmd);

    mcmd.wa = word_make(0x0C, 8);
    mcmd.wn = 8;
    mcmd.ra = word_make(0x0C, 8);
    mcmd.rn = 8;
    mcmd.wdat = mb_tst.reg_w;
    mcmd.rdat = mb_tst.reg_r;
    mcmd.attr = QC_MB_ATTR_HOLD_RW;
    mb.qc03.fun->stc_cmd_req(2, &mcmd);
    mb.qc02.fun->stc_cmd_req(2, &mcmd);

    mqc_dyna_cmd_req(&mb.qc03, &mcmd);
    mqc_dyna_cmd_req(&mb.qc02, &mcmd);
    mqc_dyna_cmd_req(&mb.qc03, &mcmd);
    mqc_dyna_cmd_req(&mb.qc02, &mcmd);

    loop(32) mb_tst.reg_w[index] = index;
    mb_tst.reg_w[0] = 0x5588;

    // task handle
    for (;;)
    {
        // wait modbus event
        osSemaphoreWait(os_obj.sid_mb, 1000);

        qc_mb_poll(&mb.qc03);
        qc_mb_poll(&mb.qc02);
        qc_mb_poll(&mb.qc04);
        qc_mb_poll(&mb.qc06);
    }
}

硬件将UART2和UART4相连,UART3和UART6相连,如下图所示:

进入状态观察MODBUS对象结构,观察通信成功次数和失败次数,如下所示,说明MODBUS主从站已通信成功,success_cnt指示执行指令成功次数。

下面进行上位机测试,由于手上仅有一个USB-TLL串口,每次只能测试一个端口,以UART4从站进行说明,串口连接在UART4(PC10,PC11)如下图所示。


打开MODBUS调试工具 Modbus Poll,如下配置:从站ID = 1,波特率115200,帧格式8N2。

 

从地址0处读取20通道数据,指令周期50ms

配置运行后结果如下:

至此MODBUS移植测试完成,整个过程十分顺利。

测试代码托管在gitee平台:

链接已隐藏,如需查看请登录或者注册

最新回复

你这个modbus是用的什么库?支持多住多从   详情 回复 发表于 2023-6-19 12:20
点赞 关注
 
 

回复
举报

6105

帖子

4

TA的资源

版主

沙发
 

不错。楼主也玩modbus啊

 
 
 

回复

267

帖子

0

TA的资源

一粒金砂(高级)

板凳
 

楼主厉害了,加油~

个人签名

gitee/casy

 
 
 

回复

4008

帖子

0

TA的资源

版主

4
 

能和cube一起用吗

 

点评

CubeIDE不熟,这个用极海自家的标准库测试,编译环境Keil,跟CubeIDE可能是不兼容的。  详情 回复 发表于 2023-5-24 12:14
 
 
 

回复

32

帖子

0

TA的资源

一粒金砂(中级)

5
 
huo_hu 发表于 2023-5-24 10:13 能和cube一起用吗  

CubeIDE不熟,这个用极海自家的标准库测试,编译环境Keil,跟CubeIDE可能是不兼容的。

 
 
 

回复

286

帖子

0

TA的资源

一粒金砂(高级)

6
 

楼主,modus是移植库嘛


点评

是的  详情 回复 发表于 2023-5-24 18:03
 
 
 

回复

4008

帖子

0

TA的资源

版主

7
 

modbus只是个协议外壳,再标准也没大用

点评

实际项目中modbus协议栈基本都会直接配置成设备间内存映射,至于内存中的数据定义已经和modbus无关了。  详情 回复 发表于 2023-5-24 18:05
 
 
 

回复

32

帖子

0

TA的资源

一粒金砂(中级)

8
 
怀揣少年梦 发表于 2023-5-24 12:50 楼主,modus是移植库嘛

是的

 
 
 

回复

32

帖子

0

TA的资源

一粒金砂(中级)

9
 
huo_hu 发表于 2023-5-24 14:54 modbus只是个协议外壳,再标准也没大用

实际项目中modbus协议栈基本都会直接配置成设备间内存映射,至于内存中的数据定义已经和modbus无关了。

 
 
 

回复

54

帖子

0

TA的资源

一粒金砂(中级)

10
 

你这个modbus是用的什么库?支持多住多从

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表