随着工业技术的发展,HMI(人机界面)的应用领域愈加广泛。通过拓普微的智能液晶显示模块实现的自定义通信协议能在一定程度上维护企业的数据隐秘性,提升产品功能的多样性,并且能够解决企业通信协议不兼容问题。
HMI的串口通信规则,除了标准Modbus协议产品,大多都是根据原厂制定的协议规则进行。然而许多企业也有其各自的通信规则及报文格式,在配套使用HMI开发应用时,企业希望保留或使用自己的功能特性和数据交互规则,用以匹配自己协议的应用开发。
基于此,拓普微的HMI串口屏有一套较为成熟的设计方案。本文将介绍智能显示模块 HMT050DTA-D 如何基于LUA脚本设计实现,在原厂提供的库函数中,有开放串口控制类的API,通过这些API函数能够实现企业的自定义通信协议设计。
此次设计将通过拓普微的智能液晶屏HMI的串口,配合LUA程序,应用串口控制类API,实现目标协议通信功能。
HMI串口通信协议,常见的报文格式一般由“帧头”、“长度码”、“功能码”、“参数数据信息”、“帧尾”、“校验码”几个部分组成。通信过程中,系统将实时查询串口的数据接收,获取符合协议的报文数据,执行规定的指令功能。
如下“表2-1:自定义协议通信报文格式”,定义了一种常见的通信报文格式。(硬件串口参数说明:波特率“115200”;数据位“8”;停止位“1”;校验如下表)
表2-1:自定义协议通信报文格式
*1. 指令长度码,计算“命令码”到“校验码”中所有数据的字节总数。
*2. 指令地址、数据、参数信息,是多字节数据,数据都是高位在前,低位在后。
*3. 指令校验码,计算“帧头”到“帧尾”中所有的数据的ModbusCRC-16校验。
目前使用的型号HMT050DTA-D默认是TOPWAY协议通信的,存在指令错误码回复机制。因此在自定义协议通信过程中,如果没有屏蔽原协议,可能会存在串口占用,回复数据混乱的情况。所以在设计自己协议通信时首先要把原厂的协议屏蔽,避免数据冲突。
获取串口数据后,需要提取符合自定义协议规则的指令以便后续对指令进行解析并执行指令功能。因此需要定义接收指令数组,用以存储串口中符合协议规则的指令数据。
协议通信中,也存在指令回复功能,比如读取/访问地址数据的指令。在解析完接收到的指令后,我们要对部分指令进行响应,所以需要定义回复指令数组,对读取/访问操作的指令进行回复。
在LUA程序设计中,需要实现的功能板块有:①从串口接收区中获取符合规定自定义规则的指令,存储在接收指令数组;②调用接收到的指令数据,对指令数据进行解析;③调用相应的功能处理函数,执行指令功能。对于读取/访问信息类的指令,还需要操作串口发送数据进行回复。
解析的指令目前主要实现4功能板块。①功能码“0x01”:访问/读取变量数据;②功能码“0x02”:改写变量数据;③功能码“0x03”:工程显示跳页;④功能码“0x04”:屏幕背光亮度控制。主要板块功能关系如图3-1所示。
图3-1 协议通信主要功能板块
在拓普微提供的LUA库函数中存在TOPWAY协议禁用函数,可以在程序初始化时调用该函数对原厂的通信协议进行屏蔽。如图4-1
调用函数:hmt.bypass(is)
输入:参数“is”使能开关。
使用说明:当“is=1”时屏蔽原TOPWAY协议,“is=0”时使用TOPWAY协议。
定义数组:CustProt_recvcmd = {}
类型:全局数组,初始化时定义。
说明:存储串口接收区中符合协议规则的指令数据。接收指令数据过程中,如过不符合定义的规则,需清空接收数组。
定义数组:CustProt_sendcmd = {}
类型:全局数组,初始化时定义。
说明:根据协议规则,存储需要通过串口进行回复的指令数据。发送完成后清空数组。
LUA程序设计,主要实现函数功能见流程图4-2。
调用函数:hmt.uartisempty()
输出:返回“1”时表示串口接收buf为空;返回“0”时表示串口接收区存在数据。
使用说明:使用该函数判断串口接收区是否存在数据。等于0时再去执行指令获取函数。
构造函数:get_CustProtrecvcmd()
输出:接收指令数组 CustProt_recvcmd。
说明:将符合自定义协议的指令存储在全局的接收指令数组;期间会对指令中帧头、帧尾、长度码3种类型的数据格式进行判断。不符合自定义协议时将清空指令数组。
调用函数:hmt.getchar()
输出:串口接收队列的第一个字节数据。
使用说明:在函数get_CustProtrecvcmd()中,获取符合自定义协议指令时会频繁调用该函数,对串口接收区的数据进行筛选。
构造函数:CmdCheck(CustProt_recvcmd)
输入:接收指令数组 CustProt_recvcmd。
说明:函数会对接收指令数组中的数据码和校验码2个类型的数据格式进行判断。不符合自定义协议时将清空指令数组,回复错误码,并重新开始获取指令。
构造函数:CmdHandle(CustProt_recvcmd)
输入:接收指令数组 CustProt_recvcmd。
说明:函数根据指令中的功能码,分类处理指令数据,如数字数据和字符串数据。
3.5.1 读变量数据功能
构造函数:_ReadvariableReturnCmd (Addr)
调用函数:hmt.readvp16(Addr)\hmt.readvp32(Addr)\hmt.readvpstr(Addr)等。
输入:自定义协议中指令的地址数据。
说明:当功能码为“0x01”时使用该函数处理,函数将根据指令中的地址类型,分类调用hmt读变量函数,读回数据并存储在回复指令数组,最后通过串口发送返回。
调用函数:hmt.putchar(byte)
输入:指令字节数据。
说明:读取后回复指令时,会频繁调用该函数,将回复指令数组中的数据通过串口发送。
3.5.2 写变量数据功能
构造函数:_Writevariable(addr, value)
_Writevariable1(addr, strvalue)
调用函数:hmt.writevp16(Addr, value)\hmt.writevp32(Addr, value)\hmt.writevpstr(Addr, strvalue)等。
输入:“Addr”自定义协议中指令的地址数据,“value/strvalue”自定义协议中需要写入变量的数字数据或字符串数据。
说明:当功能码为“0x02”时使用该函数处理,函数将根据指令中的地址类型,分类调用hmt写变量函数,将数字数据或字符串数据写入相应的变量。
调用函数:string.char(byte)
输入:接收自定义指令中的字节。
输出:字符数据。
使用说明:写入字符串变量时,需要通过该函数将数字指令数据转成字符数据写入变量。可以配合字符串连接符“..”转成字符串数据。
3.5.3 工程跳页功能
调用函数:hmt.changepage(pageid)
输入:“pageid”自定义协议中指令的页面ID信息。
使用说明:当功能码为“0x03”时使用该函数处理,CmdHandle中会处理自定义指令中双字节的ID信息为数字数据,然后将数字数据传入该函数,跳转到指定页面。
3.5.4 设置屏幕背光功能
定义数组:setBLcmd = {0x5F, 0x00}
类型:局部数组,在函数CmdHandle中定义。
说明:函数CmdHandle会将自定义指令中亮度值传入数组setBLcmd的第二个字节;配合hmt库函数hmt.runcmd(cmdtable, len)使用,用以执行内部调光指令。
调用函数:hmt.runcmd(cmdtable, len)
输入:“cmdtable”内部指令数组,“len”调用数组长度。
使用说明:当功能码为“0x04”时使用该函数处理,调用局部数组setBLcmd,执行自定义协议的调节背光功能。
本文所介绍的使用拓普微智能液晶显示模块测试通信协议,旨在引出通信协议实现的一种思路,因为工业控制、物联网智能家居、环境监控、数据安全等领域,应用层的功能设计很大程度会影响甚至决定协议层的数据传输格式。
智能显示模块HMI的串口自定义协议通信的实现,用户可以按照自己的需求灵活设计协议规则,控制产品实现期望功能,在一定程度上为应用的功能设计提供了新的解决方案。
全部0条评论
快来发表一下你的评论吧 !