通讯程序理解_第1页
通讯程序理解_第2页
通讯程序理解_第3页
通讯程序理解_第4页
通讯程序理解_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、通讯程序理解 本程序中的通讯部分以103规约为规则,通过C语言编程实现控制系统与DSP控制板之间的通讯,并且将控制系统(即上位机操作)作为链路层主站,DSP控制板为链路层子站,遵照103规约,建立通讯联系,这是一种非平衡的传输方式,即控制系统一般作为启动站,而DSP控制板一般作为从动站。在通讯过程中,数据信息以帧的形式传递,按照帧长是否可变分为固定长帧和可变长帧,一般情况下,复位,请求,响应帧(确认帧,忙帧,无所请求的数据帧等)都为固定帧长,在103规约中,每一个固定帧都有其特定的格式,详情请参考103规约。固定帧长帧的格式如下图: 其中启动字符和结束字符为固定值,控制域和地址域携带本次上传或

2、下传的简单信息;传输顺序为先低后高,另外需要注意的是,帧与帧的传输之间线路空闲间隔至少为33位,而字符之间不需要线路空闲间隔;可变帧长一般用来传输数据信息,其帧长不固定,其中的控制域和地址域与固定长帧的含义并无差别。但是需要注意的是,可变长帧的报文头是固定的,这对于校验非常重要,这是可变帧长帧校验必不可少的校验对象,其之所以可变就是就是指的链路用户数据。其格式如下图所示: 应用服务数据为可变长度的信息集合,信息集合的应用场合由类型标志,命令类型等确定,应用服务数据单元的格式如下,关于详细内容请参考103公约:地址域长度为一个字节,其高四位是发送方的地址,低四位为接收方的地址。控制域中在上层向下

3、层和下层向上层的过程中所表示的含义有差别,具体参照103公约,其控制与的格式如下图: 注:其中分为两部分的空格中,上面的一部分表示从上层到下层传输时的含义,下面的一部分表示下层到上层传输是的含义。个人认为FCB较难理解,这里稍加阐释。上层向下层传输报文时,将FCB取相反的的值,上层为下层保存一个FCB的备份,若超时未收到所期望的报文,或出现差错,则上层控制系统不改变FCB的状态,重传该报文,最多3次,如果3次以内上层收不到下层的确定或响应信息,则表示通讯故障。ASDU的类型有很多,每一种类型对应着一种数据格式,这在103规约中有明确规定,这里只介绍下一般命令型。个人认为一般命令型较为复杂,其余

4、较易理解,这里就不在一一解释。一般命令型的格式如下: 序号说明1类型标志TYP:01H2传送原因COT(见4.1.2)3命令类型FUN(见4.1.3)4附加信息SIN其中附加信息在这里要详加解释,其每种命令类型对应的含义如下表: 命令类型FUN附加信息SIN含义查询定值<20H>27 定值区域编号 20定值区域切换<30H>27 切换后的定值区号 20请求启动记录说明<51H>27 记录表中的序号 20请求故障记录说明<52H>27 记录表中的序号 20其他00H无意义以下是对我们的程序的分析:1. 变量定义和结构体构造变量包括通讯口状态,链路层

5、通讯地址,校验信息,错误码定义,命令,功能码,类型标志,传送原因等,对于结构体,首先建立数据应用层结构,应用服务数据单元接收部分具体结构如下: 一个完整的数据包由多个ASDU(应用服务数据单元)组成,每个ASDU包含在一个数据帧中 struct inasdu_data unsigned char uAsduType; /ASDU类型标志 unsigned char uCmdType; /命令类型 unsigned char uFrmCount; /组成一个数据包的帧总数 unsigned char uFrmIndex; /数据包中的当前帧序号 unsigned char uData10255;

6、 /构成当前ASDU的字符数组,其中uData帧序号0作为有效数据计数器使用 unsigned char uValidFlag; /0 ASDU不可用;1 ASDU可用;应用服务数据单元发送部分与之类似。 紧接着是链路层结构:串口状态数据,数据发送之前全部放置在该结构体的数据中struct com_data unsigned char uComState; /串口状态 unsigned char uTimeOut; /通讯超时次数 unsigned char uDataIndex; /数据区位置索引。接收状态时候该值为0,程序中将其加1,表示从第一个数开始存放,存放1个就将该寄存器加1,最后放

