【 ST NUCLEO-H743ZI测评】(4)移植Modbus测试(RTU)
<div class='showpostmsg'>本次活动测评开发板ST NUCLEO-H743ZI由ST意法半导体提供,感谢意法半导体对EEWorld测评的支持!STM32H7
NUCLEO_H743ZI
【 ST NUCLEO-H743ZI测评】(1)初识ST NUCLEO-H743ZI
【 ST NUCLEO-H743ZI测评】(2)以太网测试
【 ST NUCLEO-H743ZI测评】(3)以太网转串口测试
串口和网口都调通了,接下来移植一个Modbus协议栈,在之前的CubeMX基础上,不需要配置其他外设。
一、在之前的工程中,添加Modbus协议栈源码及对应的include位置
二、修改port文件
mbportevent.c:主要实现事件通知,这里用FreeRTos的队列实现
mbportother.c:实现协议栈的临界段处理
mbportserial.c:实现串口初始化,发送处理,接收处理,等等。需要改里面的串口为usart3。
mbporttimer.c:实现Modbus所需要的定时(计时)功能,这里用FreeRTos的周期任务来实现的,也可以用硬件定时器或任务定时器等
具体实现代码作为附件上传。
三、main.c中添加代码
添加保持寄存器的回调处理函数
#include "mbport.h"
#include "mbs.h"
#include "mbutils.h"
static uint16_t usRegHoldingValue;
eMBException
eMyRegHoldingCB( UBYTE * pubRegBuffer, USHORT usAddress, USHORT usNRegs, eMBSRegisterMode eRegMode )
{
eMBException eException = MB_PDU_EX_ILLEGAL_DATA_ADDRESS;
STATIC const ULONG usRegsMappedAt = 0x0200;
ULONG usRegStart = usAddress;
ULONG usRegEnd = usAddress + usNRegs - 1;
USHORT usIndex;
USHORT usIndexEnd;
if( ( usNRegs > 0 ) &&
( usRegStart >= usRegsMappedAt )
&& ( usRegEnd <= ( usRegsMappedAt + MB_UTILS_NARRSIZE( usRegHoldingValue ) ) ) )
{
usIndex = ( USHORT ) ( usRegStart - usRegsMappedAt );
usIndexEnd = ( USHORT ) ( usRegEnd - usRegsMappedAt );
switch ( eRegMode )
{
case MBS_REGISTER_WRITE:
for( ; usIndex <= usIndexEnd; usIndex++ )
{
usRegHoldingValue = ( USHORT ) * pubRegBuffer++ << 8;
usRegHoldingValue |= ( USHORT ) * pubRegBuffer++;
}
break;
default:
case MBS_REGISTER_READ:
for( ; usIndex <= usIndexEnd; usIndex++ )
{
*pubRegBuffer++ = ( UBYTE ) ( usRegHoldingValue >> 8 );
*pubRegBuffer++ = ( UBYTE ) ( usRegHoldingValue & 0xFF );
}
break;
}
eException = MB_PDU_EX_NONE;
}
return eException;
}
StartDefaultTask任务中添加初始化ModbusRTU、注册保持寄存器功能函数、轮询eMBSPoll等
void StartDefaultTask(void const * argument)
{
/* init code for LWIP */
MX_LWIP_Init();
/* USER CODE BEGIN 5 */
xMBSHandle xMBSHdl;
eMBErrorCode eStatus;
if( MB_ENOERR != ( eStatus = eMBSSerialInit( &xMBSHdl, MB_RTU, 1, 1, 115200, MB_PAR_NONE ) ) )
{
}
else if( MB_ENOERR != ( eStatus = eMBSRegisterHoldingCB( xMBSHdl, eMyRegHoldingCB ) ) )
{
( void )eMBSClose( xMBSHdl );
}
else
{
do
{
/* Poll the communication stack. */
eMBSPoll( xMBSHdl );
osDelay(10);
}
while( MB_ENOERR == eStatus );
( void )eMBSClose( xMBSHdl );
}
/* USER CODE END 5 */
}
四、编译运行,打开modbus调试助手测试
读寄存器,初始数据为0
写寄存器测试,写入 0001 0002 0003 0004 0005
再次读出,判断刚才写入已成功。
五、附上modbus源码
此内容由EEWORLD论坛网友dsjsjf原创,如需转载或用于商业用途需征得作者同意并注明出处
</div><script> var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;" style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
if(parseInt(discuz_uid)==0){
(function($){
var postHeight = getTextHeight(400);
$(".showpostmsg").html($(".showpostmsg").html());
$(".showpostmsg").after(loginstr);
$(".showpostmsg").css({height:postHeight,overflow:"hidden"});
})(jQuery);
} </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script> 1) 总结测试的很到位
2) 建议捎带着把modus的通信协议简单介绍一下,效果会更好^_^ 懒猫爱飞 发表于 2019-3-2 08:40
1) 总结测试的很到位
2) 建议捎带着把modus的通信协议简单介绍一下,效果会更好^_^
谢谢捧场
页:
[1]