OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4197|回复: 14

MODBUS主机正常通讯一次需要消耗多少时间

[复制链接]

2

主题

13

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2015-1-15
在线时间
62 小时
发表于 2020-5-9 10:59:21 | 显示全部楼层 |阅读模式
使用战舰V3作为modbus主机,串口1调试,串口2进行458通信,带操作系统FreeRTOS,从机使用Modbus Slave,波特率115200通信正常

modbus_read_holding_registers()函数功能,主机发送请求命令,等待从机返回数据,返回的数据保存在reg

tmp = xTaskGetTickCount();   //获取 时间点A
status= modbus_read_holding_registers(1,0,2,reg);
tmp1 = xTaskGetTickCount(); //获取 时间点B
printf("%d \r\n",tmp1-tmp);   //  B-A 等于一次正常通信消耗的时间


主机读取从机的寄存器,主机发出请求需要的八个字节的数据时间为A,从机返回响应数据,主机接受到数据时间为B,B-A为一次正常通信消耗的时间,我的大概是60ms


问题:想请教,主机正常通讯一次一般需要消耗多少时间,如果一次通信消耗按100MS计算,10个从机,每台从机轮询一次就需要1S,数据采集,1S一次就比较慢了


无标题.png
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

55

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2018-12-27
在线时间
0 小时
发表于 2020-5-9 10:59:22 | 显示全部楼层
回复 支持 反对

使用道具 举报

0

主题

70

帖子

0

精华

初级会员

Rank: 2

积分
72
金钱
72
注册时间
2019-7-11
在线时间
1 小时
发表于 2020-5-9 10:59:39 | 显示全部楼层
帮顶,原子哥,来溜一下。。。
回复 支持 反对

使用道具 举报

2

主题

172

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3142
金钱
3142
注册时间
2014-11-29
在线时间
183 小时
发表于 2020-5-9 12:42:58 | 显示全部楼层
你一次需要60ms,是有些慢了,应该有改进空间,应该在10ms内能完成一次通讯吧
回复 支持 反对

使用道具 举报

22

主题

2251

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4480
金钱
4480
注册时间
2013-4-22
在线时间
337 小时
发表于 2020-5-9 13:21:01 | 显示全部楼层
lutigers 发表于 2020-5-9 12:42
你一次需要60ms,是有些慢了,应该有改进空间,应该在10ms内能完成一次通讯吧

数据解析,数据延时,数据组包加起来都不只10ms,正常通信500ms足够了
回复 支持 反对

使用道具 举报

2

主题

13

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2015-1-15
在线时间
62 小时
 楼主| 发表于 2020-5-9 14:22:51 | 显示全部楼层
lutigers 发表于 2020-5-9 12:42
你一次需要60ms,是有些慢了,应该有改进空间,应该在10ms内能完成一次通讯吧

波特率115200 按 1 8 N 1 计算, 发送8个字节需要大约0.7MS,5MS内就应该可以完成一次通信,我打印出来时间最快的时候也在20多MS
回复 支持 反对

使用道具 举报

2

主题

13

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2015-1-15
在线时间
62 小时
 楼主| 发表于 2020-5-9 14:39:08 | 显示全部楼层
三叶草 发表于 2020-5-9 13:21
数据解析,数据延时,数据组包加起来都不只10ms,正常通信500ms足够了

之前没特别注意过数据包处理的时间,刚jlink调试了一下,好似300MS,应该更不对了,难道我调试错了?我打印的时间只有60多MS呀
回复 支持 反对

使用道具 举报

22

主题

2251

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4480
金钱
4480
注册时间
2013-4-22
在线时间
337 小时
发表于 2020-5-9 16:06:43 | 显示全部楼层
幸福的小小范 发表于 2020-5-9 14:39
之前没特别注意过数据包处理的时间,刚jlink调试了一下,好似300MS,应该更不对了,难道我调试错了?我打 ...

O(∩_∩)O哈哈~,你处理有时间吧,CPU占用资源越多,你的时间越长,传输的数据越多,时间越多,这个是可以计算的
回复 支持 反对

使用道具 举报

2

主题

13

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2015-1-15
在线时间
62 小时
 楼主| 发表于 2020-5-11 10:12:52 | 显示全部楼层
