Modbus_TCP在Android与STM32F4上的应用

本文介绍了如何在Android和STM32F429上实现Modbus_TCP通信协议,详细讲解了Modbus协议的原理、功能码及数据帧结构,并展示了硬件配置和软件实现,包括RTOS的LWIP使能和MODBUS协议包的移植。通过验证,实现了在Android APP上读写STM32F429的保持寄存器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天记录的是在学习了Modbus_RTU之后学习学习Modbus_TCP,并通过android系统的APP读写保持寄存器。

一、引言

为了学习为了学习为了学习。重要的事情说三遍。好了,that's over.

二、实验目的

为了实现移动端与终端的数据通信,应用MODBUS的通信协议,实现单片机与手机端的数据通信。

三、实验器材

硬件:1、原子哥的STM32F429IGTx开发板。2、安卓手机一部
软件:1、MDK5。2、STM32CUBEMX。3、Android Studio

四、实验原理

本实验的实验原理主要分为通信协议部分、硬件部分、软件部分。

1、modbus通信协议

modbus是很久以前的通信协议了。大概给介绍一下。
Modbus协议包括两个通信规程中使用的MODBUS应用层和服务规范
a.串行链路的RTU协议(这个在之前介绍过)
b.TCP/IP上的MODBUS。

在这里插入图片描述
上图是MODBUS的IOS层模型的两个通信规程。本次实验主要介绍的就是Modbus on TCP.modbus是OSI模型的第七层报文传输协议,它连接至不同类型总线或网络的设备之间提供客户机/服务器通信。MODBUS是一个请求/应答协议,并提供功能码规定的服务。本文将介绍MODBUS协议的各个功能码,并主要介绍本实验用到的读写寄存器的功能码。
下面是关于MODBUS协议允许在各种网络体系结构内进行简单通信。包括PLC、HMI以及一些IO口通信

在这里插入图片描述
MODBUS协议是通过报文传输数据,报文的结构是由地址域、功能码、数据和差错校验组成的。一般情况下Modbus是使用CRC校验的,但是在实际的使用中,Modbus_TCP是不用CRC校验的。因为TCP协议本身就存在校验+重传功能,所以MODBUS协议在TCP的应用上是不需要CRC校验的。
下图是modbus的数据帧结构
在这里插入图片描述
因为modbus是请求/应答的形式,所以在整个通信协议当中存在主站和从站,而且是一个主站+多个从站的组合形式。而且通信都是modbus主站发送查询指令,然后从站根据主站发送过来的功能码进行相应的操作。
当服务器对客户机响应时,它使用功能码来指示正常(无差错)响应或者出现某种差错(称为异常响应)。对于一个正常响应来说,服务器仅对原始功能码响应。
下图分别是对正常响应以及异常响应的解析图。在这里插入图片描述
在这里插入图片描述
关于modbus的一个逻辑流程图如下:
在这里插入图片描述
modbus的功能码有三个类型,分别是公共功能码、用户定义功能码、保留功能码。在这里主要使用的是公共功能码,便介绍公共功能码,至于其他功能码请自行翻阅modbus通信协议。
公共功能码一共有13个。其中有单个比特访问、16个比特访问、文件记录访问以及封装借口。
在这里插入图片描述
在这里主要应用的就是对保持寄存器的读写。因此主要使用的功能码就是03读保持寄存器功能码,以及06写单个寄存器功能码。
1.03 (0x03)读保持寄存器
在一个远程设备中,,使用该功能码读取保持寄存器连续块的内容。请求PDU说明了起始寄存器地址和寄存器数量。从零开始寻址寄存器。因此,寻址寄存器1-16为0-15.
将响应报文中的寄存器数据围城每个寄存器有两字节,在每个字节中直接地调整二进制内容。对于每个寄存器,第一个字节包括高位,并且第二个字节也包括低位比特。
在这里插入图片描述
下图是一个请求读寄存器108-110的实例:
在这里插入图片描述
将寄存器108的内容表示为两个十六进制字节值022B,或十进制555。将寄存器109-110的内容分别表示为十六进制0000和0064,或者十进制0和100。
在这里插入图片描述
2、06(0x06)
(偷点懒,直接上图。请大佬自行理解)
在这里插入图片描述
在这里插入图片描述
关于modbus大概就介绍到这里了,详细具体的细节还请自行了解modbus协议。如若有需要文档的,可以文末留言邮箱。

2、硬件

因本实验所用硬件载体为原子的阿波罗开发板STM32F429IGTx。是在STM32CUBEMX开发平台上配置相应的功能。由于是TCP/IP,而在开发板上只能板载轻型的TCP/IP协议即LWIP。下面是在CUBEMX上一些相应的配置。
使能ETH

在这里插入图片描述
由于要用到网络,需要用到操作系统,这里使能的是FREE RTOS
在这里插入图片描述
关于LWIP的使能,就是大概介绍一下
在这里插入图片描述
主要的都在这里了,毕竟是之前介绍过,就不具体详细讲了。如果不了解想知道的话可以看之前的博客。
https://mp.youkuaiyun.com/postedit/90084421
在这里插入图片描述
至于时钟树的配置都是不超过限定钟频即可。
关于硬件的配置就大体记录到这里了。

