Modbus常用功能程序的设计
笔者采用单片机作为主机,在单片机上编写程序实现单片机与PLC之间的通讯。由单片机向PLC发出命令信息,PLC自动作出回应。PLC通过单片机的串行通讯口通讯,程序用C51实现。程序的子函数及其功能:
(1)串口初始化
voidProtocolInit(void)
函数功能:串口设置为异步通讯方式1(起始位1位,数据位8位,停止位1位);定时/计数器1设置为波特率发生器,通讯速率9600bps;开串行中断,并把串行中断设置为高优先级。
(2)CRC简单函数
unsignedcharCrc16(unsignedchar*puchMsg,unsignedcharusDataLen)
函数功能:先调入一值是全“1”的16位寄存器,然后调用一过程将消息中连续的8位字节各当前寄存器中的值进行处理。每个8位字符都单独和寄存器内容相或(OR),结果向最低有效位方向移动,最高有效位以0填充。LSB被提取出来检测,如果LSB为1,寄存器单独和预置的值或一下,如果LSB为0,则不进行。整个过程要重复8次。在最后一位(第8位)完成后,下一个8位字节又单独和寄存器的当前值相或。最终寄存器中的值,是消息中所有的字节都执行之后的CRC值。
(3)初始化变量
voidInitvar(void)
函数功能:初始化所有过程变量。
(4)串行中断服务程序
voidProtocolSerialProcess(void)interrupt4using2
函数功能:发送中断发送主机形成的命令数组,发送完后置标志位;接收中断接收PLC返回的响应数组,存入接收数组,并置标志位,且假设响应正确,留待主机处理。
(5)读N个位变量(线圈)
voidProtocolRead_bit(unsignedcharDeviceAddr/*PLC局号*/,unsignedcharRegType/*寄存器类型*/,unsignedintBitAddr/*起始地址*/,unsignedcharSubAddr/*子地址*/,unsignedintBitNum/*位数*/)
函数功能:根据函数参数,形成读N个位变量的命令数组,启动发送。等待发送完并接收完(如超时未接收完则重新发送)。分析接收数组:正确,保存读取的数据;错误,重新发送。
(6)写一个位变量
voidProtocolSetBit(unsignedcharDeviceAddr/*PLC局号*/,unsignedcharRegType/*寄存器类型*/,unsignedintBitAddr/*地址*/,unsignedcharSubAddr/*子地址*/,unsignedi
ntClrSet/*写值“1”或“0”*/)
函数功能:根据函数参数,形成置某位变量为“1”或“0”的命令数组,启动发送。等待发送完并接收完(如超时未接收完则重新发送)。分析接收数组:正确,返回;错误,重新发送。
(7)读N个字节变量
voidProtocolReadByte(unsignedcharDeviceAddr/*PLC局号*/,unsignedcharRegType/*寄存器类型*/,unsignedintRegAddr/*起始地址*/,unsignedcharSubAddr/*子地址*/,unsignedintRegNum/*个数*/)
函数功能:根据函数参数,形成读N个字节变量的命令数组,启动发送。等待发送完并接收完(如超时未接收完则重新发送)。分析接收数组:正确,保存读取的数据;错误,重新发送。
(8)写N个字节变量
voidProtocolSetByte(unsignedcharDeviceAddr/*PLC局号*/,unsignedcharRegType/*寄存器类型*/,unsignedintRegAddr/*起始地址*/,unsignedcharSubAddr/*子地址*/,unsignedintRegNum/*个数*/)
函数功能:根据函数参数,形成写N个字变量的命令数组(要写的数从某参数数组中读取),启动发送。等待发送完并接收完(如超时未接收完则重新发送)。分析接收数组:正确,返回;错误,重新发送。