hyz_rtt
hyz_rtt

注册于 2 years ago

回答
0
文章
0
关注者
0

dong0520 发表于 2018-11-16 10:31
问题解决,将RT_TICK_PER_SECOND改成1000就可以了


是103板子 HSE8M吗

dong0520 发表于 2018-11-15 14:18
我刚好也在搞这个modbus主机,我debug了一下代码发现是usart接收的问题,每次只能接收到usart返回的第一个 ...


非常感谢你的分享

armink 发表于 2018-11-6 11:04
这个开源库已经出啦很久了,主机的所有功能都都没问题的。感觉还是你的用法哪块有有问题。先别随意的放大 ...


f103工程附件

下载附件[f103modbus_master.rar]

armink 发表于 2018-11-6 11:04
这个开源库已经出啦很久了,主机的所有功能都都没问题的。感觉还是你的用法哪块有有问题。先别随意的放大 ...


我昨晚又重新用ENV配置了一个发f103ZET6的主机例程,结果和之前407的板子一样。协议内容除了串口的设置其他没有做更改,下面是操作方法,仅仅尝试一个写保持寄存器功能,
从数据帧看到写入成功,但写保持寄存器的返回值仍为超时错误(跟踪发现)。
操作代码如下
void thread_entry_ModbusMasterPoll(void* parameter)
{
eMBMasterInit(MB_RTU,2,115200,MB_PAR_NONE);
eMBMasterEnable();
while (1)
{
eMBMasterPoll();
}
}
static void led_thread_entry(void* parameter)
{

eMBMasterReqErrCode errorCode = MB_MRE_NO_ERR;
uint16_t errorCount = 0;
while (1)
{
rt_thread_delay(1000);
errorCode = eMBMasterReqWriteHoldingRegister(1,3,errorCount,RT_WAITING_FOREVER);
//记录出错次数
if (errorCode != MB_MRE_NO_ERR)
{
errorCount++;
}
}
}
YMCCB~7$9Z[9M)X99H52N}N.png
errorCount的值一直增加。
现在很困惑啊,请大神再指教一下。
工程压缩后老是上传失败...

armink 发表于 2018-11-6 11:04
这个开源库已经出啦很久了,主机的所有功能都都没问题的。感觉还是你的用法哪块有有问题。先别随意的放大 ...


工程是通过ENV配置的,然后修改了串口及485配置,外部晶振频率(25M\8M昨晚也尝试了,应该和晶振无关),时钟节拍改成0.05ms,T3.5那里也改了,计算是1.75ms(115200波特率),其他地方也没做更改,操作方法就是按照大神之前共享的代码里的测试方法,使用用户的API进行操作。进行读写都没问题,一进行缓冲区数据操作就操作不了,操作方法就是在读写保持寄存器操作后,将缓冲区数组按照说明来直接赋值给变量。我也看了个之前您回复相关问题的论坛帖子
FreeModbus主机下如何获取相关寄存器的实际数据?
https://www.rt-thread.org/qa/forum.php?mod=viewthread&tid=7964&fromuid=11674
(出处: RT-Thread开发者社区)
我的理解就是直接操作缓冲区数组,操作的方法,我把代码发给你,大神帮忙看看。
回头我再重新建立工程,放置我没注意把modbus代码哪里给更改了。

armink 发表于 2018-11-5 13:50
超时原因就是你的从机没有返回呀。


我跟总了一下eMBMasterPoll()函数,第一次进入是eEvent为EV_MASTER_READY,然后就跳出eMBMasterPoll()函数,然后跟踪继续第二次循环进去eMBMasterPoll()函数,
eEvent为 EV_MASTER_FRAME_SENT,然后eEvent为EV_MASTER_READY,然后就跳出eMBMasterPoll()函数,然后再第三次循环进入eMBMasterPoll()函数,在进行语句
if( xMBMasterPortEventGet( &eEvent ) == TRUE )便走不动了,

armink 发表于 2018-11-5 13:50
超时原因就是你的从机没有返回呀。


对于主机保存从机的数据缓存区数据的获取操作,之前有测试过嘛?我看主机源程序操作里没有相关的测试代码,只测试了读写。
对于系统节拍,我设置的50微妙,但对于T3.5还是确保1.75ms的(波特率115200),不知道系统节拍对这个会不会有影响。

armink 发表于 2018-11-5 13:51
你可以再看下 “往 1 号从机的寄存器 1 写入数据“” 为啥能成功