3、软件

软件这一部分包括开发板的程序以及安卓端的APP程序。
(1)开发板软件部分
在这里主要是移植了MODBUS的协议包。说实话,modbus_tcp比RTU简单超多,基本上把协议包移植过去就能直接使用了
在这里插入图片描述
协议包的内容我就不具体讲了,有需要的可以留言邮箱。都是根据Modbus协议转换成的代码。我也会把这个发到github上,有需要的可以自行下载。链接见文末。
在rtos的空闲任务队列中,加入两行代码

void TCPTask02(void const * argument)
{
   
   
  /* USER CODE BEGIN TCPTask02 */
	
	eMBTCPInit(0);	
	eMBEnable();
  /* Infinite loop */
  for(;;)
  {
   
   
		//socket_server_init();
		eMBPoll();
    osDelay(1);
  }
  /* USER CODE END TCPTask02 */
}

关于这两个函数的详细代码

#if MB_TCP_ENABLED > 0
eMBErrorCode
eMBTCPInit( USHORT ucTCPPort )
{
   
   
    eMBErrorCode    eStatus = MB_ENOERR;

    if( ( eStatus = eMBTCPDoInit( ucTCPPort ) ) != MB_ENOERR )
    {
   
   
        eMBState = STATE_DISABLED;
    }
    else if( !xMBPortEventInit(  ) )
    {
   
   
        /* Port dependent event module initalization failed. */
        eStatus = MB_EPORTERR;
    }
    else
    {
   
   
        pvMBFrameStartCur = eMBTCPStart;
        pvMBFrameStopCur = eMBTCPStop;
        peMBFrameReceiveCur = eMBTCPReceive;
        peMBFrameSendCur = eMBTCPSend;
        pvMBFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBTCPPortClose : NULL;
        ucMBAddress = MB_TCP_PSEUDO_ADDRESS;
        eMBCurrentMode = MB_TCP;
        eMBState = STATE_DISABLED;
    }
    return eStatus;
}
#endif

eMBEnable( void )
{
   
   
    eMBErrorCode    eStatus = MB_ENOERR;

    if( eMBState == STATE_DISABLED )
    {
   
   
        /* Activate the protocol stack. */
        pvMBFrameStartCur(  );
        eMBState = STATE_ENABLED;
    }
    else
    {
   
   
        eStatus = MB_EILLSTATE;
    }
    return eStatus;
}
eMBPoll( void )
{
   
   
    static UCHAR   *ucMBFrame;
    static UCHAR    ucRcvAddress;
    static UCHAR    ucFunctionCode;
    static USHORT   usLength;
    static eMBException eException;

    int             i;
    eMBErrorCode    eStatus = MB_ENOERR;
    eMBEventType    eEvent;

    /* Check if the protocol stack is ready. */
    if( eMBState != STATE_ENABLED )
    {
   
   
        
用户可以根据需求在驱动库里选择相对应的通讯驱动程序,配置相应的通讯握手参数,自由定义需要控制和采集的变量名、通讯地址、数据类型和初始值。功能说明及图片展示: 1.安装完成首次进入将会显示三页功能简要展示页面。 2.点击“立即使用”按钮,进入登录界面(公测账户为admin,密码admin)。 3.登录成功进入APP主页,此时主页所有状态为初始未配置状态。 4.在主页状态下向右滑动,可打开功能模块选择列表。 5.点击“WIFI连接”进入连接现场设备网络页面,如果此时用户已通过手WIFI页面连接现场设备,则直接跳过此步骤。 6.连接成功后返回功能模块选择列表,点击“参数设置”进入通讯相关参数配置页面(首先进入驱动配置页面),目前驱动库中只有支持Modbus TCP的驱动,后续会持续更新,用户通过在驱动库列表中长按操作将选中的驱动挑选至已选列表中,如果要取消,可以在已选列表中通过同样的长按操作完成。 7.配置要访问的设备通讯参数,主页的操作逻辑一致,在驱动配置页面向右滑动打开配置功能列表,点击“通讯参数配置”进入通讯参数配置页,然后点击右上角的加号,此时软件会根据已选的驱动类型自动添加一条相对应的通讯参数,用户可以通过双击的方式打开修改列表,然后在列表的某一条参数处通过长按的方式进入最终的修改对话框,修改完成后,可以通过长按的方式选定当前需要的参数配置信息到已选区域。 8.通讯参数配置完成后,向右滑动进入配置功能列表,点击“IO参数配置”进入地址段的分配,点击右上角的加号,在弹出的对话框中根据实际需求分配响应的起始地址以及地址数量,分配完成后,可在屏幕右侧边缘向左滑动调出隐藏功能菜单,通过功能菜单可查看和修改配置地址段的功能对应的IO点信息。 9.所有配置完成后,可返回主页,此时主页显示当前配置的信息,其中“控制操作”功能可以通过按钮发送布尔值,操作逻辑为当前值为0时发送1,当前值为1时发送0,而“参数设置”功能通过对子项长按可以设置调出输入框设置相应的参数值。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值