Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Modbus
关于modbus主机如何获得缓冲区数据的问题
发布于 2018-11-01 18:02:09 浏览:8920
订阅该版
1、已经确定读写保持寄存器成功 ![MasterTest 03先写入保持寄存器值成功并随后成功读取写入的寄存器值.png.png](/uploads/201811/01/173809eip2h2w2vi0907w6.png) 2、目的:要获取这个寄存器里的值0x47e,并把它赋值给一个变量(只是以此为例子,实际是读取一个只可读的寄存器里的值,然后使用)。 3、程序里是先往保持寄存器0x50(400051)里写入0x47e,再读取写入的值0x47e,从步骤1中的模拟里的收发数据帧可知读写成功。 查贴和一些相关博客得知: * (A)FreeModbus从机默认使用 一维数组作为缓存区数据结构; * (B)FreeModbus主机可以存储所有网内从机的数据,所以主机采用二维数组对所有从机节点数据进行存储. *二维数组的列号代表寄存器、线圈及离散量地址,行号代表从机节点ID,但需要做减一处理 *例如usMRegHoldBuf[2][1]代表从机ID为 3,保持寄存器地址为 1 的从机数据。 在读保持寄存器语句之后,进行变量赋值,a=usMRegHoldBuf[3][0],实际得到的是a的值始终为0,无论是进行程序跟踪,观察变量值变化,还是 将a再写入寄存器的其他地址进行模拟从数据帧看到仍是0。 4、随后查找原因,对比从机,发现从机里保持寄存器的读写函数里都是有调用其对应的保持寄存器回掉函数的。 再回来看主机,发现主机保持寄存器的操作函数里有两种(此处粘贴读保持寄存器的函数): (1)第一个函数内容如下 ```eMBMasterReqErrCode eMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs, LONG lTimeOut ) { UCHAR *ucMBFrame; eMBMasterReqErrCode eErrStatus = MB_MRE_NO_ERR; if ( ucSndAddr > MB_MASTER_TOTAL_SLAVE_NUM ) eErrStatus = MB_MRE_ILL_ARG; else if ( xMBMasterRunResTake( lTimeOut ) == FALSE ) eErrStatus = MB_MRE_MASTER_BUSY; else { vMBMasterGetPDUSndBuf(&ucMBFrame); vMBMasterSetDestAddress(ucSndAddr); ucMBFrame[MB_PDU_FUNC_OFF] = MB_FUNC_READ_HOLDING_REGISTER; ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] = usRegAddr >> 8; ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF + 1] = usRegAddr; ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF] = usNRegs >> 8; ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF + 1] = usNRegs; vMBMasterSetPDUSndLength( MB_PDU_SIZE_MIN + MB_PDU_REQ_READ_SIZE ); ( void ) xMBMasterPortEventPost( EV_MASTER_FRAME_SENT ); eErrStatus = eMBMasterWaitRequestFinish( ); } return eErrStatus; }```可以看到此函数里是没有调用其对应的回调接口函数eMBErrorCode eMBMasterRegHoldingCB(UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode)的,所以我觉得这个数据没有存进回掉接口函数对应的缓冲区数组USHORT usMRegHoldBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_HOLDING_NREGS]里 (2)第二个函数如下 ```eMBMasterFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen ) { UCHAR *ucMBFrame; USHORT usRegAddress; USHORT usRegCount; eMBException eStatus = MB_EX_NONE; eMBErrorCode eRegStatus; /* If this request is broadcast, and it's read mode. This request don't need execute. */ if ( xMBMasterRequestIsBroadcast() ) { eStatus = MB_EX_NONE; } else if( *usLen >= MB_PDU_SIZE_MIN + MB_PDU_FUNC_READ_SIZE_MIN ) { vMBMasterGetPDUSndBuf(&ucMBFrame); usRegAddress = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF] << 8 ); usRegAddress |= ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_ADDR_OFF + 1] ); usRegAddress++; usRegCount = ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF] << 8 ); usRegCount |= ( USHORT )( ucMBFrame[MB_PDU_REQ_READ_REGCNT_OFF + 1] ); /* Check if the number of registers to read is valid. If not * return Modbus illegal data value exception. */ if( ( usRegCount >= 1 ) && ( 2 * usRegCount == pucFrame[MB_PDU_FUNC_READ_BYTECNT_OFF] ) ) { /* Make callback to fill the buffer. */ eRegStatus = eMBMasterRegHoldingCB( &pucFrame[MB_PDU_FUNC_READ_VALUES_OFF], usRegAddress, usRegCount, MB_REG_READ ); /* If an error occured convert it into a Modbus exception. */ if( eRegStatus != MB_ENOERR ) { eStatus = prveMBError2Exception( eRegStatus ); } } else { eStatus = MB_EX_ILLEGAL_DATA_VALUE; } } else { /* Can't be a valid request because the length is incorrect. */ eStatus = MB_EX_ILLEGAL_DATA_VALUE; } return eStatus; } #endif```这个函数里是有调用回调接口函数eMBErrorCode eMBMasterRegHoldingCB(UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode)的,但是这个函数是放在这里,然后主函数里也没有使用,使用的都是第一个函数来读保持寄存器的。 5、问题 (1)是不是我哪里理解的有问题? (2)缓冲区有没有找错? (3)操作方式对不对? 希望有操作过的大神指点一下,谢谢!
查看更多
38
个回答
默认排序
按发布时间排序
armink
2018-11-01
这家伙很懒,什么也没写!
你的描述,我看的不是很明白。 我想确认下,先别关心太复杂的地址情况,常规情况下,往 1 号从机的寄存器 1 写入数据是否成功?
hyz_rtt
2018-11-02
这家伙很懒,什么也没写!
[i=s] 本帖最后由 hyz_rtt 于 2018-11-2 09:00 编辑 [/i] 我的目的是读取某一保持寄存器的值后,然后从其对应的缓冲区获得这个寄存器的值进行使用。
hyz_rtt
2018-11-02
这家伙很懒,什么也没写!
>你的描述,我看的不是很明白。 > >我想确认下,先别关心太复杂的地址情况,常规情况下,往 1 号从机的寄存器 ... --- 读写都成功的,从图里的收发数据帧可以看到是成功的,而且我在实际使用时可以确认也写入成功了
armink
2018-11-02
这家伙很懒,什么也没写!
接着来,再测试下 1 号从机的 50 寄存器是否成功
hyz_rtt
2018-11-02
这家伙很懒,什么也没写!
>接着来,再测试下 1 号从机的 50 寄存器是否成功 --- 成功的 [attach]6744[/attach]。
hyz_rtt
2018-11-02
这家伙很懒,什么也没写!
>接着来,再测试下 1 号从机的 50 寄存器是否成功 --- 我有一个疑问,在mb_m.c里 ``` /* An array of Modbus functions handlers which associates Modbus function * codes with implementing functions. */ //将Modbus函数代码与实现函数相关联的Modbus函数处理程序数组xMasterFuncHandlers[16] static xMBFunctionHandler xMasterFuncHandlers[MB_FUNC_HANDLERS_MAX] = { #if MB_FUNC_OTHER_REP_SLAVEID_ENABLED > 0 //TODO Add Master function define {MB_FUNC_OTHER_REPORT_SLAVEID, eMBFuncReportSlaveID}, #endif #if MB_FUNC_READ_INPUT_ENABLED > 0 {MB_FUNC_READ_INPUT_REGISTER, eMBMasterFuncReadInputRegister}, #endif #if MB_FUNC_READ_HOLDING_ENABLED > 0 {MB_FUNC_READ_HOLDING_REGISTER, eMBMasterFuncReadHoldingRegister}, #endif #if MB_FUNC_WRITE_MULTIPLE_HOLDING_ENABLED > 0 {MB_FUNC_WRITE_MULTIPLE_REGISTERS, eMBMasterFuncWriteMultipleHoldingRegister}, #endif #if MB_FUNC_WRITE_HOLDING_ENABLED > 0 {MB_FUNC_WRITE_REGISTER, eMBMasterFuncWriteHoldingRegister}, #endif #if MB_FUNC_READWRITE_HOLDING_ENABLED > 0 {MB_FUNC_READWRITE_MULTIPLE_REGISTERS, eMBMasterFuncReadWriteMultipleHoldingRegister}, #endif #if MB_FUNC_READ_COILS_ENABLED > 0 {MB_FUNC_READ_COILS, eMBMasterFuncReadCoils}, #endif #if MB_FUNC_WRITE_COIL_ENABLED > 0 {MB_FUNC_WRITE_SINGLE_COIL, eMBMasterFuncWriteCoil}, #endif #if MB_FUNC_WRITE_MULTIPLE_COILS_ENABLED > 0 {MB_FUNC_WRITE_MULTIPLE_COILS, eMBMasterFuncWriteMultipleCoils}, #endif #if MB_FUNC_READ_DISCRETE_INPUTS_ENABLED > 0 {MB_FUNC_READ_DISCRETE_INPUTS, eMBMasterFuncReadDiscreteInputs}, #endif }; ``` 为何全是eMBExceptioneMBMasterFuncReadHoldingRegister( UCHAR * pucFrame, USHORT * usLen )、eMBExceptioneMBMasterFuncReadWriteMultipleHoldingRegister( UCHAR * pucFrame, USHORT * usLen )这样的处理函数,而没有在主函数里实际测试或者使用的eMBMasterReqErrCodeeMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs, LONG lTimeOut )、eMBMasterReqErrCodeeMBMasterReqReadWriteMultipleHoldingRegister( UCHAR ucSndAddr,USHORT usReadRegAddr, USHORT usNReadRegs, USHORT * pusDataBuffer,USHORT usWriteRegAddr, USHORT usNWriteRegs, LONG lTimeOut )。
armink
2018-11-02
这家伙很懒,什么也没写!
>成功的 >。 --- 再试试 3 号从机的 0 寄存器是否成功,完事后再来确认 3 号的 50 寄存器是否成功
armink
2018-11-02
这家伙很懒,什么也没写!
>我有一个疑问,在mb_m.c里 >为何全是eMBExceptioneMBMasterFuncReadHoldingRegister( UCHAR * pucFrame, U ... --- 发现你到现在都没有区分哪个才是用户采用的主机请求 API 呀。建议再仔细看下文档 [https://github.com/armink/FreeModbus_Slave-Master-RTT-STM32#%E4%B8%89api](https://github.com/armink/FreeModbus_Slave-Master-RTT-STM32#%E4%B8%89api)
hyz_rtt
2018-11-02
这家伙很懒,什么也没写!
>再试试 3 号从机的 0 寄存器是否成功,完事后再来确认 3 号的 50 寄存器是否成功 ... --- 我先试的就是0,然后改成50的
hyz_rtt
2018-11-02
这家伙很懒,什么也没写!
>发现你到现在都没有区分哪个才是用户采用的主机请求 API 呀。建议再仔细看下文档 > >https://github.com/ar ... --- 用户操作的是eMBMasterReqErrCodeeMBMasterReqReadHoldingRegister( UCHAR ucSndAddr, USHORT usRegAddr, USHORT usNRegs, LONG lTimeOut )这种的,但是没看到他和回掉函数有任何调用关系,我就是想通过缓冲区来操作读到的保持寄存器数据
撰写答案
登录
注册新账号
关注者
0
被浏览
8.9k
关于作者
hyz_rtt
这家伙很懒,什么也没写!
提问
10
回答
38
被采纳
0
关注TA
发私信
相关问题
1
ModbusRTU协议栈漏发送最后一个字节
2
3.0 增加freemodbus,编译不过
3
RT_THREAD上面的串口MODBUSRTU为啥没功能码?
4
关于 freemodbus 里存在的一点问题分享
5
请教如何使用组件里的FreeMODBUS
6
求一个FreeModbus的从机测试程序
7
FreeModbus的从机调试说明(含测试程序)
8
rtt_freemodbus
9
freemodbus怎么配置到uart
10
FreeModeBus从机调试问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
GD32F450 片内 flash驱动适配
2
STM32H7R7运行CherryUSB
3
RT-Smart首次线下培训,锁定2024 RT-Thread开发者大会!
4
使用RC522软件包驱动FM1722
5
常量数据类型和表达式陷阱分享
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
freemodbus
PWM
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
中断
编译报错
Debug
SFUD
rt_mq_消息队列_msg_queue
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
a1012112796
10
个答案
1
次被采纳
踩姑娘的小蘑菇
4
个答案
1
次被采纳
红枫
4
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
Ryan_CW
4
个答案
1
次被采纳
本月文章贡献
catcatbing
3
篇文章
5
次点赞
YZRD
2
篇文章
5
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
Woshizhapuren
1
篇文章
5
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部