嗯 等没事了我再跟踪下 做个记录 分析下

armink 发表于 2018-11-4 09:37
你先分析下超时问题,其他问题不要揉在一起


看了一下午,目前没找到原因,1、跟踪返回值为超时错误的函数eMBMasterWaitRequestFinish( ),等到系统事件接收rt_event_recv(&xMasterOsEvent,
EV_MASTER_PROCESS_SUCESS | EV_MASTER_ERROR_RESPOND_TIMEOUT
| EV_MASTER_ERROR_RECEIVE_DATA
| EV_MASTER_ERROR_EXECUTE_FUNCTION,
RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER,
&recvedEvent);

就走不下去,然后跟进去这个函数,然后跟着跟着就回到用户操作函数了eMBMasterReqErrCode
eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usRegData, LONG lTimeOut )了
2、自己的想法是,主机的用户API是怎样和其回调接口函数联系的进而进行数据缓存的?没找到之间相关的调用和联系。

然后就是发现和回掉接口函数有直接调用关系的是这些报文解析函数(例如eMBException
eMBMasterFuncWriteHoldingRegister( UCHAR * pucFrame, USHORT * usLen )),而这些报文解析函数是放在
xMBFunctionHandler xMasterFuncHandlers[MB_FUNC_HANDLERS_MAX]数组里的,这些函数会在eMBMasterPoll( )里
被查询到执行case EV_MASTER_EXECUTE的情况时执行:看是广播还是不是广播,然后调用报文解析函数,再在报文解
析函数里调用接口回掉函数来进行数据缓存,我目前的理解是这么缓存数据的。
然后我就跟踪eMBMasterPoll( )函数的执行,发现只是会循环执行case EV_MASTER_READY、 case EV_MASTER_FRAME_RECEIVED,
然后就跳出,并没有执行case EV_MASTER_EXECUTE的情况,报文解析函数就没执行过,回掉函数也就不会被调用,就缓存不了数据。
哪里理解不对,大神再指点一下,感觉很茫然:'(

armink 发表于 2018-11-4 09:37
你先分析下超时问题,其他问题不要揉在一起


好的

[quote][size=2][url=forum.php?mod=redirect&goto=findpost&pid=39004&ptid=8235][color=#999999]armink 发表于 2018-11-3 13:48[/color][/url][/size] 有没有查看这个函数的返回结果[/quote] [size=4]跟踪看了一下,无论是读写均返回值eMBMasterReqErrCode变量eErrStatus均为MB_MRE_TIMEDOUT(响应超时。[/size][size=4]主机在设定的时间内未收到从机响应。/*!< timeout error occurred. */)[/size][size=4]具体截图如下[/size] [size=4][attach]6749[/attach][/size] [size=4]为什么返回值超时,读写保持寄存器数据却成功了,后面是因为主机等待请求完成函数eMBMasterWaitRequestFinish( void ) 的返回值[/size] [size=4]为超时错误而导致数据无法存到定义的缓冲区吗?[/size]

armink 发表于 2018-11-3 13:48
有没有查看这个函数的返回结果


没有,我把那个返回结果的变量省去了,回头我加上再试试

    本帖最后由 hyz_rtt 于 2018-11-2 19:59 编辑


armink 发表于 2018-11-2 19:37
发现你到现在都没有区分哪个才是用户采用的主机请求 API 呀。建议再仔细看下文档

https://github.com/ar ...

I[X2$H$~M1`MG${~(C$[(@Y.png
我是如下操作的
     rt_thread_delay(10000);/*必须通讯延时500ms*/

ControlWord=0x47e;
//写单个保持寄存器(增强型,保持寄存器协议地址0(PLC地址400001)存储内容为控制字,可写可读)
//函数参数:从机地址;保持寄存器地址;修改后的寄存器值F;超时时间
eMBMasterReqWriteHoldingRegister(0x03,0x00,ControlWord,RT_WAITING_FOREVER);
REF1 =5000;
eMBMasterReqWriteHoldingRegister(0x03,0x01,REF1,RT_WAITING_FOREVER);

eMBMasterReqReadHoldingRegister(0x03,0x00,0x03,RT_WAITING_FOREVER);
rt_thread_delay(200);

StatusWord = usMRegHoldBuf[2][1];//获得状态字的值

eMBMasterReqWriteHoldingRegister(0x03,0x03,StatusWord,RT_WAITING_FOREVER);



发布
问题