dsjsjf 发表于 2019-3-1 16:53

【 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>

懒猫爱飞 发表于 2019-3-2 08:40

1) 总结测试的很到位
2) 建议捎带着把modus的通信协议简单介绍一下,效果会更好^_^

dsjsjf 发表于 2019-3-6 22:03

懒猫爱飞 发表于 2019-3-2 08:40
1) 总结测试的很到位
2) 建议捎带着把modus的通信协议简单介绍一下,效果会更好^_^

谢谢捧场
页: [1]
查看完整版本: 【 ST NUCLEO-H743ZI测评】(4)移植Modbus测试(RTU)