命令帧共6个字节,传输方向为PC机到单片机。以0X00H作为帧起始,数据长度为2,当数据1和数据2同为0X00时,表示启动接口卡,单片机接收到该信号后.会初始化SJA1000,并将结果反馈给PC机(成功或失败);当数据1和数据2同为0XFFH时,表示要求接口卡停止工作,单片机会让SJA1000进入睡眠模式,以退出总线;当数据1为0X01H时,表示PC机要求只接收某个节点的数据,数据2则表示该接点的节点号,单片机会重新设置SJA1000的验收滤波器,屏蔽掉其他不需要的节点数据。
应答帧共6个字节,传输方向为单片机到PC机。以0X11H作为帧起始,数据长度为2,当单片机接收到PC机的启动或停止命令,并设置成功后,发送两字节数据同为0X00H给PC,若设置失败,则发送两字节数据同为0XFFH给PC;对于PC要求读取特定节点的命令,单片机以0X10H作为应答起始,并以两字节同为0X00H表示成功,两字节同为0XFFH表示失败。
数据帧为接口卡从总线上读到的数据,因为总线上数据有标准帧、远程帧等之分,而且每个帧中装载的数据长度未知,所以数据帧的长度不定,其传输方向也为单片机到PC,起始字节为0X22H。SJA1000每次接收到有效数据后会让单片机产生接收中断,单片机则在中断处理中将数据首先读入到RAM中暂时存放,然后计算其数据长度和校验和,将数据封装成帧,然后将帧通过串口送给PC处理和显示。
各种类型的帧以0X33H作为帧结束标识。校验和字节用来保证数据的准确性,单片机在发送数据前将各个字节相加,并将结果填人校验字节。PC端接收到数据后,重新计算校验和,并与单片机发送的校验和相比较,相同则正确接收,否则要求单片机重新发送。
2.2 协议的透明性分析
在同步传输数据的过程中,帧的起始字节和结束字节是非常重要的,它能够保证数据帧的准确性。但因为这两个字节的存在,同时也引出了另一个待解决的问题,就是当数据场中出现了与起始字节相同的数据时,很有可能会导致PC端把它看成一个新的帧起始,从而导致数据的处理和显示错误,这也就是数据传输的透明性问题。针对串口的数据传输,有一种比较好的解决方案。该方法将数据转换成为ASCII字符来进行传送,就是将每个字节的数据进行拆分,将一个16进制的字节拆分成两个字节,如5AH,5BH,5CH,…,可以拆分为50H,0AH,50H,0BH,50H,OCH,…,PC机再接收到数据后,再将数据进行两两相或组合。这样,只需要32个字节就可以组合成为00H~0FFH中任一个数据。但这种办法的缺点也是显而易见的,应用它所发送的有效数据量是正常发送的两倍,对于串口这种传输速度不高的通信介质而言,在数据量较大的情况下,不是一种可取的方法。
在该接口卡中作者采取了另一种转义字符的方法。首先定义一个转义字符标识OXDBH。对于CAN总线而言,其每个帧的最大数据长度为8,即使将CAN的帧信息和识别码全部当作数据发送,其长度最大也只有13 B。这样可以肯定的是,正常情况下数据帧中数据长度字节的高4位必然为0。因此在数据发送之前,首先检查该数据中是否有与起始字节0X22H、结束字节0X33H和转义标识0XDBH相同的数据,如果没有,则正常发送;如果有,则检测出与这两个字节相同数据的个数,并将该个数填充到数据长度字节的高4位中;同时,将这些数据前添加转义字符标识,并将该数据进行转义。如数据0X22H。0X33H,0XDBH…,则转义成0XDBH。0XD2H。0XDBH,0XD3H,0XDBH,0XDDH…。PC机在接收到数据帧后,首先检查数据长度字节,看其高4位是否为0,如果为0,说明该数据组不存在转义字符,可以直接处理;如果为N。则表明数据组中存在N个转义字符,并且每个转义字符都以0XDB开始,需要首先将它们重新修改回原始数据。相比而言,这种办法有很好的稳定性和接口利用率,其数据流量也不会很高。