7、入在COM.uInData0中;发送的时候该值为1,表示直接发需要传送的数据,发完一个数再加1 unsigned char uInData255; /输入数据区,其中COM.uInData0作为有效数据计数器使用 unsigned char uOutData255; /输出数据区,其中COM.uOutData0作为有效数据计数器使用 unsigned char uACDFlag; /故障时间标志位 unsigned char uFCBFlag; /帧计数位 unsigned char uRadFlag; /广播标志位 unsigned char uSourceAddr; /请求源地址 unsi

8、gned char uDestinAddr; /目的地址;2. 分析各个重要子函数:l void LPDU_Analyze();此子函数的功能是链路层数据分析及提取,也就是com数组中的一帧数据进行处理判断。首先提取这个数据帧的长度,进而判断该数据帧是固定帧还是可变帧长帧,在103规约中,固定帧的帧长是5个字节,所以很容易判断是否为固定帧(因为可变帧长的报文头加上各种标志就已经7个字节,所以可以排除5个字节的可变帧长帧的干扰),根据判断结果提取出对应的控制域信息,COM.uInData2对应的是固定帧的控制域数据,而COM.uInData5对应着可变帧长帧的控制域信息,这个由103公约决定,上

9、述格式中已经说明。紧接着判断对应控制域的计数有效位是否有效,至于为什么将控制域数据与0x10进行&运算就可以判断是否有效?请参照前文所述的控制域格式。在计数有效位即FCV位有效后,(uCtlCode&0x20)!=0)用来判断计数位的值,将声明的FCB标志位即uFCBFlag取与之相反的值,至于原因,前文已经讲到。在取到uFCBFlag的值以后,在判断DSP是否将计数位变位,如果变位则表示数据传输成功,进而提取功能码,否则重传数据。uFrmType=uCtlCode&0x0F;即提取到了功能码;然后利用switch语句对功能码进行判断;每个功能码的数值由103公约决定,

10、在变量初始化中已经用define语句进行定义。Switch中的语句都较为简单,在理解上文的基础上且在源程序中已经进行详细解释,在这里就不在详加赘述。在该子程序的最后有判断数据是否有效的程序,分别是对故障标志位和ACD位进行判断,如果条件成立则进行事件记录。l void ASDU_Extract();这个子函数的功能是从接收的数据中提取应用服务数据。首先要得到应用服务数据的总长,至于为什么减2?是因为L即总长包括控制域信息和地址域信息,这个上文中的可变帧长帧格格式中可以清楚地看到。紧接着得到ASDU类型标志和命令类型。然后利用switch语句对各种类型的ASDU进行相对应的操作。switch语句

11、中的大部分语句容易理解,就不再解释,但我认为以下部分需要深刻理解: case ASDU3_SETSLIST: /用户定值 InAsdus.uFrmCount=COM.uInData10; InAsdus.uFrmIndex=COM.uInData11; 看到这个我想很多人不明白,为什么COM数组中的第10和第11个跟别表示帧总数和当前帧数呢?其实如果仔细看前文,这个问题已经解决过了,在链路层数据的前个字节是各种链路规约的信息,而服务层中如果是整定值列表则第个和第个字节分别表示总帧数和当前帧数,详见链路层结构体。至此我想已经解释清楚这个问题了。 在switch语句执行完之后,接着就是保存刚刚提取

12、出来的当前帧数,然后保存应用服务数据的总长,紧接着利用for循环,将接收到的数据提取出来。接下来就是判断当前帧数是否为总帧数,若成立则置位ASDU有效位,否则清零该位。l void ASDU_Analyze();这个子函数的功能是分析提取出来的数据信息。首先提取应用服务数据信息中的传送原因和命令类型,至于为什么是数组中的第2和第3个数据,上文中的应用服务单元的格式已说明。然后就是利用switch语句对ASDU的每一种类型进行相对应的处理,InAsdus.uAsduType在void ASDU_Extract()中已经提取出来。对于每个ASDU类型都有与其相对应的数据格式,详情请看103规约,这