三叶草 发表于 2020-5-9 13:21
数据解析,数据延时,数据组包加起来都不只10ms,正常通信500ms足够了

感谢你的耐心回复,modbus之前没用过,有两个问题一直困惑着我,向您咨询咨询,一个modbus从机问题,一个是主机问题,先咨询从机问题:

STM32战舰V3板子,移植modbus从机
使用标准库STM32F10x_StdPeriph_Lib_V3.5.0
FreeRTOSv9.0
FreeMODBUS V1.6
波特率:115200 1 8 N 1
以主机读一个线圈为例
主机发送8字节数据,从机返回8字节数据

1/115200 * 10 * 8 = 1/1440 = 0.69ms   按1MS计算

从机接收一帧数据,从接收第一字节到接收完毕需要1MS
从机发送一帧数据,从发送第一字节到第八字节需要1MS

从机响应时间 = 从机接受数据时间 + 从机处理数据时间 + 从机发送数据时间
从机接受数据时间 = 1ms  //从机接受数据时间应该大于1ms
从机发送数据时间 = 1ms      //从机发送数据时间应该大于1ms
从机处理数据时间 这个我没经验无法估算 假如按5MS计算

从机响应时间 = 1 + 5 + 1 = 7MS

按上面计算,我认为从机响应一个周期是7MS,主机最快每7MS进行一次通讯,不知道对不对
如果主机每5MS发送一次请求,则从机反应不过来


以上分析的不知道对不对??

这里遇到困惑:
static void Test_Task(void* parameter)
{       
        eMBInit(MB_RTU,0x01,0,115200,MB_PAR_NONE);//115200 1 8 N 1
        eMBEnable();
        while(1)
        {
                eMBPoll();               
                vTaskDelay(50);///////问题1处    带操作系统的话,这里延时50ms
        }       
}

一共两个任务,一个低优先级任务LED灯闪烁,Test_Task任务为高优先级

