----为了避免这种情况的发生,可以用文本来传送二进制数据。通过以16进制ASCII码的格式描述数据,每个二进制的字节都可以表示成一对ASCII编码,这对编码表示这个字节的两个16进制字符。这种格式可以表示任何的数值,仅仅使用ASCII代码的30H到39H(表示0到9)和41H到46H(表示A到F)。ASCII码的其余部分可以用作控制字(起始标志、结束标志、指令类型等)。这样,数据中的47H以ASCII码的形式进行传送就变成了34H 37H 两个字节,从而避免了PLC因接收到数据中的47H而停止接收的错误。
PLC程序执行过程
----PLC在第一次扫描时执行初始化子程序,对端口及RCV指令进行初始化。初始化完成后,运行RCV指令使端口处于接受状态。
----RCV会将以"g"开头"G"结尾的指令保存到接收缓冲区,并同时产生接收完成中断。
----RCVcomplete中断服务程序用来处理接收完成中断事件,它会将接收缓冲区中的十六进制ASCII码还原成数据并保存,同时置位Verify子程序的触发条件(M0.1)。 ----Verify子程序首先复位本身的触发条件以防止子程序被重复调用,然后求出接收缓冲区中指令的BCC校验码并与指令中的BCC校验码进行比对。如果相等则置BCC码校验正确的标志位(M0.0)为1;如果指令格式正确(指令的结束标志在接收缓冲区中特定的位置VB133)而BCC码不相等,则发送代表BCC校验码错误的反馈信息;如果指令格式不正确(VB133中不是指令的结束标志),则返回代表指令格式错误的反馈信息。
----Read子程序的触发条件为:指令中的站地址与本机站地址相符、指令类型为读指令、BCC检验码正确。当条件满足时,Read子程序被执行。Read子程序首先禁止RCV,然后将指令所要读取的数据转换成十六进制ASCII码并写入发送缓冲区、计算BCC检验码、最后发送反馈信息。
----Write子程序的触发条件为:指令中的站地址与本机站地址相符、指令类型为写指令、BCC检验码正确。当条件满足时,Write子程序被执行。Write子程序首先禁止RCV,然后将指令中的数据写入目标寄存器,最后发送代表写入正确的反馈信息。
----PLC每接到一条指令后都会发送一条反馈信息,当反馈信息发送完成时,会产生发送完成中断,XMTcomplete中断服务程序用来处理发送完成中断事件。在XMTcomplete中断服务程序中所要执行的操作包括:复位BCC校验码正确的标志位(M0.0);允许RCV;bcc码寄存器清零;重新装入用于计算BCC校验码的地址指针;接收缓冲区中存放指令结束字符的字节VB133清零(用来判断下一条指令格式是否正确)。
PLC寄存器地址分配
----此程序占用PLC寄存器的VB100-VB199,内部继电器占用M0.0和M0.1。
主程序:
NETWORK 1
LD SM0.1 //第一次扫描调用初始化子程序
CALL initialize
NETWORK 2
LDB= VB134, VB199 //指令中的站地址与本机站地址相符
AB= VB102, 5 //指令类型为读指令
A M0.0 //BCC码校验正确
CALL Read //调用读子程序
NETWORK 3
LDB= VB134, VB199 //指令中的站地址与本机站地址相符
AB= VB102, 6 //指令类型为写指令
A M0.0 //BCC码校验正确
CALL Write //调用写子程序
NETWORK 4
LD M0.1 //指令接收完成后调用BCC码校验子程序
CALL Verify
NETWORK 5
LD SM4.5 //当端口空闲时启动RCV
RCV VB100, 0
Read子程序:
NETWORK 1
LD SM0.0 //停止端口0的接收
R SM87.7, 1
R M0.0, 1
RCV VB100, 0
NETWORK 2
LD SM0.0 //将数据写入发送缓冲区
MOVB 103, VB154
MOVB 1, VB155
HTA *VD135, VB156, 16
MOVB 26, VB174
MOVB 21, VB153
NETWORK 3
LD SM0.0 //计算BCC校验码
FOR VW177, +1, +16
NETWORK 4
LD SM0.0
XORB *VD181, VB180
NETWORK 5
LD SM0.0
INCD VD181
NETWORK 6
NEXT
NETWORK 7
LD SM0.0
HTA VB180, VB172, 2 //BCC校验码写入发送缓冲区
NETWORK 8
LD SM4.5 //发送反馈信息
XMT VB153, 0
Write子程序:
NETWORK 1
LD SM0.0 //停止端口0的接收
R SM87.7, 1
R M0.0, 1
RCV VB100, 0
NETWORK 2
LD SM0.0 //装入要写如数据源的地址指针
MOVD &VB115, VD145
NETWORK 3
LD SM0.0 //写入数据
ATH *VD145, *VD135, VB139
NETWORK 4
LD SM0.0 //指令执行的反馈信息写入发送缓冲区
MOVB 21, VB153
MOVB 103, VB154
MOVB 2, VB155
MOVB 26, VB174
NETWORK 5
LD SM4.5 //发送指令执行的反馈信息
XMT VB153, 0
Verify子程序:
NETWORK 1
LD SM0.0
R M0.1, 1 //复位verify子程序的执行条件
NETWORK 2
LD SM0.0 //计算BCC码
FOR VW175, +1, +29
NETWORK 3
LD SM0.0
XORB *VD149, VB179
NETWORK 4
LD SM0.0
INCD VD149
NETWORK 5
NEXT
NETWORK 6
LDB= VB179, VB140 //当BCC码校验正确时,M0.0置1
AB= VB133, 71
S M0.0, 1
NETWORK 7
LDB= VB133, 71 //BCC码错误时发送反馈信息
AB<> VB179, VB140
MOVB 21, VB153
MOVB 103, VB154
MOVB 3, VB155
MOVB 26, VB174
R SM87.7, 1
RCV VB100, 0
XMT VB153, 0
NETWORK 8
LDB<> VB133, 71 //指令格式错误或RCV超时时发送反馈信息
MOVB 21, VB153
MOVB 103, VB154
MOVB 4, VB155
MOVB 26, VB174
R SM87.7, 1
RCV VB100, 0
XMT VB153, 0
Initialize子程序:
NETWORK 1
LD SM0.0
MOVB 9, SMB30 //0口"9600,N,8,1"
NETWORK 2
LD SM0.0 //RCV指令初始化
MOVB 16#EC, SMB87
MOVB 103, SMB88
MOVB 71, SMB89
MOVB +1000, SMW92
MOVB 35, SMB94
R SM87.2, 1
NETWORK 3
LD SM0.0
ATCH RCVcomplete, 23 //连接口0接收完成的中断
NETWORK 4
LD SM0.0
ATCH XMTcomplete, 9 //连接口0发送完成的中断
NETWORK 5
LD SM0.0
ENI //中断允许
NETWORK 6
LD SM0.0
MOVB 2, VB199 //将本机站地址装入寄存器
NETWORK 7
LD SM0.0
MOVB &VB102, VD149 //装入地址指针
MOVB 0, VB179 //BCC码寄存器清零
MOVB &VB156, VD181 //装入地址指针
MOVB 0, VB180 //BCC码寄存器清零
RCVcomplete中断程序
NETWORK 1
LD SM0.0
ATH VB103, VB134, 2 //指令译码(ASCII码到十六进制)
ATH VB105, VB135, 8
ATH VB113, VB139, 2
ATH VB131, VB140, 2
S M0.1, 1 //置位Verify子程序的触发条件
MOVB 0, VB179 //BCC码寄存器清零
MOVD &VB102, VD149 //装入地址指针
XMTcomplete中断程序
NETWORK 1
LD SM0.0
R M0.0, 1 //复位BCC校验码正确的标志位
S SM87.7, 1 //允许口0进行接收
MOVB 0, VB179 //BCC校验码寄存器清零
MOVB 0, VB180 //BCC校验码寄存器清零
MOVD &VB102, VD149 //重新装入地址指针
MOVD &VB156, VD181
MOVB 0, VB133 //接收缓冲区中存放指令结束字符的字节