USART HMI 资料中心

官方技术交流QQ群:916560014

站点工具


6.指令集:6.高级应用与特殊指令

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
6.指令集:6.高级应用与特殊指令 [2019/09/02 16:56]
admin
6.指令集:6.高级应用与特殊指令 [2020/04/08 13:13] (当前版本)
admin
行 1: 行 1:
-<h1 style="​white-space:​ normal;​font-size:​ 32px;​border-bottom:​ 2px solid rgb(204, 204, 204);​padding:​ 0px 4px 0px 0px;​text-align:​ center;​margin:​ 0px 0px 20px"><​span style="​font-family:​ arial, helvetica, sans-serif;​font-size:​ 24px"><​strong>​HMI</​strong><​strong>​高级应用与特殊指令详解</​strong></​span></​h1><​p style="​white-space:​ normal"><​span style="​font-size:​ 18px;​font-family:​ arial, helvetica, sans-serif">&​nbsp;<​strong>​本文档主要讲述一些高级应用,实现一些特殊功能,大多数项目是用不上这些功能的,如果您的项目用不上,可以忽略此文档。</​strong></​span></​p><​p style="​white-space:​ normal"><​span style="​background-color:​ rgb(242, 242, 242);​font-size:​ 32px;color: rgb(192, 80, 77);​font-family:​ arial, helvetica, sans-serif"><​br/></​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​strong>​【章节索引】</​strong></​span></​p><​p style="​white-space:​ normal"><​a href="#​b1"​ target="​_self">​一.串口数据解析模式篇之主动解析模式应用详解</​a></​p><​p style="​white-space:​ normal"><​a href="#​b2"​ target="​_self">​二.HMI下载协议详解</​a></​p><​p style="​white-space:​ normal"><​a href="#​comcrc"​ target="​_self">​三.串口指令增加CRC校验</​a></​p><​p style="​white-space:​ normal"><​a href="#​comfile" target="​_self">​四.运行中串口传输图片到内存或SD卡</​a></​p><​p style="​white-space:​ normal"><​br/></​p><​table width="​100%"><​tbody><​tr class="​firstRow"><​td style="​background-color:​ rgb(146, 208, 80)"><​p style="​text-align:​ center"><​span style="​font-family:​ arial, helvetica, sans-serif"><​strong><​span style="​font-size:​ 19px;​font-family:​ 宋体"><​a name="​b1"></​a></​span></​strong><​strong>​一.串口数据解析模式篇之主动解析模式应用详解</​strong></​span></​p></​td></​tr></​tbody></​table><​table width="​100%"><​tbody><​tr class="​firstRow"><​td style="​background-color:​ rgb(238, 236, 225)"><​p><​span style="​font-family:​ 宋体, SimSun">​屏幕上电默认是被动解析模式,所有串口指令需按照指令集中的格式来对屏幕进行操作,假如你需要自定义协议,不按照指令集格式来发串口数据给屏幕,而使用你自定义的格式,那么就需要把屏幕配置为主动解析模式。要使用此功能,请务必确保你有以下2点基础:</​span></​p><​p><​span style="​font-family:​ 宋体, SimSun">​1.明白什么叫HEX,​什么叫String,​什么叫ASCII,​分别什么关系,怎么转换。&​nbsp;​ &nbsp; &​nbsp;</​span></​p><​p><​span style="​font-family:​ 宋体, SimSun">​2.明白单字节数值,双字节数值,四字节数值,分别有什么区别,它们在内存中是什么样的储存方式,明白什么叫小端模式,什么叫大端模式。明白低位在前是什么含义。&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;</​span></​p><​p><​span style="​font-family:​ 宋体, SimSun">​如果以上2点你都比较明白,那么请继续往下看,否则强烈建议不要再继续往下看了,因为大多数的项目是用不上这个功能的,使用默认的被动解析模式就可以了,没必要配置为下面的主动解析模式。</​span></​p></​td></​tr></​tbody></​table><​p style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​此篇幅涉及到以下几个内容</​span>:</​span></​p><​p class="​MsoListParagraph"​ style="​margin-left:​ 24px;​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei">​1.<​span style="​font-variant-numeric:​ normal;​font-variant-east-asian:​ normal;​font-stretch:​ normal;​font-size:​ 9px;​line-height:​ normal;​font-family:​ &#​39;​Times New Roman&#​39;">&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;</​span></​span><​span style="​font-family:​ 宋体">​串口数据解析模式系统变量</​span><​span style="​font-family:​ 黑体, SimHei">:​recmod</​span></​span></​p><​p class="​MsoListParagraph"​ style="​margin-left:​ 24px;​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei">​2.<​span style="​font-variant-numeric:​ normal;​font-variant-east-asian:​ normal;​font-stretch:​ normal;​font-size:​ 9px;​line-height:​ normal;​font-family:​ &#​39;​Times New Roman&#​39;">&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;</​span></​span><​span style="​font-family:​ 宋体">​串口缓冲区数据大小系统变量</​span><​span style="​font-family:​ 黑体, SimHei">:​usize</​span></​span></​p><​p class="​MsoListParagraph"​ style="​margin-left:​ 24px;​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei">​3.<​span style="​font-variant-numeric:​ normal;​font-variant-east-asian:​ normal;​font-stretch:​ normal;​font-size:​ 9px;​line-height:​ normal;​font-family:​ &#​39;​Times New Roman&#​39;">&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;</​span></​span><​span style="​font-family:​ 宋体">​串口缓冲区数据组</​span><​span style="​font-family:​ 黑体, SimHei">:​u[index]</​span></​span></​p><​p class="​MsoListParagraph"​ style="​margin-left:​ 24px;​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei">​4.<​span style="​font-variant-numeric:​ normal;​font-variant-east-asian:​ normal;​font-stretch:​ normal;​font-size:​ 9px;​line-height:​ normal;​font-family:​ &#​39;​Times New Roman&#​39;">&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;</​span></​span><​span style="​font-family:​ 宋体">​串口缓冲区数据拷贝指令</​span><​span style="​font-family:​ 黑体, SimHei">:​ucopy</​span></​span></​p><​p class="​MsoListParagraph"​ style="​margin-left:​ 24px;​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei">​5.<​span style="​font-variant-numeric:​ normal;​font-variant-east-asian:​ normal;​font-stretch:​ normal;​font-size:​ 9px;​line-height:​ normal;​font-family:​ &#​39;​Times New Roman&#​39;">&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;</​span></​span><​span style="​font-family:​ 宋体">​串口数据解析模式退出密码</​span>&​nbsp;</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun"><​span style="​background:​ yellow">​1.串口数据解析模式系统变量recmod(0为被动解析模式,</​span><​strong><​span style="​background:​ yellow">​1</​span></​strong><​strong><​span style="​background:​ yellow">​为主动解析模式</​span></​strong><​span style="​background:​ yellow">​)</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​屏幕上电</​span><​span style="​font-family:​ 黑体, SimHei">​recmod</​span><​span style="​font-family:​ 宋体">​为</​span><​span style="​font-family:​ 黑体, SimHei">​0</​span><​span style="​font-family:​ 宋体">​,即被动解析模式,在此模式下,外部设备按照标准指令集的指令格式发送串口指令给屏幕执行;如果你将</​span><​span style="​font-family:​ 黑体, SimHei">​recmod&​nbsp;</​span><​span style="​font-family:​ 宋体">​设置为</​span><​span style="​font-family:​ 黑体, SimHei">​1(</​span><​span style="​font-family:​ 宋体">​可以在上电默认页的初始化事件中写上</​span><​span style="​font-family:​ 黑体, SimHei">​recmod=1</​span><​span style="​font-family:​ 宋体">​即可</​span><​span style="​font-family:​ 黑体, SimHei">​)</​span><​span style="​font-family:​ 宋体">​,那么屏幕进入主动解析模式,然后所有的串口指令都不会被执行</​span><​span style="​font-family:​ 黑体, SimHei">​(</​span><​span style="​font-family:​ 宋体">​注意:是串口指令不会被执行,上位软件编辑界面时写入事件中的固件指令是不会受影响的,依然正常执行</​span><​span style="​font-family:​ 黑体, SimHei">​)</​span><​span style="​font-family:​ 宋体">​,所有的串口数据均存放在串口缓冲区中,等待您去主动读取。每次读完数据后,使用udelete指令删除缓冲区中已经读取的字节数,</​span><​span style="​font-family:​ 宋体">​否则缓冲区溢出后就无法接收新数据。</​span>&​nbsp;</​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei;​background:​ yellow">​2.</​span><​span style="​font-family:​ 宋体;​background:​ yellow">​串口缓冲区数据大小系统变量</​span><​span style="​font-family:​ 黑体, SimHei;​background:​ yellow">​usize(</​span><​span style="​font-family:​ 宋体;​background:​ yellow">​只能读取,不可设置</​span><​span style="​font-family:​ 黑体, SimHei;​background:​ yellow">​)</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​读取此变量可以知道当前串口缓冲区已经缓存多少数据。</​span>&​nbsp;</​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei;​background:​ yellow">​3.</​span><​span style="​font-family:​ 宋体;​background:​ yellow">​串口缓冲区数据组</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​串口缓冲区数据组的写法为</​span><​span style="​font-family:​ 黑体, SimHei">​u[index]&​nbsp;&​nbsp;​ (index</​span><​span style="​font-family:​ 宋体">​为序号</​span><​span style="​font-family:​ 黑体, SimHei">​)</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​例</​span><​span style="​font-family:​ 黑体, SimHei">​1</​span><​span style="​font-family:​ 宋体">​:从缓冲区中</​span><​span style="​font-family:​ 黑体, SimHei">​0</​span><​span style="​font-family:​ 宋体">​位置开始获取一个</​span><​span style="​font-family:​ 黑体, SimHei">​1</​span><​span style="​font-family:​ 宋体">​字节的数值,赋值给数字控件</​span><​span style="​font-family:​ 黑体, SimHei">​n0,&​nbsp;</​span><​span style="​font-family:​ 宋体">​写法如下</​span><​span style="​font-family:​ 黑体, SimHei">:</​span></​span></​p><​pre class="​brush:​cpp;​toolbar:​false"><​span style="​font-family:​ arial, helvetica, sans-serif">​n0.val=u[0]<​br/></​span></​pre><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​例</​span><​span style="​font-family:​ 黑体, SimHei">​2:&​nbsp;</​span><​span style="​font-family:​ 宋体">​从缓冲区中</​span><​span style="​font-family:​ 黑体, SimHei">​0</​span><​span style="​font-family:​ 宋体">​位置开始获取一个</​span><​span style="​font-family:​ 黑体, SimHei">​2</​span><​span style="​font-family:​ 宋体">​字节的数值</​span><​span style="​font-family:​ 黑体, SimHei">​(</​span><​span style="​font-family:​ 宋体">​小端模式,低位在前</​span><​span style="​font-family:​ 黑体, SimHei">​)</​span><​span style="​font-family:​ 宋体">​,赋值给数字控件</​span><​span style="​font-family:​ 黑体, SimHei">​n0,&​nbsp;</​span><​span style="​font-family:​ 宋体">​写法如下</​span><​span style="​font-family:​ 黑体, SimHei">:</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​br/></​p><​pre class="​brush:​cpp;​toolbar:​false"><​span style="​font-family:​ arial, helvetica, sans-serif">​n0.val=u[1]<​br/>​n0.val&​lt;&​lt;​=8<​br/>​n0.val+=u[0]<​br/></​span></​pre><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​例</​span>​3:&​nbsp;<​span style="​font-family:​ 宋体">​从缓冲区中</​span>​0<​span style="​font-family:​ 宋体">​位置开始获取一个</​span>​4<​span style="​font-family:​ 宋体">​字节的数值</​span>​(<​span style="​font-family:​ 宋体">​小端模式,低位在前</​span>​)<​span style="​font-family:​ 宋体">​,赋值给数字控件</​span>​n0,&​nbsp;<​span style="​font-family:​ 宋体">​写法如下</​span>:</​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​br/></​p><​pre class="​brush:​cpp;​toolbar:​false"><​span style="​font-family:​ arial, helvetica, sans-serif">​n0.val=u[3]<​br/>​n0.val&​lt;&​lt;​=8<​br/>​n0.val+=u[2]<​br/>​n0.val&​lt;&​lt;​=8<​br/>​n0.val+=u[1]<​br/>​n0.val&​lt;&​lt;​=8<​br/>​n0.val+=u[0]<​br/></​span></​pre><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​strong><​span style="​font-family:​ 宋体;​color:​ rgb(242, 242, 242);​background:​ red">​难道对一个</​span></​strong><​strong><​span style="​font-family:​ 黑体, SimHei;​color:​ rgb(242, 242, 242);​background:​ red">​4</​span></​strong><​strong><​span style="​font-family:​ 宋体;​color:​ rgb(242, 242, 242);​background:​ red">​字节的整型变量赋值缓冲区中的内容只能是分</​span></​strong><​strong><​span style="​font-family:​ 黑体, SimHei;​color:​ rgb(242, 242, 242);​background:​ red">​4</​span></​strong><​strong><​span style="​font-family:​ 宋体;​color:​ rgb(242, 242, 242);​background:​ red">​次单字节赋值再加</​span></​strong><​strong><​span style="​font-family:​ 黑体, SimHei;​color:​ rgb(242, 242, 242);​background:​ red">​3</​span></​strong><​strong><​span style="​font-family:​ 宋体;​color:​ rgb(242, 242, 242);​background:​ red">​次移位吗?</​span></​strong><​strong>&​nbsp;</​strong><​strong><​span style="​font-family:​ 宋体;​color:​ rgb(242, 242, 242);​background:​ red">​当然不是!当然有更方便的做法,请继续往下看</​span></​strong><​strong><​span style="​font-family:​ 黑体, SimHei;​color:​ rgb(242, 242, 242);​background:​ red">​!&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;</​span></​strong><​strong><​span style="​font-family:​ 黑体, SimHei;​color:​ rgb(242, 242, 242)">&​nbsp;</​span></​strong></​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei;​background:​ yellow">​4.</​span><​span style="​font-family:​ 宋体;​background:​ yellow">​串口缓冲区数据拷贝指令</​span><​span style="​font-family:​ 黑体, SimHei;​background:​ yellow">​ucopy</​span><​br/></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​格式</​span><​span style="​font-family:​ 黑体, SimHei">:​ ucopy,att, srcstar, lenth, decstar</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​说明:将串口缓冲区中的数据拷贝到变量中</​span><​span style="​font-family:​ 黑体, SimHei">​(recmod=1</​span><​span style="​font-family:​ 宋体">​模式下有效</​span><​span style="​font-family:​ 黑体, SimHei">​)</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei">​att:</​span><​span style="​font-family:​ 宋体">​目标变量名称</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei">​srcstar:</​span><​span style="​font-family:​ 宋体">​串口缓冲区数据起始位</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei">​lenth:</​span><​span style="​font-family:​ 宋体">​拷贝长度</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei">​decstar:</​span><​span style="​font-family:​ 宋体">​目标变量数据起始位</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​此指令可以从串口缓冲区的指定位置连续拷贝指定数量的数据到目标变量</​span><​span style="​font-family:​ 黑体, SimHei">​(</​span><​span style="​font-family:​ 宋体">​目标变量可以是字符串变量,可以是数值变量</​span><​span style="​font-family:​ 黑体, SimHei">​)</​span><​span style="​font-family:​ 宋体">​。</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​例</​span><​span style="​font-family:​ 黑体, SimHei">​1</​span><​span style="​font-family:​ 宋体">​:从缓冲区中</​span><​span style="​font-family:​ 黑体, SimHei">​0</​span><​span style="​font-family:​ 宋体">​位置开始获取一个</​span><​span style="​font-family:​ 黑体, SimHei">​4</​span><​span style="​font-family:​ 宋体">​字节的数值</​span><​span style="​font-family:​ 黑体, SimHei">​(</​span><​span style="​font-family:​ 宋体">​小端模式,低位在前</​span><​span style="​font-family:​ 黑体, SimHei">​)</​span><​span style="​font-family:​ 宋体">​,赋值给数字控件</​span><​span style="​font-family:​ 黑体, SimHei">​n0,&​nbsp;</​span><​span style="​font-family:​ 宋体">​写法如下</​span><​span style="​font-family:​ 黑体, SimHei">:</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​br/></​p><​pre class="​brush:​cpp;​toolbar:​false"><​span style="​font-family:​ arial, helvetica, sans-serif">​ucopy&​nbsp;​n0.val,​0,​4,​0<​br/>​udelete 4&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;//​删除缓冲区中前面4个字节,如果后面还有其他数据,会自动顶上来<​br/></​span></​pre><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体;​color:​ rgb(192, 0, 0)">​温馨提示:每个数值变量系统都是按</​span><​span style="​font-family:​ 黑体, SimHei;​color:​ rgb(192, 0, 0)">​4</​span><​span style="​font-family:​ 宋体;​color:​ rgb(192, 0, 0)">​字节分配内存,假如你使用</​span><​span style="​font-family:​ 黑体, SimHei;​color:​ rgb(192, 0, 0)">​ucopy</​span><​span style="​font-family:​ 宋体;​color:​ rgb(192, 0, 0)">​从缓冲区获取小于</​span><​span style="​font-family:​ 黑体, SimHei;​color:​ rgb(192, 0, 0)">​4</​span><​span style="​font-family:​ 宋体;​color:​ rgb(192, 0, 0)">​字节的数值,一定要注意剩余部分的字节数据处理,以免出现数据异常,操作方法请参考下面这个例子:</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​例</​span><​span style="​font-family:​ 黑体, SimHei">​2:&​nbsp;</​span><​span style="​font-family:​ 宋体">​从缓冲区中</​span><​span style="​font-family:​ 黑体, SimHei">​0</​span><​span style="​font-family:​ 宋体">​位置开始获取一个</​span><​span style="​font-family:​ 黑体, SimHei">​2</​span><​span style="​font-family:​ 宋体">​字节的数值</​span><​span style="​font-family:​ 黑体, SimHei">​(</​span><​span style="​font-family:​ 宋体">​小端模式,低位在前</​span><​span style="​font-family:​ 黑体, SimHei">​)</​span><​span style="​font-family:​ 宋体">​,赋值给数字控件</​span><​span style="​font-family:​ 黑体, SimHei">​n0.val</​span><​span style="​font-family:​ 宋体">​的低</​span><​span style="​font-family:​ 黑体, SimHei">​16</​span><​span style="​font-family:​ 宋体">​位</​span><​span style="​font-family:​ 黑体, SimHei">,&​nbsp;</​span><​span style="​font-family:​ 宋体">​写法如下</​span><​span style="​font-family:​ 黑体, SimHei">:</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​br/></​p><​pre class="​brush:​cpp;​toolbar:​false"><​span style="​font-family:​ arial, helvetica, sans-serif">​n0.val=0<​br/>​ucopy&​nbsp;​n0.val,​0,​2,​0&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;//​如果要赋值给高16位,就写成ucopy&​nbsp;​n0.val,​0,​2,​2<​br/>​udelete 2 &nbsp; &nbsp; &​nbsp;//​删除缓冲区中前面2个字节,如果后面还有其他数据,会自动顶上来<​br/></​span></​pre><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​解释:先将</​span>​n0.val<​span style="​font-family:​ 宋体">​赋值为</​span>​0<​span style="​font-family:​ 宋体">​,目的在于确保</​span>​n0.val<​span style="​font-family:​ 宋体">​的</​span>​4<​span style="​font-family:​ 宋体">​个字节全置</​span>​0<​span style="​font-family:​ 宋体">​,然后再从缓冲区拷贝</​span>​2<​span style="​font-family:​ 宋体">​个字节进来,否则会因为你只拷了</​span>​2<​span style="​font-family:​ 宋体">​字节而导致</​span>​n0.val<​span style="​font-family:​ 宋体">​原来剩下的</​span>​2<​span style="​font-family:​ 宋体">​字节数据还在,然后导致</​span>​n0.val<​span style="​font-family:​ 宋体">​最终的数值并不是你想要的数值。</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​例</​span><​span style="​font-family:​ 黑体, SimHei">​3:&​nbsp;</​span><​span style="​font-family:​ 宋体">​从缓冲区中</​span><​span style="​font-family:​ 黑体, SimHei">​0</​span><​span style="​font-family:​ 宋体">​位置开始获取一个</​span><​span style="​font-family:​ 黑体, SimHei">​10</​span><​span style="​font-family:​ 宋体">​字节的字符串,赋值给文本控件</​span><​span style="​font-family:​ 黑体, SimHei">​t0,&​nbsp;</​span><​span style="​font-family:​ 宋体">​写法如下</​span><​span style="​font-family:​ 黑体, SimHei">:</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​br/></​p><​pre class="​brush:​cpp;​toolbar:​false"><​span style="​font-family:​ arial, helvetica, sans-serif">​if(usize&​gt;​=10)&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;//​确保缓冲区数据大小足够10个<​br/>​{<​br/>​ucopy&​nbsp;​t0.txt,​0,​10,​0<​br/>​udelete 10 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &​nbsp;//​删除缓冲区中前面10个字节,如果后面还有其他数据,会自动顶上来<​br/>​}<​br/></​span></​pre><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​strong><​span style="​font-family:​ 宋体">​重要提示:</​span></​strong><​strong>​code_c</​strong><​strong><​span style="​font-family:​ 宋体">​指令会将缓冲区数据清空,有可能会导致还没有读取的数据就被提前删除,所以在主动解析模式下建议使用udelete指令来删除已经读取的内容,而不要使用code_c指令</​span></​strong><​strong><​span style="​font-family:​ 宋体">​。</​span></​strong><​strong>&​nbsp;</​strong></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​strong><​span style="​font-family:​ 宋体;​color:​ white;​background:​ red">​以上案例中使用的所有语句,指令,都是在上位编辑界面下,写入事件中的固件指令,串口一旦配置为主动解析模式,就不能再执行串口指令了,所以必须是由固件指令来操作读取串口数据,而不能是通过串口指令操作</​span></​strong><​strong><​span style="​font-family:​ 黑体, SimHei;​color:​ white;​background:​ red">​(</​span></​strong><​strong><​span style="​font-family:​ 宋体;​color:​ white;​background:​ red">​否则就自相矛盾了</​span></​strong><​strong><​span style="​font-family:​ 黑体, SimHei;​color:​ white;​background:​ red">​)</​span></​strong><​strong><​span style="​font-family:​ 宋体;​color:​ white;​background:​ red">​。</​span></​strong>&​nbsp;</​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei;​background:​ yellow">​5.</​span><​span style="​font-family:​ 宋体;​background:​ yellow">​退出主动解析模式</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​常规的退出主动解析模式方法是在事件中写入</​span><​span style="​font-family:​ 黑体, SimHei">​recmod=0</​span><​span style="​font-family:​ 宋体">​的固件指令,如果想通过串口数据来退出,串口发送</​span><​span style="​font-family:​ 黑体, SimHei">​recmod=0</​span><​span style="​font-family:​ 宋体">​是肯定没有用的,可以通过发送一串退出密码来实现退出主动解析模式</​span><​span style="​font-family:​ 黑体, SimHei">,</​span><​span style="​font-family:​ 宋体">​退出密码为一串</​span><​span style="​font-family:​ 黑体, SimHei">​24</​span><​span style="​font-family:​ 宋体">​字节的字符串</​span><​span style="​font-family:​ 黑体, SimHei">​+3</​span><​span style="​font-family:​ 宋体">​字节的结束符。</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​24字节的字符串:</​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​DRAKJHSUYDGBNCJHGJKSHBDN &​nbsp;​(字符串数据,必须大写)</​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun"><​span style="​font-family:​ 黑体, SimHei">​3</​span><​span style="​font-family:​ 宋体">​字节的结束符(</​span></​span><​span style="​font-family:​ 黑体, SimHei">​Hex</​span><​span style="​font-family:​ 宋体">​数据</​span><​span style="​font-family:​ 黑体, SimHei">​)</​span><​span style="​font-family:​ 宋体">​:</​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ 黑体, SimHei">​0xff 0xff 0xff&​nbsp;​ &nbsp; &nbsp; &​nbsp;&​nbsp;</​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun"><​span style="​font-family:​ 宋体;​background:​ lime">​合计</​span><​span style="​font-family:​ 黑体, SimHei;​background:​ lime">​27</​span><​span style="​font-family:​ 宋体;​background:​ lime">​字节</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​background:​ lime;​font-family:​ arial, helvetica, sans-serif"><​br/></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​background:​ lime;​font-family:​ arial, helvetica, sans-serif"><​br/></​span></​p><​table width="​100%"><​tbody><​tr class="​firstRow"><​td style="​background-color:​ rgb(146, 208, 80)"><​p style="​text-align:​ center"><​span style="​font-family:​ arial, helvetica, sans-serif"><​strong><​span style="​font-size:​ 19px;​font-family:​ 宋体"><​a name="​b2"></​a></​span></​strong><​span style="​font-family:​ 黑体, SimHei"><​strong><​span style="​font-family:​ 宋体">​二</​span></​strong><​strong>​.HMI</​strong><​strong><​span style="​font-family:​ 宋体">​下载协议详解</​span></​strong></​span></​span></​p></​td></​tr></​tbody></​table><​table width="​100%"><​tbody><​tr class="​firstRow"><​td style="​background-color:​ rgb(238, 236, 225)"><​p style="​text-indent:​ 28px;​line-height:​ 33px"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​本文讲述的</​span><​span style="​font-family:​ 黑体, SimHei">​HMI</​span><​span style="​font-family:​ 宋体">​下载协议仅适用于希望自己制作<​strong><​span style="​font-family:​ 黑体, SimHei;​color:​ red">​下载程序</​span></​strong>​或者希望单片机去控制</​span><​span style="​font-family:​ 黑体, SimHei;​color:​ red">​HMI</​span><​strong><​span style="​font-family:​ 宋体;​color:​ red">​下载资源文件</​span></​strong><​span style="​font-family:​ 宋体">​的用户,属于<​strong><​span style="​font-family:​ 黑体, SimHei;​color:​ red">​高级应用</​span></​strong>​范畴,不属于</​span><​span style="​font-family:​ 黑体, SimHei">​HMI</​span><​span style="​font-family:​ 宋体">​界面设计的范畴,因此需要有一定基础的用户才能操作。深圳市淘晶驰电子有限公司仅仅只对此协议做一个公布说明,不提供任何跟下载协议有关的技术支持,如果对串口操作不熟悉的朋友建议忽略此说明,请直接使用</​span><​span style="​font-family:​ 黑体, SimHei">​USART HMI</​span><​span style="​font-family:​ 宋体">​软件进行下载即可,无需对此协议有任何了解。</​span>&​nbsp;</​span></​p></​td></​tr></​tbody></​table><​p style="​white-space:​ normal"><​span style="​font-size:​ 18px"><​strong><​span style="​font-family:​ 宋体, SimSun;​color:​ rgb(192, 0, 0)">​温馨提示:官方有按照本协议开发好的专用下载工具(TFTFileDownload),并且开放源代码,欢迎下载使用:</​span></​strong><​strong><​span style="​font-family:​ 宋体, SimSun"><​a href="​http://​wiki.tjc1688.com/​doku.php?​id=2.%E4%B8%8A%E4%BD%8D%E8%BD%AF%E4%BB%B6%E4%B8%8B%E8%BD%BD:​4.%E5%B8%B8%E7%94%A8%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7"​ target="​_self"​ style="​font-size:​ 20px">​点击此处下载</​a></​span></​strong></​span></​p><​p style="​white-space:​ normal"><​strong><​span style="​font-family:​ 宋体, SimSun">​【下载步骤1:联机操作】</​span></​strong></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​此步骤主要用来搜索HMI设备在哪个串口上,以及设备当前的波特率。如果这两个条件是已知的,那么可以不用做这个步骤,在你的程序中直接固定串口号和设备当前使用的波特率后直接跳到步骤2开始下载。</​span></​p><​p style="​white-space:​ normal"><​span style="​color:​ rgb(192, 80, 77)"><​strong><​span style="​font-family:​ 宋体, SimSun">​●搜索方法:</​span></​strong></​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​分别向电脑的每个串口分别用不同波特率发送一个联机指令:​connect+结束符</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​设备收到联机指令后会返回联机数据,如果收到正确的联机数据,说明设备联机成功,至此,得到当前设备的串口号和当前使用的波特率.</​span></​p><​p style="​white-space:​ normal"><​span style="​color:​ rgb(192, 80, 77)"><​strong><​span style="​font-family:​ 宋体, SimSun">​●联机指令发送说明:</​span></​strong></​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​因为一直在循环发送指令,所以当屏幕在正确的波特率上收到数据时,数据的最前面肯定会有部分上一次错误的波特率下的错误数据,因此这个时候第一条指令肯定是会被当成错误指令的。所以每次发送的时候需要发两条指令,第一条发4个字节的HEX空指令(00 ff ff ff),​第二条才是connect+结束符</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​延时说明:​每次尝试一次联机指令后需要等待数据返回的最短时间为(单位:​ms):​ (1000000/​尝试的波特率)+30</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​假如在9600波特率下尝试联机,需要等待返回的最短时间为:</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​1000000/​9600+30=134ms</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​其他波特率以此类推</​span></​p><​p style="​white-space:​ normal"><​span style="​color:​ rgb(192, 80, 77)"><​strong><​span style="​font-family:​ 宋体, SimSun">​●数据解释:</​span></​strong></​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​以TJC4024T032_011R设备为例,设备返回如下8组数据(每组数据逗号隔开):</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​comok 1,​101,​TJC4024T032_011R,​52,​61488,​D264B8204F0E1828,​16777216</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​comok:​握手回应</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​1:​表示带触摸(0是不带触摸)</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​101:​设备内部预留数据</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​TJC4024T032_011R:​设备型号</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​52:​设备固件版本号</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​61488:​设备主控芯片内部编码</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​D264B8204F0E1828:​设备唯一序列号</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​16777216:​设备FLASH大小(单位:字节)</​span></​p><​p style="​white-space:​ normal"><​strong><​span style="​font-family:​ 宋体, SimSun">​【下载步骤2:开始下载】</​span></​strong></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​此时已经知道设备在哪个串口号上,也知道设备当前的波特率了,可以发送下载指令了。</​span></​p><​p style="​white-space:​ normal"><​span style="​color:​ rgb(192, 80, 77)"><​strong><​span style="​font-family:​ 宋体, SimSun">​■第一步:发送指令whmi-wri filesize,​baud,​res0</​span></​strong></​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​filesize:​tft文件的大小(单位:字节)</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​baud:​强制下载使用的波特率</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​res0:​预留数据,使用任意ASCII字符即可</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​假如需要下载的tft文件大小为10000字节,​需要使用115200波特率下载,那么就发送指令:</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​whmi-wri 10000,​115200,​0</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​发送完此指令以后,需要修改电脑的波特率为刚才设置的强制波特率(如果当前波特率和强制下载波特率不一致的话)</​span></​p><​p style="​white-space:​ normal"><​span style="​color:​ rgb(192, 80, 77)"><​strong><​span style="​font-family:​ 宋体, SimSun">​■第二步:下发tft文件的二进制数据</​span></​strong></​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​设备收到whmi-wri指令后在250ms左右后会返回一个0x05的数据(仅仅是一个字节,没有3个0XFF的结束符,波特率为刚才设置的强制下载波特率),​收到此数据后,可以开始下发tft文件的二进制数据,下发格式为每包下发4096字节,最后一包剩余多少就发多少,每包发送完成以后,需要等待屏幕返回响应信号,响应信号依然为一个单一字节的0x05。&​nbsp;</​span></​p><​p><​span style="​font-family:​ 宋体, SimSun"><​br/></​span></​p><​table width="​100%"><​tbody><​tr class="​firstRow"><​td valign="​middle"​ style="​background-color:​ rgb(146, 208, 80)"><​p><​strong><​a name="​comcrc"></​a>​三.串口指令增加CRC校验<​span style="​color:​ rgb(255, 0, 0);">​(0.56及其以上上位机版本支持)</​span></​strong></​p></​td></​tr></​tbody></​table><​table width="​100%"><​tbody><​tr class="​firstRow"><​td style="​background-color:​ rgb(238, 236, 225)"><​p style="​text-indent:​ 28px;​line-height:​ 33px"><​span style="​font-family:​ 宋体">​正常情况下,指令直接发送即可,不需要校验,如果您的项目对指令传输要求很严格必须开启校验请按照下列说明发送指令</​span></​p></​td></​tr></​tbody></​table><​p style="​white-space:​ normal"><​span style="​color:​ rgb(192, 0, 0)">​切记注意:上位软件版本0.56开始才支持指令CRC,之前的版本是不支持的。</​span></​p><​p style="​white-space:​ normal">​带校验或不带校验无需做任何配置,只需修改指令即可,您可以上一条指令带校验,下一条指令不带校验也是可以的。两种指令的区别如下:</​p><​p style="​white-space:​ normal"><​strong>​1.变更结束符</​strong></​p><​p style="​white-space:​ normal">&​nbsp;​ &​nbsp;​普通指令结束符为0xff 0xff 0xff,​带校验的指令结束符为0xfe 0xfe 0xfe。</​p><​p style="​white-space:​ normal"><​strong>​2.CRC16校验算法<​strong style="​white-space:​ normal; background-color:​ rgb(146, 208, 80);"><​a name="​crc16"></​a></​strong></​strong></​p><​p style="​white-space:​ normal">&​nbsp;​ &​nbsp;​指令CRC16校验算法使用MODBUS的CRC16校验算法,​计算函数如下:</​p><​p style="​white-space:​ normal">&​nbsp;​ &​nbsp;​需要校验的数据为所有指令数据,如果是带地址的指令,从地址开始算,不带地址的指令,就从指令第一个字节开始计算,结束符不计算在内。</​p><​pre class="​brush:​cpp;​toolbar:​false">​static&​nbsp;​U8&​nbsp;​InvertUint8(U8&​nbsp;​data)+<h1 style="​white-space:​ normal;​font-size:​ 32px;​border-bottom:​ 2px solid rgb(204, 204, 204);​padding:​ 0px 4px 0px 0px;​text-align:​ center;​margin:​ 0px 0px 20px"><​span style="​font-family:​ arial, helvetica, sans-serif;​font-size:​ 24px"><​strong>​HMI</​strong><​strong>​高级应用与特殊指令详解</​strong></​span></​h1><​p style="​white-space:​ normal"><​span style="​font-size:​ 18px;​font-family:​ arial, helvetica, sans-serif">&​nbsp;<​strong>​本文档主要讲述一些高级应用,实现一些特殊功能,大多数项目是用不上这些功能的,如果您的项目用不上,可以忽略此文档。</​strong></​span></​p><​p style="​white-space:​ normal"><​span style="​background-color:​ rgb(242, 242, 242);​font-size:​ 32px;color: rgb(192, 80, 77);​font-family:​ arial, helvetica, sans-serif"><​br/></​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​strong>​【章节索引】</​strong></​span></​p><​p style="​white-space:​ normal"><​a href="#​b1"​ target="​_self">​一.串口数据解析模式篇之主动解析模式应用详解</​a></​p><​p style="​white-space:​ normal"><​a href="#​b2"​ target="​_self">​二.HMI下载协议详解</​a></​p><​p style="​white-space:​ normal"><​a href="#​comcrc"​ target="​_self">​三.串口指令增加CRC校验</​a></​p><​p style="​white-space:​ normal"><​a href="#​mcrc" target="​_self">​四.程序中使用CRC校验数据</​a></​p><​p style="​white-space:​ normal"><​a href="#​comfile"​ target="​_self">​五.运行中串口传输图片到内存或SD卡</​a></​p><​p style="​white-space:​ normal"><​br/></​p><​table width="​100%"><​tbody><​tr class="​firstRow"><​td style="​background-color:​ rgb(146, 208, 80)"><​p style="​text-align:​ center"><​span style="​font-family:​ arial, helvetica, sans-serif"><​strong><​span style="​font-size:​ 19px;​font-family:​ 宋体"><​a name="​b1"></​a></​span></​strong><​strong>​一.串口数据解析模式篇之主动解析模式应用详解</​strong></​span></​p></​td></​tr></​tbody></​table><​table width="​100%"><​tbody><​tr class="​firstRow"><​td style="​background-color:​ rgb(238, 236, 225)"><​p><​span style="​font-family:​ 宋体, SimSun">​屏幕上电默认是被动解析模式,所有串口指令需按照指令集中的格式来对屏幕进行操作,假如你需要自定义协议,不按照指令集格式来发串口数据给屏幕,而使用你自定义的格式,那么就需要把屏幕配置为主动解析模式。要使用此功能,请务必确保你有以下2点基础:</​span></​p><​p><​span style="​font-family:​ 宋体, SimSun">​1.明白什么叫HEX,​什么叫String,​什么叫ASCII,​分别什么关系,怎么转换。&​nbsp;​ &nbsp; &​nbsp;</​span></​p><​p><​span style="​font-family:​ 宋体, SimSun">​2.明白单字节数值,双字节数值,四字节数值,分别有什么区别,它们在内存中是什么样的储存方式,明白什么叫小端模式,什么叫大端模式。明白低位在前是什么含义。&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​ &​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;</​span></​p><​p><​span style="​font-family:​ 宋体, SimSun">​如果以上2点你都比较明白,那么请继续往下看,否则强烈建议不要再继续往下看了,因为大多数的项目是用不上这个功能的,使用默认的被动解析模式就可以了,没必要配置为下面的主动解析模式。</​span></​p></​td></​tr></​tbody></​table><​p style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​此篇幅涉及到以下几个内容</​span>:</​span></​p><​p class="​MsoListParagraph"​ style="​margin-left:​ 24px;​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei">​1.<​span style="​font-variant-numeric:​ normal;​font-variant-east-asian:​ normal;​font-stretch:​ normal;​font-size:​ 9px;​line-height:​ normal;​font-family:​ &#​39;​Times New Roman&#​39;">&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;</​span></​span><​span style="​font-family:​ 宋体">​串口数据解析模式系统变量</​span><​span style="​font-family:​ 黑体, SimHei">:​recmod</​span></​span></​p><​p class="​MsoListParagraph"​ style="​margin-left:​ 24px;​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei">​2.<​span style="​font-variant-numeric:​ normal;​font-variant-east-asian:​ normal;​font-stretch:​ normal;​font-size:​ 9px;​line-height:​ normal;​font-family:​ &#​39;​Times New Roman&#​39;">&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;</​span></​span><​span style="​font-family:​ 宋体">​串口缓冲区数据大小系统变量</​span><​span style="​font-family:​ 黑体, SimHei">:​usize</​span></​span></​p><​p class="​MsoListParagraph"​ style="​margin-left:​ 24px;​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei">​3.<​span style="​font-variant-numeric:​ normal;​font-variant-east-asian:​ normal;​font-stretch:​ normal;​font-size:​ 9px;​line-height:​ normal;​font-family:​ &#​39;​Times New Roman&#​39;">&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;</​span></​span><​span style="​font-family:​ 宋体">​串口缓冲区数据组</​span><​span style="​font-family:​ 黑体, SimHei">:​u[index]</​span></​span></​p><​p class="​MsoListParagraph"​ style="​margin-left:​ 24px;​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei">​4.<​span style="​font-variant-numeric:​ normal;​font-variant-east-asian:​ normal;​font-stretch:​ normal;​font-size:​ 9px;​line-height:​ normal;​font-family:​ &#​39;​Times New Roman&#​39;">&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;</​span></​span><​span style="​font-family:​ 宋体">​串口缓冲区数据拷贝指令</​span><​span style="​font-family:​ 黑体, SimHei">:​ucopy</​span></​span></​p><​p class="​MsoListParagraph"​ style="​margin-left:​ 24px;​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei">​5.<​span style="​font-variant-numeric:​ normal;​font-variant-east-asian:​ normal;​font-stretch:​ normal;​font-size:​ 9px;​line-height:​ normal;​font-family:​ &#​39;​Times New Roman&#​39;">&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;</​span></​span><​span style="​font-family:​ 宋体">​串口数据解析模式退出密码</​span>&​nbsp;</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun"><​span style="​background:​ yellow">​1.串口数据解析模式系统变量recmod(0为被动解析模式,</​span><​strong><​span style="​background:​ yellow">​1</​span></​strong><​strong><​span style="​background:​ yellow">​为主动解析模式</​span></​strong><​span style="​background:​ yellow">​)</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​屏幕上电</​span><​span style="​font-family:​ 黑体, SimHei">​recmod</​span><​span style="​font-family:​ 宋体">​为</​span><​span style="​font-family:​ 黑体, SimHei">​0</​span><​span style="​font-family:​ 宋体">​,即被动解析模式,在此模式下,外部设备按照标准指令集的指令格式发送串口指令给屏幕执行;如果你将</​span><​span style="​font-family:​ 黑体, SimHei">​recmod&​nbsp;</​span><​span style="​font-family:​ 宋体">​设置为</​span><​span style="​font-family:​ 黑体, SimHei">​1(</​span><​span style="​font-family:​ 宋体">​可以在上电默认页的初始化事件中写上</​span><​span style="​font-family:​ 黑体, SimHei">​recmod=1</​span><​span style="​font-family:​ 宋体">​即可</​span><​span style="​font-family:​ 黑体, SimHei">​)</​span><​span style="​font-family:​ 宋体">​,那么屏幕进入主动解析模式,然后所有的串口指令都不会被执行</​span><​span style="​font-family:​ 黑体, SimHei">​(</​span><​span style="​font-family:​ 宋体">​注意:是串口指令不会被执行,上位软件编辑界面时写入事件中的固件指令是不会受影响的,依然正常执行</​span><​span style="​font-family:​ 黑体, SimHei">​)</​span><​span style="​font-family:​ 宋体">​,所有的串口数据均存放在串口缓冲区中,等待您去主动读取。每次读完数据后,使用udelete指令删除缓冲区中已经读取的字节数,</​span><​span style="​font-family:​ 宋体">​否则缓冲区溢出后就无法接收新数据。</​span>&​nbsp;</​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei;​background:​ yellow">​2.</​span><​span style="​font-family:​ 宋体;​background:​ yellow">​串口缓冲区数据大小系统变量</​span><​span style="​font-family:​ 黑体, SimHei;​background:​ yellow">​usize(</​span><​span style="​font-family:​ 宋体;​background:​ yellow">​只能读取,不可设置</​span><​span style="​font-family:​ 黑体, SimHei;​background:​ yellow">​)</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​读取此变量可以知道当前串口缓冲区已经缓存多少数据。</​span>&​nbsp;</​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei;​background:​ yellow">​3.</​span><​span style="​font-family:​ 宋体;​background:​ yellow">​串口缓冲区数据组</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​串口缓冲区数据组的写法为</​span><​span style="​font-family:​ 黑体, SimHei">​u[index]&​nbsp;&​nbsp;​ (index</​span><​span style="​font-family:​ 宋体">​为序号</​span><​span style="​font-family:​ 黑体, SimHei">​)</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​例</​span><​span style="​font-family:​ 黑体, SimHei">​1</​span><​span style="​font-family:​ 宋体">​:从缓冲区中</​span><​span style="​font-family:​ 黑体, SimHei">​0</​span><​span style="​font-family:​ 宋体">​位置开始获取一个</​span><​span style="​font-family:​ 黑体, SimHei">​1</​span><​span style="​font-family:​ 宋体">​字节的数值,赋值给数字控件</​span><​span style="​font-family:​ 黑体, SimHei">​n0,&​nbsp;</​span><​span style="​font-family:​ 宋体">​写法如下</​span><​span style="​font-family:​ 黑体, SimHei">:</​span></​span></​p><​pre class="​brush:​cpp;​toolbar:​false"><​span style="​font-family:​ arial, helvetica, sans-serif">​n0.val=u[0]<​br/></​span></​pre><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​例</​span><​span style="​font-family:​ 黑体, SimHei">​2:&​nbsp;</​span><​span style="​font-family:​ 宋体">​从缓冲区中</​span><​span style="​font-family:​ 黑体, SimHei">​0</​span><​span style="​font-family:​ 宋体">​位置开始获取一个</​span><​span style="​font-family:​ 黑体, SimHei">​2</​span><​span style="​font-family:​ 宋体">​字节的数值</​span><​span style="​font-family:​ 黑体, SimHei">​(</​span><​span style="​font-family:​ 宋体">​小端模式,低位在前</​span><​span style="​font-family:​ 黑体, SimHei">​)</​span><​span style="​font-family:​ 宋体">​,赋值给数字控件</​span><​span style="​font-family:​ 黑体, SimHei">​n0,&​nbsp;</​span><​span style="​font-family:​ 宋体">​写法如下</​span><​span style="​font-family:​ 黑体, SimHei">:</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​br/></​p><​pre class="​brush:​cpp;​toolbar:​false"><​span style="​font-family:​ arial, helvetica, sans-serif">​n0.val=u[1]<​br/>​n0.val&​lt;&​lt;​=8<​br/>​n0.val+=u[0]<​br/></​span></​pre><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​例</​span>​3:&​nbsp;<​span style="​font-family:​ 宋体">​从缓冲区中</​span>​0<​span style="​font-family:​ 宋体">​位置开始获取一个</​span>​4<​span style="​font-family:​ 宋体">​字节的数值</​span>​(<​span style="​font-family:​ 宋体">​小端模式,低位在前</​span>​)<​span style="​font-family:​ 宋体">​,赋值给数字控件</​span>​n0,&​nbsp;<​span style="​font-family:​ 宋体">​写法如下</​span>:</​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​br/></​p><​pre class="​brush:​cpp;​toolbar:​false"><​span style="​font-family:​ arial, helvetica, sans-serif">​n0.val=u[3]<​br/>​n0.val&​lt;&​lt;​=8<​br/>​n0.val+=u[2]<​br/>​n0.val&​lt;&​lt;​=8<​br/>​n0.val+=u[1]<​br/>​n0.val&​lt;&​lt;​=8<​br/>​n0.val+=u[0]<​br/></​span></​pre><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​strong><​span style="​font-family:​ 宋体;​color:​ rgb(242, 242, 242);​background:​ red">​难道对一个</​span></​strong><​strong><​span style="​font-family:​ 黑体, SimHei;​color:​ rgb(242, 242, 242);​background:​ red">​4</​span></​strong><​strong><​span style="​font-family:​ 宋体;​color:​ rgb(242, 242, 242);​background:​ red">​字节的整型变量赋值缓冲区中的内容只能是分</​span></​strong><​strong><​span style="​font-family:​ 黑体, SimHei;​color:​ rgb(242, 242, 242);​background:​ red">​4</​span></​strong><​strong><​span style="​font-family:​ 宋体;​color:​ rgb(242, 242, 242);​background:​ red">​次单字节赋值再加</​span></​strong><​strong><​span style="​font-family:​ 黑体, SimHei;​color:​ rgb(242, 242, 242);​background:​ red">​3</​span></​strong><​strong><​span style="​font-family:​ 宋体;​color:​ rgb(242, 242, 242);​background:​ red">​次移位吗?</​span></​strong><​strong>&​nbsp;</​strong><​strong><​span style="​font-family:​ 宋体;​color:​ rgb(242, 242, 242);​background:​ red">​当然不是!当然有更方便的做法,请继续往下看</​span></​strong><​strong><​span style="​font-family:​ 黑体, SimHei;​color:​ rgb(242, 242, 242);​background:​ red">​!&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;</​span></​strong><​strong><​span style="​font-family:​ 黑体, SimHei;​color:​ rgb(242, 242, 242)">&​nbsp;</​span></​strong></​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei;​background:​ yellow">​4.</​span><​span style="​font-family:​ 宋体;​background:​ yellow">​串口缓冲区数据拷贝指令</​span><​span style="​font-family:​ 黑体, SimHei;​background:​ yellow">​ucopy</​span><​br/></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​格式</​span><​span style="​font-family:​ 黑体, SimHei">:​ ucopy,att, srcstar, lenth, decstar</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​说明:将串口缓冲区中的数据拷贝到变量中</​span><​span style="​font-family:​ 黑体, SimHei">​(recmod=1</​span><​span style="​font-family:​ 宋体">​模式下有效</​span><​span style="​font-family:​ 黑体, SimHei">​)</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei">​att:</​span><​span style="​font-family:​ 宋体">​目标变量名称</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei">​srcstar:</​span><​span style="​font-family:​ 宋体">​串口缓冲区数据起始位</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei">​lenth:</​span><​span style="​font-family:​ 宋体">​拷贝长度</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei">​decstar:</​span><​span style="​font-family:​ 宋体">​目标变量数据起始位</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​此指令可以从串口缓冲区的指定位置连续拷贝指定数量的数据到目标变量</​span><​span style="​font-family:​ 黑体, SimHei">​(</​span><​span style="​font-family:​ 宋体">​目标变量可以是字符串变量,可以是数值变量</​span><​span style="​font-family:​ 黑体, SimHei">​)</​span><​span style="​font-family:​ 宋体">​。</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​例</​span><​span style="​font-family:​ 黑体, SimHei">​1</​span><​span style="​font-family:​ 宋体">​:从缓冲区中</​span><​span style="​font-family:​ 黑体, SimHei">​0</​span><​span style="​font-family:​ 宋体">​位置开始获取一个</​span><​span style="​font-family:​ 黑体, SimHei">​4</​span><​span style="​font-family:​ 宋体">​字节的数值</​span><​span style="​font-family:​ 黑体, SimHei">​(</​span><​span style="​font-family:​ 宋体">​小端模式,低位在前</​span><​span style="​font-family:​ 黑体, SimHei">​)</​span><​span style="​font-family:​ 宋体">​,赋值给数字控件</​span><​span style="​font-family:​ 黑体, SimHei">​n0,&​nbsp;</​span><​span style="​font-family:​ 宋体">​写法如下</​span><​span style="​font-family:​ 黑体, SimHei">:</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​br/></​p><​pre class="​brush:​cpp;​toolbar:​false"><​span style="​font-family:​ arial, helvetica, sans-serif">​ucopy&​nbsp;​n0.val,​0,​4,​0<​br/>​udelete 4&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;//​删除缓冲区中前面4个字节,如果后面还有其他数据,会自动顶上来<​br/></​span></​pre><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体;​color:​ rgb(192, 0, 0)">​温馨提示:每个数值变量系统都是按</​span><​span style="​font-family:​ 黑体, SimHei;​color:​ rgb(192, 0, 0)">​4</​span><​span style="​font-family:​ 宋体;​color:​ rgb(192, 0, 0)">​字节分配内存,假如你使用</​span><​span style="​font-family:​ 黑体, SimHei;​color:​ rgb(192, 0, 0)">​ucopy</​span><​span style="​font-family:​ 宋体;​color:​ rgb(192, 0, 0)">​从缓冲区获取小于</​span><​span style="​font-family:​ 黑体, SimHei;​color:​ rgb(192, 0, 0)">​4</​span><​span style="​font-family:​ 宋体;​color:​ rgb(192, 0, 0)">​字节的数值,一定要注意剩余部分的字节数据处理,以免出现数据异常,操作方法请参考下面这个例子:</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​例</​span><​span style="​font-family:​ 黑体, SimHei">​2:&​nbsp;</​span><​span style="​font-family:​ 宋体">​从缓冲区中</​span><​span style="​font-family:​ 黑体, SimHei">​0</​span><​span style="​font-family:​ 宋体">​位置开始获取一个</​span><​span style="​font-family:​ 黑体, SimHei">​2</​span><​span style="​font-family:​ 宋体">​字节的数值</​span><​span style="​font-family:​ 黑体, SimHei">​(</​span><​span style="​font-family:​ 宋体">​小端模式,低位在前</​span><​span style="​font-family:​ 黑体, SimHei">​)</​span><​span style="​font-family:​ 宋体">​,赋值给数字控件</​span><​span style="​font-family:​ 黑体, SimHei">​n0.val</​span><​span style="​font-family:​ 宋体">​的低</​span><​span style="​font-family:​ 黑体, SimHei">​16</​span><​span style="​font-family:​ 宋体">​位</​span><​span style="​font-family:​ 黑体, SimHei">,&​nbsp;</​span><​span style="​font-family:​ 宋体">​写法如下</​span><​span style="​font-family:​ 黑体, SimHei">:</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​br/></​p><​pre class="​brush:​cpp;​toolbar:​false"><​span style="​font-family:​ arial, helvetica, sans-serif">​n0.val=0<​br/>​ucopy&​nbsp;​n0.val,​0,​2,​0&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;//​如果要赋值给高16位,就写成ucopy&​nbsp;​n0.val,​0,​2,​2<​br/>​udelete 2 &nbsp; &nbsp; &​nbsp;//​删除缓冲区中前面2个字节,如果后面还有其他数据,会自动顶上来<​br/></​span></​pre><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​解释:先将</​span>​n0.val<​span style="​font-family:​ 宋体">​赋值为</​span>​0<​span style="​font-family:​ 宋体">​,目的在于确保</​span>​n0.val<​span style="​font-family:​ 宋体">​的</​span>​4<​span style="​font-family:​ 宋体">​个字节全置</​span>​0<​span style="​font-family:​ 宋体">​,然后再从缓冲区拷贝</​span>​2<​span style="​font-family:​ 宋体">​个字节进来,否则会因为你只拷了</​span>​2<​span style="​font-family:​ 宋体">​字节而导致</​span>​n0.val<​span style="​font-family:​ 宋体">​原来剩下的</​span>​2<​span style="​font-family:​ 宋体">​字节数据还在,然后导致</​span>​n0.val<​span style="​font-family:​ 宋体">​最终的数值并不是你想要的数值。</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​例</​span><​span style="​font-family:​ 黑体, SimHei">​3:&​nbsp;</​span><​span style="​font-family:​ 宋体">​从缓冲区中</​span><​span style="​font-family:​ 黑体, SimHei">​0</​span><​span style="​font-family:​ 宋体">​位置开始获取一个</​span><​span style="​font-family:​ 黑体, SimHei">​10</​span><​span style="​font-family:​ 宋体">​字节的字符串,赋值给文本控件</​span><​span style="​font-family:​ 黑体, SimHei">​t0,&​nbsp;</​span><​span style="​font-family:​ 宋体">​写法如下</​span><​span style="​font-family:​ 黑体, SimHei">:</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​br/></​p><​pre class="​brush:​cpp;​toolbar:​false"><​span style="​font-family:​ arial, helvetica, sans-serif">​if(usize&​gt;​=10)&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;//​确保缓冲区数据大小足够10个<​br/>​{<​br/>​ucopy&​nbsp;​t0.txt,​0,​10,​0<​br/>​udelete 10 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &​nbsp;//​删除缓冲区中前面10个字节,如果后面还有其他数据,会自动顶上来<​br/>​}<​br/></​span></​pre><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​strong><​span style="​font-family:​ 宋体">​重要提示:</​span></​strong><​strong>​code_c</​strong><​strong><​span style="​font-family:​ 宋体">​指令会将缓冲区数据清空,有可能会导致还没有读取的数据就被提前删除,所以在主动解析模式下建议使用udelete指令来删除已经读取的内容,而不要使用code_c指令</​span></​strong><​strong><​span style="​font-family:​ 宋体">​。</​span></​strong><​strong>&​nbsp;</​strong></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​strong><​span style="​font-family:​ 宋体;​color:​ white;​background:​ red">​以上案例中使用的所有语句,指令,都是在上位编辑界面下,写入事件中的固件指令,串口一旦配置为主动解析模式,就不能再执行串口指令了,所以必须是由固件指令来操作读取串口数据,而不能是通过串口指令操作</​span></​strong><​strong><​span style="​font-family:​ 黑体, SimHei;​color:​ white;​background:​ red">​(</​span></​strong><​strong><​span style="​font-family:​ 宋体;​color:​ white;​background:​ red">​否则就自相矛盾了</​span></​strong><​strong><​span style="​font-family:​ 黑体, SimHei;​color:​ white;​background:​ red">​)</​span></​strong><​strong><​span style="​font-family:​ 宋体;​color:​ white;​background:​ red">​。</​span></​strong>&​nbsp;</​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 黑体, SimHei;​background:​ yellow">​5.</​span><​span style="​font-family:​ 宋体;​background:​ yellow">​退出主动解析模式</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​常规的退出主动解析模式方法是在事件中写入</​span><​span style="​font-family:​ 黑体, SimHei">​recmod=0</​span><​span style="​font-family:​ 宋体">​的固件指令,如果想通过串口数据来退出,串口发送</​span><​span style="​font-family:​ 黑体, SimHei">​recmod=0</​span><​span style="​font-family:​ 宋体">​是肯定没有用的,可以通过发送一串退出密码来实现退出主动解析模式</​span><​span style="​font-family:​ 黑体, SimHei">,</​span><​span style="​font-family:​ 宋体">​退出密码为一串</​span><​span style="​font-family:​ 黑体, SimHei">​24</​span><​span style="​font-family:​ 宋体">​字节的字符串</​span><​span style="​font-family:​ 黑体, SimHei">​+3</​span><​span style="​font-family:​ 宋体">​字节的结束符。</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​24字节的字符串:</​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​DRAKJHSUYDGBNCJHGJKSHBDN &​nbsp;​(字符串数据,必须大写)</​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun"><​span style="​font-family:​ 黑体, SimHei">​3</​span><​span style="​font-family:​ 宋体">​字节的结束符(</​span></​span><​span style="​font-family:​ 黑体, SimHei">​Hex</​span><​span style="​font-family:​ 宋体">​数据</​span><​span style="​font-family:​ 黑体, SimHei">​)</​span><​span style="​font-family:​ 宋体">​:</​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ 黑体, SimHei">​0xff 0xff 0xff&​nbsp;​ &nbsp; &nbsp; &​nbsp;&​nbsp;</​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun"><​span style="​font-family:​ 宋体;​background:​ lime">​合计</​span><​span style="​font-family:​ 黑体, SimHei;​background:​ lime">​27</​span><​span style="​font-family:​ 宋体;​background:​ lime">​字节</​span></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​background:​ lime;​font-family:​ arial, helvetica, sans-serif"><​br/></​span></​p><​p class="​MsoListParagraph"​ style="​white-space:​ normal"><​span style="​background:​ lime;​font-family:​ arial, helvetica, sans-serif"><​br/></​span></​p><​table width="​100%"><​tbody><​tr class="​firstRow"><​td style="​background-color:​ rgb(146, 208, 80)"><​p style="​text-align:​ center"><​span style="​font-family:​ arial, helvetica, sans-serif"><​strong><​span style="​font-size:​ 19px;​font-family:​ 宋体"><​a name="​b2"></​a></​span></​strong><​span style="​font-family:​ 黑体, SimHei"><​strong><​span style="​font-family:​ 宋体">​二</​span></​strong><​strong>​.HMI</​strong><​strong><​span style="​font-family:​ 宋体">​下载协议详解</​span></​strong></​span></​span></​p></​td></​tr></​tbody></​table><​table width="​100%"><​tbody><​tr class="​firstRow"><​td style="​background-color:​ rgb(238, 236, 225)"><​p style="​text-indent:​ 28px;​line-height:​ 33px"><​span style="​font-family:​ arial, helvetica, sans-serif"><​span style="​font-family:​ 宋体">​本文讲述的</​span><​span style="​font-family:​ 黑体, SimHei">​HMI</​span><​span style="​font-family:​ 宋体">​下载协议仅适用于希望自己制作<​strong><​span style="​font-family:​ 黑体, SimHei;​color:​ red">​下载程序</​span></​strong>​或者希望单片机去控制</​span><​span style="​font-family:​ 黑体, SimHei;​color:​ red">​HMI</​span><​strong><​span style="​font-family:​ 宋体;​color:​ red">​下载资源文件</​span></​strong><​span style="​font-family:​ 宋体">​的用户,属于<​strong><​span style="​font-family:​ 黑体, SimHei;​color:​ red">​高级应用</​span></​strong>​范畴,不属于</​span><​span style="​font-family:​ 黑体, SimHei">​HMI</​span><​span style="​font-family:​ 宋体">​界面设计的范畴,因此需要有一定基础的用户才能操作。深圳市淘晶驰电子有限公司仅仅只对此协议做一个公布说明,不提供任何跟下载协议有关的技术支持,如果对串口操作不熟悉的朋友建议忽略此说明,请直接使用</​span><​span style="​font-family:​ 黑体, SimHei">​USART HMI</​span><​span style="​font-family:​ 宋体">​软件进行下载即可,无需对此协议有任何了解。</​span>&​nbsp;</​span></​p></​td></​tr></​tbody></​table><​p style="​white-space:​ normal"><​span style="​font-size:​ 18px"><​strong><​span style="​font-family:​ 宋体, SimSun;​color:​ rgb(192, 0, 0)">​温馨提示:官方有按照本协议开发好的专用下载工具(TFTFileDownload),并且开放源代码,欢迎下载使用:</​span></​strong><​strong><​span style="​font-family:​ 宋体, SimSun"><​a href="​http://​wiki.tjc1688.com/​doku.php?​id=2.%E4%B8%8A%E4%BD%8D%E8%BD%AF%E4%BB%B6%E4%B8%8B%E8%BD%BD:​4.%E5%B8%B8%E7%94%A8%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7"​ target="​_self"​ style="​font-size:​ 20px">​点击此处下载</​a></​span></​strong></​span></​p><​p style="​white-space:​ normal"><​strong><​span style="​font-family:​ 宋体, SimSun">​【下载步骤1:联机操作】</​span></​strong></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​此步骤主要用来搜索HMI设备在哪个串口上,以及设备当前的波特率。如果这两个条件是已知的,那么可以不用做这个步骤,在你的程序中直接固定串口号和设备当前使用的波特率后直接跳到步骤2开始下载。</​span></​p><​p style="​white-space:​ normal"><​span style="​color:​ rgb(192, 80, 77)"><​strong><​span style="​font-family:​ 宋体, SimSun">​●搜索方法:</​span></​strong></​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​分别向电脑的每个串口分别用不同波特率发送一个联机指令:​connect+结束符</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​设备收到联机指令后会返回联机数据,如果收到正确的联机数据,说明设备联机成功,至此,得到当前设备的串口号和当前使用的波特率.</​span></​p><​p style="​white-space:​ normal"><​span style="​color:​ rgb(192, 80, 77)"><​strong><​span style="​font-family:​ 宋体, SimSun">​●联机指令发送说明:</​span></​strong></​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​因为一直在循环发送指令,所以当屏幕在正确的波特率上收到数据时,数据的最前面肯定会有部分上一次错误的波特率下的错误数据,因此这个时候第一条指令肯定是会被当成错误指令的。所以每次发送的时候需要发两条指令,第一条发4个字节的HEX空指令(00 ff ff ff),​第二条才是connect+结束符</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​延时说明:​每次尝试一次联机指令后需要等待数据返回的最短时间为(单位:​ms):​ (1000000/​尝试的波特率)+30</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​假如在9600波特率下尝试联机,需要等待返回的最短时间为:</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​1000000/​9600+30=134ms</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​其他波特率以此类推</​span></​p><​p style="​white-space:​ normal"><​span style="​color:​ rgb(192, 80, 77)"><​strong><​span style="​font-family:​ 宋体, SimSun">​●数据解释:</​span></​strong></​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​以TJC4024T032_011R设备为例,设备返回如下8组数据(每组数据逗号隔开):</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​comok 1,​101,​TJC4024T032_011R,​52,​61488,​D264B8204F0E1828,​16777216</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​comok:​握手回应</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​1:​表示带触摸(0是不带触摸)</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​101:​设备内部预留数据</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​TJC4024T032_011R:​设备型号</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​52:​设备固件版本号</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​61488:​设备主控芯片内部编码</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​D264B8204F0E1828:​设备唯一序列号</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​16777216:​设备FLASH大小(单位:字节)</​span></​p><​p style="​white-space:​ normal"><​strong><​span style="​font-family:​ 宋体, SimSun">​【下载步骤2:开始下载】</​span></​strong></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​此时已经知道设备在哪个串口号上,也知道设备当前的波特率了,可以发送下载指令了。</​span></​p><​p style="​white-space:​ normal"><​span style="​color:​ rgb(192, 80, 77)"><​strong><​span style="​font-family:​ 宋体, SimSun">​■第一步:发送指令whmi-wri filesize,​baud,​res0</​span></​strong></​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​filesize:​tft文件的大小(单位:字节)</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​baud:​强制下载使用的波特率</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​res0:​预留数据,使用任意ASCII字符即可</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​假如需要下载的tft文件大小为10000字节,​需要使用115200波特率下载,那么就发送指令:</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​whmi-wri 10000,​115200,​0</​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​发送完此指令以后,需要修改电脑的波特率为刚才设置的强制波特率(如果当前波特率和强制下载波特率不一致的话)</​span></​p><​p style="​white-space:​ normal"><​span style="​color:​ rgb(192, 80, 77)"><​strong><​span style="​font-family:​ 宋体, SimSun">​■第二步:下发tft文件的二进制数据</​span></​strong></​span></​p><​p style="​white-space:​ normal"><​span style="​font-family:​ 宋体, SimSun">​设备收到whmi-wri指令后在250ms左右后会返回一个0x05的数据(仅仅是一个字节,没有3个0XFF的结束符,波特率为刚才设置的强制下载波特率),​收到此数据后,可以开始下发tft文件的二进制数据,下发格式为每包下发4096字节,最后一包剩余多少就发多少,每包发送完成以后,需要等待屏幕返回响应信号,响应信号依然为一个单一字节的0x05。&​nbsp;</​span></​p><​p><​span style="​font-family:​ 宋体, SimSun"><​br/></​span></​p><​table width="​100%"><​tbody><​tr class="​firstRow"><​td valign="​middle"​ style="​background-color:​ rgb(146, 208, 80)"><​p><​strong><​a name="​comcrc"></​a>​三.串口指令增加CRC校验<​span style="​color:​ rgb(255, 0, 0);">​(0.56及其以上上位机版本支持)</​span></​strong></​p></​td></​tr></​tbody></​table><​table width="​100%"><​tbody><​tr class="​firstRow"><​td style="​background-color:​ rgb(238, 236, 225)"><​p style="​text-indent:​ 28px;​line-height:​ 33px"><​span style="​font-family:​ 宋体">​正常情况下,指令直接发送即可,不需要校验,如果您的项目对指令传输要求很严格必须开启校验请按照下列说明发送指令</​span></​p></​td></​tr></​tbody></​table><​p style="​white-space:​ normal"><​span style="​color:​ rgb(192, 0, 0)">​切记注意:上位软件版本0.56开始才支持指令CRC,之前的版本是不支持的。</​span></​p><​p style="​white-space:​ normal">​带校验或不带校验无需做任何配置,只需修改指令即可,您可以上一条指令带校验,下一条指令不带校验也是可以的。两种指令的区别如下:</​p><​p style="​white-space:​ normal"><​strong>​1.变更结束符</​strong></​p><​p style="​white-space:​ normal">&​nbsp;​ &​nbsp;​普通指令结束符为0xff 0xff 0xff,​带校验的指令结束符为0xfe 0xfe 0xfe。</​p><​p style="​white-space:​ normal"><​strong>​2.CRC16校验算法<​strong style="​white-space:​ normal; background-color:​ rgb(146, 208, 80);"><​a name="​crc16"></​a></​strong></​strong></​p><​p style="​white-space:​ normal">&​nbsp;​ &​nbsp;​指令CRC16校验算法使用MODBUS的CRC16校验算法,​计算函数如下:</​p><​p style="​white-space:​ normal">&​nbsp;​ &​nbsp;​需要校验的数据为所有指令数据,如果是带地址的指令,从地址开始算,不带地址的指令,就从指令第一个字节开始计算,结束符不计算在内。</​p><​pre class="​brush:​cpp;​toolbar:​false">​static&​nbsp;​U8&​nbsp;​InvertUint8(U8&​nbsp;​data)
 { {
 &​nbsp;&​nbsp;&​nbsp;​int&​nbsp;​i;​ &​nbsp;&​nbsp;&​nbsp;​int&​nbsp;​i;​
行 45: 行 45:
 &​nbsp;&​nbsp;&​nbsp;&​nbsp;​wCRCin&​nbsp;​=&​nbsp;​InvertUint16(wCRCin);​ &​nbsp;&​nbsp;&​nbsp;&​nbsp;​wCRCin&​nbsp;​=&​nbsp;​InvertUint16(wCRCin);​
 &​nbsp;&​nbsp;&​nbsp;&​nbsp;​return&​nbsp;​(wCRCin);​ &​nbsp;&​nbsp;&​nbsp;&​nbsp;​return&​nbsp;​(wCRCin);​
-}</​pre><​p style="​white-space:​ normal"><​strong>​3.CRC16校验码写入方式</​strong></​p><​p style="​white-space:​ normal">&​nbsp;​ &​nbsp;​指令后面,结束符前面,加上2字节的CRC16校验码(HEX)+1字节的常数:​0x01(HEX),​相当于在指令和结束符中间插入了3个字节,CRC校验码的储存方式是小端模式,​低位在前。</​p><​p><​span style="​color:​ rgb(192, 0, 0)">​如果屏幕收到带校验的指令后发现校验失败,会返回错误:0x09 0xff 0xff 0xff</​span></​p><​p><​br/></​p><​table width="​100%"><​tbody><​tr class="​firstRow"><​td valign="​middle"​ style="​background-color:​ rgb(146, 208, 80)"><​p><​strong><​a name="​comfile"></​a>​.运行中串口传输图片到内存或SD卡<​strong style="​white-space:​ normal; background-color:​ rgb(146, 208, 80);"><​span style="​color:​ rgb(255, 0, 0);">​(0.56及其以上上位机版本支持)</​span></​strong></​strong></​p></​td></​tr></​tbody></​table><​table width="​100%"><​tbody><​tr class="​firstRow"><​td style="​background-color:​ rgb(238, 236, 225)"><​p style="​text-indent:​ 28px;​line-height:​ 33px"><​strong><​span style="​font-family:​ arial, helvetica, sans-serif;​color:​ rgb(192, 0, 0)">​如果要传输图片文件到内存,请先在工程设置里面配置内存文件系统空间大小,默认是0,即没有空间用来储存内存文件。</​span></​strong></​p><​p style="​text-indent:​ 28px;​line-height:​ 33px"><​strong><​span style="​font-family:​ arial, helvetica, sans-serif;​color:​ rgb(192, 0, 0)"><​img src="/​dokuwiki/​ueditor/​php/​upload/​image/​20190313/​1552468597380056.png"​ title="​1552468597380056.png"​ alt="​D7_7PJI~8}GIJBTAST0YK2A.png"/></​span></​strong></​p><​p style="​text-indent:​ 28px;​line-height:​ 33px"><​strong><​span style="​font-family:​ arial, helvetica, sans-serif;​color:​ rgb(192, 0, 0)"><​img src="/​dokuwiki/​ueditor/​php/​upload/​image/​20190313/​1552468628932197.png"​ title="​1552468628932197.png"​ alt="​ON4DYYK25BCB2_MI`49C[_P.png"/></​span></​strong></​p><​p style="​text-indent:​ 28px;​line-height:​ 33px"><​strong><​span style="​font-family:​ arial, helvetica, sans-serif;​color:​ rgb(192, 0, 0)">​如果是传输图片文件到SD卡,请确保SD卡磁盘格式为FAT32,​最大支持32G容量的卡</​span></​strong></​p><​p style="​text-indent:​ 28px;​line-height:​ 33px"><​br/></​p><​p style="​text-indent:​ 28px;​line-height:​ 33px"><​br/></​p></​td></​tr></​tbody></​table><​p style="​white-space:​ normal"><​strong><​strong><​strong><​strong style="​font-size:​ 18px"><​span style="​font-family:​ 宋体, SimSun;​color:​ rgb(192, 0, 0)"><​br/></​span></​strong></​strong></​strong></​strong></​p><​p style="​white-space:​ normal"><​strong><​strong><​strong><​strong style="​font-size:​ 18px"><​span style="​font-family:​ 宋体, SimSun;​color:​ rgb(192, 0, 0)">​温馨提示:官方有按照本协议开发好的专用串口透传文件工具(SerialFileUp),并且开放源代码,欢迎下载使用:</​span></​strong></​strong></​strong></​strong></​p><​p style="​white-space:​ normal"><​strong><​strong><​strong><​strong style="​font-size:​ 18px"><​span style="​font-family:​ 宋体, SimSun"><​strong><​a href="​http://​wiki.tjc1688.com/​doku.php?​id=2.%E4%B8%8A%E4%BD%8D%E8%BD%AF%E4%BB%B6%E4%B8%8B%E8%BD%BD:​4.%E5%B8%B8%E7%94%A8%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7"​ target="​_self"​ style="​font-size:​ 20px">​点击此处下载</​a></​strong></​span></​strong></​strong></​strong></​strong></​p><​p style="​white-space:​ normal"><​strong><​strong><​strong><​strong style="​font-size:​ 18px"><​br/></​strong></​strong></​strong></​strong></​p><​p style="​white-space:​ normal"><​strong>​1.如何使用内存中的图片文件</​strong><​br/></​p><​p style="​white-space:​ normal">&​nbsp;​ &​nbsp;​使用“外部图片“控件,设置path属性为文件路径,如:​ram/​0.jpg</​p><​p style="​white-space:​ normal"><​strong>​2.如何使用SD卡中的图片文件</​strong></​p><​p style="​white-space:​ normal">&​nbsp;​ &​nbsp;​使用“外部图片“控件,设置path属性为文件路径,如:​sd0/​0.jpg<​br/></​p><​p style="​white-space:​ normal"><​strong>​3.支持什么类型的图片文件</​strong></​p><​p>&​nbsp;​ &​nbsp;<​strong>​jpg格式:</​strong>​如果使用jpg格式的图片,务必保证图片编码为:​baseline DCT,​否则将无法显示,​如果屏幕方向设置的是0度,直接使用jpg原图即可,如果屏幕方向设置的是90度,需要将图片顺时钟旋转90度再给屏幕使用,否则显示出来的图片方向是错的。其他方向180度,270度以此类推,屏幕方向是多少度,就需要您提前把图片顺时钟旋转多少度。</​p><​p>&​nbsp;​ &​nbsp;<​strong>​xi格式:</​strong>​此格式为HMI专用图片格式,支持透明背景,推荐使用这种格式,xi格式的图片获取方式可以使用软件工具菜单中的图片转换工具:​PictureBox转换</​p><​p><​img src="/​dokuwiki/​ueditor/​php/​upload/​image/​20190313/​1552469288125906.png"​ title="​1552469288125906.png"​ alt="​X}DOZO7EU5ORK7]4%K$4H@A.png"/></​p><​p><​span style="​color:​ rgb(192, 0, 0)">​目前仅支持以上两种格式的图片文件。</​span></​p><​p><​strong>​4.串口传输协议</​strong></​p><​p><​span style="​color:​ rgb(192, 0, 0)">​第一步:​发送串口传输文件指令:​twfile filepath,​filesize</​span></​p><​p>​filepath:​文件存放路径 如:​ram/​a.jpg 或 sd0/​a.jpg</​p><​p>​filesize:​文件实际大小</​p><​p>​假如要传一个文件到内存中,名字为a.jpg,​大小为3282,​指令为:twfile &​quot;​ram/​a.jpg&​quot;,​3282</​p><​p>​假如要传一个文件到SD卡中,名字为a.jpg,​大小为3282,​指令为:twfile &​quot;​sd0/​a.jpg&​quot;,​3282</​p><​p>​屏幕收到此指令后,会立即创建一个指定大小的文件在目标路径上,如果创建成功将返回:​0xfe+结束符,​表示已经进入透传状态,可以开始分包透传数据。如果创建文件失败会返回:​0x06+结束符,​并继续工作在指令接收状态。</​p><​p><​span style="​color:​ rgb(192, 0, 0)">​第二步:分包透传文件数据</​span></​p><​p>​收到0xfe+结束符后,可以开始分包透传数据;​一个完整的数据包由2部分组成:包头+数据</​p><​p><​strong>​包头:</​strong>​3a a1 bb 44 7f ff fe +包ID(2字节整形数据)+校验类型(1字节整形数据) +数据大小(2字节整形数据),合计12字节</​p><​pre class="​brush:​cpp;​toolbar:​false">​包ID:​文件透传开始第一次包ID为0,每成功透传一包,ID加1.+}</​pre><​p style="​white-space:​ normal"><​strong>​3.CRC16校验码写入方式</​strong></​p><​p style="​white-space:​ normal">&​nbsp;​ &​nbsp;​指令后面,结束符前面,加上2字节的CRC16校验码(HEX)+1字节的常数:​0x01(HEX),​相当于在指令和结束符中间插入了3个字节,CRC校验码的储存方式是小端模式,​低位在前。</​p><​p><​span style="​color:​ rgb(192, 0, 0)">​如果屏幕收到带校验的指令后发现校验失败,会返回错误:0x09 0xff 0xff 0xff</​span></​p><​table width="​100%"><​tbody><​tr class="​firstRow"><​td valign="​middle"​ style="​background-color:​ rgb(146, 208, 80);"><p><​strong><​a name="​mcrc"></​a>​四.程序中使用CRC校验数据<​span style="​color:​ rgb(255, 0, 0);">​(1.60.1及其以上上位机版本支持)</​span></​strong></​p></​td></​tr></​tbody></​table><​p style="​padding:​ 0px; color: rgb(51, 51, 51); font-family:​ Arial, sans-serif; font-size: 14px; white-space:​ normal;">​1.以下代码将实现屏幕给外部设备发送2组常量数据,并在结尾带上Modbus的CRC16校验结果:</​p><​pre class="​brush:​cpp;​toolbar:​false"​ style="​margin-top:​ 5px; margin-bottom:​ 5px; padding: 0.7em 1em; font-family:​ Consolas, &​quot;​Andale Mono WT&​quot;,​ &​quot;​Andale Mono&​quot;,​ &​quot;​Bitstream Vera Sans Mono&​quot;,​ &​quot;​Nimbus Mono L&​quot;,​ Monaco, &​quot;​Courier New&​quot;,​ monospace; font-size: 14px; direction: ltr; background-color:​ rgb(251, 250, 249); color: rgb(51, 51, 51); box-shadow: rgb(204, 204, 204) 0px 0px 0.5em inset; border-radius:​ 2px; overflow: auto; overflow-wrap:​ normal; border: 1px solid rgb(204, 204, 204);">​crcrest&​nbsp;​1,​0xffff&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​复位CRC 
 +crcputs&​nbsp;&​quot;​hex&​nbsp;​date&​nbsp;​is:&​quot;,​0&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​CRC校验字符串:​hex&​nbsp;​date&​nbsp;​is:​ 
 +crcputh&​nbsp;​03&​nbsp;​25&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​CRC校验hex:​0x03,​0x25 
 +prints&​nbsp;&​quot;​hex&​nbsp;​date&​nbsp;​is:&​quot;,​0&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​串口发送字符串:​hex&​nbsp;​date&​nbsp;​is:​ 
 +printh&​nbsp;​03&​nbsp;​25&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​串口发送hex:​0x03,​0x25 
 +prints&​nbsp;​crcval,​2&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​串口发送校验结果</​pre><​p style="​padding:​ 0px; color: rgb(51, 51, 51); font-family:​ Arial, sans-serif; font-size: 14px; white-space:​ normal;"​><​br/></​p><p style="​padding:​ 0px; color: rgb(51, 51, 51); font-family:​ Arial, sans-serif; font-size: 14px; white-space:​ normal;">​2.以下代码将实现屏幕给外部设备发送2组变量数据,并在结尾带上Modbus的CRC16校验结果:</​p><​pre class="​brush:​c#;​toolbar:​false;"​ style="​margin-top:​ 5px; margin-bottom:​ 5px; padding: 0.7em 1em; font-family:​ Consolas, &​quot;​Andale Mono WT&​quot;,​ &​quot;​Andale Mono&​quot;,​ &​quot;​Bitstream Vera Sans Mono&​quot;,​ &​quot;​Nimbus Mono L&​quot;,​ Monaco, &​quot;​Courier New&​quot;,​ monospace; font-size: 14px; direction: ltr; background-color:​ rgb(251, 250, 249); color: rgb(51, 51, 51); box-shadow: rgb(204, 204, 204) 0px 0px 0.5em inset; border-radius:​ 2px; overflow: auto; overflow-wrap:​ normal; border: 1px solid rgb(204, 204, 204);">​crcrest&​nbsp;​1,​0xffff&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​复位CRC 
 +crcputs&​nbsp;​t0.txt,​0&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​CRC校验字符串变量t0.txt 
 +crcputs&​nbsp;​n0.val,​0&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​CRC校验数值变量n0.val 
 +prints&​nbsp;​t0.txt,​0&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​串口发送字符串变量t0.txt 
 +prints&​nbsp;​n0.val,​4&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​串口发送数值变量n0.val 
 +prints&​nbsp;​crcval,​2&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​串口发送校验结果</​pre><​p style="​padding:​ 0px; color: rgb(51, 51, 51); font-family:​ Arial, sans-serif; font-size: 14px; white-space:​ normal;"><​br/></​p><​p style="​padding:​ 0px; color: rgb(51, 51, 51); font-family:​ Arial, sans-serif; font-size: 14px; white-space:​ normal;">​3.以下代码将实现在主动解析模式下对串口缓冲区的数据进行CRC校验,​并将成功与否的结果显示到t0.txt</​p><​pre class="​brush:​cpp;​toolbar:​false"​ style="​margin-top:​ 5px; margin-bottom:​ 5px; padding: 0.7em 1em; font-family:​ Consolas, &​quot;​Andale Mono WT&​quot;,​ &​quot;​Andale Mono&​quot;,​ &​quot;​Bitstream Vera Sans Mono&​quot;,​ &​quot;​Nimbus Mono L&​quot;,​ Monaco, &​quot;​Courier New&​quot;,​ monospace; font-size: 14px; direction: ltr; background-color:​ rgb(251, 250, 249); color: rgb(51, 51, 51); box-shadow: rgb(204, 204, 204) 0px 0px 0.5em inset; border-radius:​ 2px; overflow: auto; overflow-wrap:​ normal; border: 1px solid rgb(204, 204, 204);">​if(usize&​gt;​=24) 
 +
 +&​nbsp;&​nbsp;​crcrest&​nbsp;​1,​0xffff&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​复位CRC 
 +&​nbsp;&​nbsp;​crcputu&​nbsp;​0,​22&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​校验串口缓冲区的前面22个字节 
 +&​nbsp;&​nbsp;​sys0=0&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​sys0是4字节的整形数据,​CRC结果只有2字节,所以先给多余字节数据清零 
 +&​nbsp;&​nbsp;​ucopy&​nbsp;​sys0,​22,​2,​0&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​将接收缓冲区中接收到的CRC结果赋值给sys0 
 +&​nbsp;&​nbsp;​if(sys0==crcval)校验通过 
 +&​nbsp;&​nbsp;​{ 
 +&​nbsp;&​nbsp;&​nbsp;&​nbsp;​t0.txt=&​quot;​校验通过&​quot;​ 
 +&​nbsp;&​nbsp;​}else 
 +&​nbsp;&​nbsp;​{ 
 +&​nbsp;&​nbsp;&​nbsp;&​nbsp;​t0.txt=&​quot;​校验不通过&​quot;​ 
 +&​nbsp;&​nbsp;​} 
 +&​nbsp;&​nbsp;​udelete&​nbsp;​24&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;&​nbsp;​删除已经处理的24字节 
 +}</pre><​table width="​100%"><​tbody><​tr class="​firstRow"><​td valign="​middle"​ style="​background-color:​ rgb(146, 208, 80)"><​p><​strong><​a name="​comfile"></​a>​.运行中串口传输图片到内存或SD卡<​strong style="​white-space:​ normal; background-color:​ rgb(146, 208, 80);"><​span style="​color:​ rgb(255, 0, 0);">​(0.56及其以上上位机版本支持)</​span></​strong></​strong></​p></​td></​tr></​tbody></​table><​table width="​100%"><​tbody><​tr class="​firstRow"><​td style="​background-color:​ rgb(238, 236, 225)"><​p style="​text-indent:​ 28px;​line-height:​ 33px"><​strong><​span style="​font-family:​ arial, helvetica, sans-serif;​color:​ rgb(192, 0, 0)">​如果要传输图片文件到内存,请先在工程设置里面配置内存文件系统空间大小,默认是0,即没有空间用来储存内存文件。</​span></​strong></​p><​p style="​text-indent:​ 28px;​line-height:​ 33px"><​strong><​span style="​font-family:​ arial, helvetica, sans-serif;​color:​ rgb(192, 0, 0)"><​img src="/​dokuwiki/​ueditor/​php/​upload/​image/​20190313/​1552468597380056.png"​ title="​1552468597380056.png"​ alt="​D7_7PJI~8}GIJBTAST0YK2A.png"/></​span></​strong></​p><​p style="​text-indent:​ 28px;​line-height:​ 33px"><​strong><​span style="​font-family:​ arial, helvetica, sans-serif;​color:​ rgb(192, 0, 0)"><​img src="/​dokuwiki/​ueditor/​php/​upload/​image/​20190313/​1552468628932197.png"​ title="​1552468628932197.png"​ alt="​ON4DYYK25BCB2_MI`49C[_P.png"/></​span></​strong></​p><​p style="​text-indent:​ 28px;​line-height:​ 33px"><​strong><​span style="​font-family:​ arial, helvetica, sans-serif;​color:​ rgb(192, 0, 0)">​如果是传输图片文件到SD卡,请确保SD卡磁盘格式为FAT32,​最大支持32G容量的卡</​span></​strong></​p><​p style="​text-indent:​ 28px;​line-height:​ 33px"><​br/></​p><​p style="​text-indent:​ 28px;​line-height:​ 33px"><​br/></​p></​td></​tr></​tbody></​table><​p style="​white-space:​ normal"><​strong><​strong><​strong><​strong style="​font-size:​ 18px"><​span style="​font-family:​ 宋体, SimSun;​color:​ rgb(192, 0, 0)"><​br/></​span></​strong></​strong></​strong></​strong></​p><​p style="​white-space:​ normal"><​strong><​strong><​strong><​strong style="​font-size:​ 18px"><​span style="​font-family:​ 宋体, SimSun;​color:​ rgb(192, 0, 0)">​温馨提示:官方有按照本协议开发好的专用串口透传文件工具(SerialFileUp),并且开放源代码,欢迎下载使用:</​span></​strong></​strong></​strong></​strong></​p><​p style="​white-space:​ normal"><​strong><​strong><​strong><​strong style="​font-size:​ 18px"><​span style="​font-family:​ 宋体, SimSun"><​strong><​a href="​http://​wiki.tjc1688.com/​doku.php?​id=2.%E4%B8%8A%E4%BD%8D%E8%BD%AF%E4%BB%B6%E4%B8%8B%E8%BD%BD:​4.%E5%B8%B8%E7%94%A8%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7"​ target="​_self"​ style="​font-size:​ 20px">​点击此处下载</​a></​strong></​span></​strong></​strong></​strong></​strong></​p><​p style="​white-space:​ normal"><​strong><​strong><​strong><​strong style="​font-size:​ 18px"><​br/></​strong></​strong></​strong></​strong></​p><​p style="​white-space:​ normal"><​strong>​1.如何使用内存中的图片文件</​strong><​br/></​p><​p style="​white-space:​ normal">&​nbsp;​ &​nbsp;​使用“外部图片“控件,设置path属性为文件路径,如:​ram/​0.jpg</​p><​p style="​white-space:​ normal"><​strong>​2.如何使用SD卡中的图片文件</​strong></​p><​p style="​white-space:​ normal">&​nbsp;​ &​nbsp;​使用“外部图片“控件,设置path属性为文件路径,如:​sd0/​0.jpg<​br/></​p><​p style="​white-space:​ normal"><​strong>​3.支持什么类型的图片文件</​strong></​p><​p>&​nbsp;​ &​nbsp;<​strong>​jpg格式:</​strong>​如果使用jpg格式的图片,务必保证图片编码为:​baseline DCT,​否则将无法显示,​如果屏幕方向设置的是0度,直接使用jpg原图即可,如果屏幕方向设置的是90度,需要将图片顺时钟旋转90度再给屏幕使用,否则显示出来的图片方向是错的。其他方向180度,270度以此类推,屏幕方向是多少度,就需要您提前把图片顺时钟旋转多少度。</​p><​p>&​nbsp;​ &​nbsp;<​strong>​xi格式:</​strong>​此格式为HMI专用图片格式,支持透明背景,推荐使用这种格式,xi格式的图片获取方式可以使用软件工具菜单中的图片转换工具:​PictureBox转换</​p><​p><​img src="/​dokuwiki/​ueditor/​php/​upload/​image/​20190313/​1552469288125906.png"​ title="​1552469288125906.png"​ alt="​X}DOZO7EU5ORK7]4%K$4H@A.png"/></​p><​p><​span style="​color:​ rgb(192, 0, 0)">​目前仅支持以上两种格式的图片文件。</​span></​p><​p><​strong>​4.串口传输协议</​strong></​p><​p><​span style="​color:​ rgb(192, 0, 0)">​第一步:​发送串口传输文件指令:​twfile filepath,​filesize</​span></​p><​p>​filepath:​文件存放路径 如:​ram/​a.jpg 或 sd0/​a.jpg</​p><​p>​filesize:​文件实际大小</​p><​p>​假如要传一个文件到内存中,名字为a.jpg,​大小为3282,​指令为:twfile &​quot;​ram/​a.jpg&​quot;,​3282</​p><​p>​假如要传一个文件到SD卡中,名字为a.jpg,​大小为3282,​指令为:twfile &​quot;​sd0/​a.jpg&​quot;,​3282</​p><​p>​屏幕收到此指令后,会立即创建一个指定大小的文件在目标路径上,如果创建成功将返回:​0xfe+结束符,​表示已经进入透传状态,可以开始分包透传数据。如果创建文件失败会返回:​0x06+结束符,​并继续工作在指令接收状态。</​p><​p><​span style="​color:​ rgb(192, 0, 0)">​第二步:分包透传文件数据</​span></​p><​p>​收到0xfe+结束符后,可以开始分包透传数据;​一个完整的数据包由2部分组成:包头+数据</​p><​p><​strong>​包头:</​strong>​3a a1 bb 44 7f ff fe +包ID(2字节整形数据)+校验类型(1字节整形数据) +数据大小(2字节整形数据),合计12字节</​p><​pre class="​brush:​cpp;​toolbar:​false">​包ID:​文件透传开始第一次包ID为0,每成功透传一包,ID加1.
 校验类型:​0x00为无校验,​0x01为CRC16(MODBUS的CRC16校验算法,​指令校验篇幅中有计算函数参考),​0x02为标准CRC32 校验类型:​0x00为无校验,​0x01为CRC16(MODBUS的CRC16校验算法,​指令校验篇幅中有计算函数参考),​0x02为标准CRC32
 数据大小:​数据大小用户随意指定,最小1字节,最大4096字节(此数据大小不包含12字节的包头,但是包含CRC校验码)</​pre><​p><​strong>​数据:</​strong>​文件数据+CRC校验码数据(小端模式,低位在前),​如果是无校验的包,就没有CRC校验码。如果是CRC16就是2字节的校验码,如果是CRC32就是4字节的校验码,切记注意校验码数据要记入包头的数据大小参数中。</​p><​p>​CRC16校验算法为MODBUS CRC16,<a href="#​crc16"​ target="​_self"​ style="​text-decoration:​ underline; color: rgb(0, 0, 0);"><​strong><​span style="​color:​ rgb(0, 0, 0);">​点击此处查看参考函数代码</​span></​strong></​a>​ CRC32校验算法为标准CRC32。</​p><​p><​span style="​color:​ rgb(151, 72, 6)">​屏幕收到一个完整的包数据后,如果处理成功会返回0x05(单字节,没有结束符),​此时可进入下一个包的发送。</​span></​p><​p><​span style="​color:​ rgb(151, 72, 6)">​如果包ID不按规则累加或者包数据出错,屏幕将会返回本包处理失败的错误:​0x04(单字节,无结束符)。</​span></​p><​p><​span style="​color:​ rgb(151, 72, 6)">​所有包发送完成后,屏幕会返回0xfd+结束符。并自动退出透传模式转为指令模式。</​span></​p><​p><​span style="​color:​ rgb(151, 72, 6)">​如果本包透传失败(超过500ms没有收到屏幕回应或者收到屏幕返回本包校验失败的错误信息),重新发本包数据,重发本包数据时包ID无需加1。</​span></​p><​p><​span style="​color:​ rgb(151, 72, 6)">​如果数据包发了一半后悔了,停顿20ms以上重新发本包数据即可。</​span></​p><​p><​span style="​color:​ rgb(151, 72, 6)">​如果透传文件中途想停止透传,请发一个包ID为65535,无校验,数据大小为0的数据包,​即:​3a a1 bb 44 7f ff fe ff ff 00 00 00 屏幕收到这样的包数据后会立刻强制结束透传,并返回透传结束的数据:0xfd+结束符</​span></​p><​p><​span style="​color:​ rgb(151, 72, 6)">​如果你的文件数据中包含退出包数据是不用担心的,因为这个数据的前面满足不了20ms以上的停顿,屏幕只会把他当数据储存,不会当结束包来处理。</​span></​p><​p><​br/></​p><​p><​br/></​p><​p><​br/></​p>​ 数据大小:​数据大小用户随意指定,最小1字节,最大4096字节(此数据大小不包含12字节的包头,但是包含CRC校验码)</​pre><​p><​strong>​数据:</​strong>​文件数据+CRC校验码数据(小端模式,低位在前),​如果是无校验的包,就没有CRC校验码。如果是CRC16就是2字节的校验码,如果是CRC32就是4字节的校验码,切记注意校验码数据要记入包头的数据大小参数中。</​p><​p>​CRC16校验算法为MODBUS CRC16,<a href="#​crc16"​ target="​_self"​ style="​text-decoration:​ underline; color: rgb(0, 0, 0);"><​strong><​span style="​color:​ rgb(0, 0, 0);">​点击此处查看参考函数代码</​span></​strong></​a>​ CRC32校验算法为标准CRC32。</​p><​p><​span style="​color:​ rgb(151, 72, 6)">​屏幕收到一个完整的包数据后,如果处理成功会返回0x05(单字节,没有结束符),​此时可进入下一个包的发送。</​span></​p><​p><​span style="​color:​ rgb(151, 72, 6)">​如果包ID不按规则累加或者包数据出错,屏幕将会返回本包处理失败的错误:​0x04(单字节,无结束符)。</​span></​p><​p><​span style="​color:​ rgb(151, 72, 6)">​所有包发送完成后,屏幕会返回0xfd+结束符。并自动退出透传模式转为指令模式。</​span></​p><​p><​span style="​color:​ rgb(151, 72, 6)">​如果本包透传失败(超过500ms没有收到屏幕回应或者收到屏幕返回本包校验失败的错误信息),重新发本包数据,重发本包数据时包ID无需加1。</​span></​p><​p><​span style="​color:​ rgb(151, 72, 6)">​如果数据包发了一半后悔了,停顿20ms以上重新发本包数据即可。</​span></​p><​p><​span style="​color:​ rgb(151, 72, 6)">​如果透传文件中途想停止透传,请发一个包ID为65535,无校验,数据大小为0的数据包,​即:​3a a1 bb 44 7f ff fe ff ff 00 00 00 屏幕收到这样的包数据后会立刻强制结束透传,并返回透传结束的数据:0xfd+结束符</​span></​p><​p><​span style="​color:​ rgb(151, 72, 6)">​如果你的文件数据中包含退出包数据是不用担心的,因为这个数据的前面满足不了20ms以上的停顿,屏幕只会把他当数据储存,不会当结束包来处理。</​span></​p><​p><​br/></​p><​p><​br/></​p><​p><​br/></​p>​
6.指令集/6.高级应用与特殊指令.txt · 最后更改: 2020/04/08 13:13 由 admin        浏览次数:67827/1822349(本页/全站)