13、里的switch语句内的程序有几个地方较为复杂,现在就来一一分析。 case ASDU1_COMMAND: uSIN=InAsdus.uData04; ASDU_01_Command_Execute(uFUN,uSIN); 如果是一般命令类型,则进入到命令类型的详细程序中去。uSIN得到的是附加信息,用来判断该命令是一般命令类型中的哪一种。其对应含义在前文中已经讲明。 case ASDU3_SETSLIST: 整定值下载命令 首先提取定值区号,然后提取总帧数。在将计数变量归零之后利用for循环提取全部定值。最后组装整定值,为后续程序做准备。 case ASDU11_CFMCMD: 定值与控制频

14、率修改执行 首先判断InAsdus.uData04的值,根据值的不同进行相对应的操作,在这种ASDU类型下,InAsdus.uData04表示的含义在103规约中已做规定。其余部分较易理解。 注:未提到的数据类型较易理解,就不在详加赘述。 在该子程序最后另InAsdus.uValidFlag=0,即清零标志位。防止该数据再被利用。l char LPDU_Check();此子函数的功能是链路层数据的校验。首先利用switch语句判断是固定帧还是可变帧长帧,分别对应必备的校验内容,其校验内容由103规约决定。对于可变帧长帧:先检验起始符是否正确,103规约中规定可变帧长帧的起始符为0x68。接着判

15、断帧的第二个字节与第三个字节是否相等,在程序中就是:if (COM.uInData2!=COM.uInData3)在可变帧长帧的格式中第二个和第三个字节都是总帧长的地址,所以判断这两个字节是否相等可起到校验作用。紧接着是提取用户数据的总长度,uAsduLen=COM.uInData2-2,后面的减2是因为L包括一个字节的地址域数据和一个字节的控制域数据。紧接着提取目的地址和源地址,地址域数据的高4位是源地址即主站地址,低4位是目的地址即子站地址,提取之后判断子站地址是否为DSP板的地址。紧接着校验校验和,校验和包括地址域,控制域数据及所有数据之和,可变帧的最后一个字节所存位校验和,将得到的校验

16、和与之相比较,相等则正确,否则数据错误。最后校验结束支付是否正确,可变帧长帧的结束字符是0x16。至此可变帧长帧的校验已经结束。下面开始讨论固定帧的校验,首先提取主站地址和子站地址,地址域数据的结构与可变帧长帧的结构相同。接着判断子站地址是否为我们的DSP控制板的地址。固定帧长的校验和只有地址域数据和控制域数据的和,将所得的校验和与已经存在的较验和进行校验,判断数据是否有效。最后判断固定帧的结束符是否正确,103规约中规定固定帧的结束符为0x16。在这里我想解释一下固定帧长为什么没有校验起始符?其实起始符已经利用switch语句进行判断,如果起始符不正确根本进不来校验其他部分,而可变帧长帧之所

17、以有校验其起始符的步骤是因为可变帧长帧的格式规定第一个字节和第4个字节都是起始符即0x68,在switch中已经检验第一个起始符了,而固定帧长帧的起始符只有1一个,即第一个字节,其实switch(COM.uInData1)是优先级最高的校验。总之一句话,对于不同帧的校验内容由其特殊格式决定。到这里我想这个子函数已经解释清楚了。l void Communicate();此子函数的功能是中断中使用的通讯程序。利用switch语句判断端口状态并对其各个状态进行相对应的得操作。当端口状态处于发送状态时,判断发送缓冲寄存器是否准备就绪,当SCICTL2寄存器中的最高位即TXRDY为1时,表示SCITXB

18、UF准备好接收下一组发送的数据。这里需要注意的是,该模式下串口一次只能发送一个数据,这样for语句应该就可以理解为什么是只能循环一次了。将要发送的数据送给串口缓冲区,然后利用if语句进行发送过程是否结束的判断,如果数据发送完毕,或者发送到最后一个就结束,其判断语句用C语言的或运算符表示如下:if(COM.uDataIndex>=COM.uOutData0|COM.uDataIndex>=254) COM.uOutData0中存放的是一帧数据中的字节总数。如果发送完毕则将端口状态置为等待状态,否则字节计数变量自加1。如果端口状态为等待状态则直接跳出switch语句。下面来讨论端口状态为接收状态的情况,首先提取位置区索引的值,当处于接收状态时,该值为0。紧接着判断接收缓冲寄存器是否准备就绪,SCI

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论