上面分析理论上从机响应一个周期是7MS,这里vTaskDelay(50)
问题1:问题1处 系统延时50MS,我认为这里就会把从机的处理周期设每50MS,不对,应该是57MS,(一帧数据 eMBPoll->EV_FRAME_RECEIVED 接收,延时vTaskDelay(50), eMBPoll->EV_EXECUTE 处理并发送 ,为完整的一个周期
如果主机每40MS发送一次请求,然而从机从接受数据到发送数据一个周期为57MS,所以主机发送请求周期应该大于57MS


如果想让从机反应及时,就把vTaskDelay(50)延时改小


不知道我分析的对不对??

时间轴
0  1  2 3 4 5 6 7 8 9 ... 50 51 52 53 54 55 56 57 58 59 60
      A                            B                 
时间点A 执行eMBPoll :EV_FRAME_RECEIVED        
时间点B 执行eMBPoll :EV_EXECUTE

原因在eMBPoll中
eMBPoll()
{
        switch ( eEvent )
        {
        ...       
        case EV_FRAME_RECEIVED:        //接收到一帧数据
            case EV_EXECUTE: //处理数据,发送响应帧,发送响应给主机
                }
}

先eMBPoll 执行 EV_FRAME_RECEIVED接收到主机发送的请求帧数据,
再eMBPoll 执行 EV_EXECUTE 处理主机发送的请求帧,解析,最后发送响应给主机

        while(1)
        {
                eMBPoll();               
                vTaskDelay(50);///////问题1处    带操作系统的话,这里延时50ms
        }       
里面执行过程类似这样:
        eMBPoll                       //第一次通讯
                case EV_FRAME_RECEIVED:   //从机接收一帧数据
        .......
        .......
        vTaskDelay(50);
        .......
        .......
        eMBPoll
                case EV_EXECUTE:         //处理数据,发送响应帧,发送响应给主机
        vTaskDelay(50);
        eMBPoll                                           //第2次通讯
                case EV_FRAME_RECEIVED:  //从机接收一帧数据
        .......
        .......
        vTaskDelay(50);
        .......
        .......
        eMBPoll
                case EV_EXECUTE:        //处理数据,发送响应帧,发送响应给主机
        vTaskDelay(50);
       
       

















回复 支持 反对

使用道具 举报

3

主题

1155

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7464
金钱
7464
注册时间
2015-1-15
在线时间
1368 小时
发表于 2020-5-11 10:38:08 来自手机 | 显示全部楼层
你定时器超时时间不用考虑?你还用这么多的延时函数
回复 支持 反对

使用道具 举报

2

主题

13

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2015-1-15
在线时间
62 小时
 楼主| 发表于 2020-5-11 12:52:51 | 显示全部楼层
yklstudent 发表于 2020-5-11 10:38
你定时器超时时间不用考虑?你还用这么多的延时函数


感谢你的解答:

static void Test_Task(void* parameter)
{      
        eMBInit(MB_RTU,0x01,0,115200,MB_PAR_NONE);//115200 1 8 N 1
        eMBEnable();
        while(1)
        {
                eMBPoll();               
                vTaskDelay(50);///////问题1处    带操作系统的话,这里延时50ms
        }      
}


任务里只有这一个延时呀,定时器超时3.5字符时间,如果在超时之前接收到数据,直接将数据丢弃,并重新开始定时,直到超时,超时标识一帧数据传输完毕,然后进行数据处理,
你说的:时器超时时间不用考虑?不太明白什么意思
你说的那么多延时?,,只有一个延时呀 vTaskDelay(50);///////问题1处    带操作系统的话,这里延时50ms

回复 支持 反对

使用道具 举报

2

主题

13

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
256
金钱
256
注册时间
2015-1-15
在线时间
62 小时
 楼主| 发表于 2020-5-11 14:11:00 | 显示全部楼层
yklstudent 发表于 2020-5-11 10:38
你定时器超时时间不用考虑?你还用这么多的延时函数

我找到耗时的地方

第一步:主机发送完一帧数据请求后使能串口接收,设置事件xEventGroupWaitBits
第二步:主机接收到一帧数据,定时器1800US后超时,我在定时器超时  xEventGroupSetBitsFromISR 设置事件
第三步:禁止发送,禁止接收,处理数据

代码如下


  mb_port_serial_enable(MB_POLL_FALSE,MB_POLL_TRUE);//  /*使能发送*/       // 串口发送一帧数据后 在串口中断中 xEventGroupSetBitsFromISR事件组置位
  xEventGroupWaitBits(              //等待 串口   发送完一帧数据                              
                                        mb_poll_events_group,
                                        MB_POLL_SEND_OVER_EVT,
                                        pdTRUE,
                                        pdFALSE,
                                        MODBUS_POLL_SEND_TIMEOUT);       

//串口发送完一帧数据后,进行接收从机响应
  mb_port_serial_enable(MB_POLL_TRUE,MB_POLL_FALSE); /*使能接收*/  //串口接收完一帧数据,启动定时器,在定时器 1800US超时后 xEventGroupSetBitsFromISR 事件组置位
  event = xEventGroupWaitBits(
                                        mb_poll_events_group,       
                                        MB_POLL_RESPONSE_EVT,         
                                        pdTRUE,                            
                                        pdFALSE,                    
                                        MODBUS_POLL_RESPONSE_TIMEOUT);       
  
  /*禁止发送,禁止接收*/
  mb_port_serial_enable(MB_POLL_FALSE,MB_POLL_FALSE);


我发现是从定时器超时xEventGroupSetBitsFromISR,到上面红色字体xEventGroupWaitBits这里消耗了30-50MS

难道是执行事件通讯消耗大量的时间?





回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2020-9-30
在线时间
7 小时
发表于 2020-12-9 13:12:11 | 显示全部楼层
能不能发一下工程文件
回复 支持 反对

使用道具 举报

0

主题

15

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
431
金钱
431
注册时间
2018-10-26
在线时间
115 小时
发表于 2020-12-10 09:32:31 | 显示全部楼层
这个vTaskDelay(50);     用不着50,换小一点也行
回复 支持 反对

使用道具 举报

18

主题

151

帖子

0

精华

高级会员

Rank: 4

积分
508
金钱
508
注册时间
2020-4-22
在线时间
241 小时
发表于 2020-12-11 09:24:57 | 显示全部楼层
本帖最后由 moranyidui 于 2020-12-11 09:26 编辑

115200,几十个字节的话,一般来说,30ms差不多
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-23 20:13

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表