您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > Modbus协议与现场总线解析
3.1Modbus协议Modbus是MODICON公司于1979年开发的一种通讯协议。它是一种在工业领域被广为应用的真正开放、标准的网络通讯协议,已经成为一种电子控制器的通用语言,通过此协议控制器之间可以通讯,已成为一种工业标准。不同厂商生产的控制设备通过Modbus协议可以连成通讯网络,在PLC、变频器、电器设备及自动化仪表等领域都广泛应用Modbus协议。Modbus是链路层的主/从协议,采用请求响---应方式.主站发出带有从站地址的请求报文,具有该地址的从站收到该报文后发出响应报文。第三章Modbus协议与现场总线Modbus在OSI模型中所使用的层3.1.1Modbus协议的物理层1.网络结构总线式主从结构主设备:PC机,PLC从设备:PLC,智能仪表一个主站可有1—253个从站,从站之间不能相互通讯。2.通讯方式(a)一对一:主设备可以和从设备通讯,从设备响应。(b)一对N(广播):主设备对N个从设备,从设备无响应。0地址表示广播地址。3.物理层支持RS-485、RS-232C。CRLF0D0ACOLON3A3.1.2Modbus协议的帧格式Modbus有两种格式:ASCII格式;RTU格式1.ASCII码帧格式(用ASCII表示数据)(1).字节格式(2).数据表示方法地址:21表示ASCII码32H,31H(:)(2)说明:a.地址域:从设备地址0-253,地址0为广播地址。b.功能域:代码范围1-255,命令从设备执行哪些功能(如读测量值,读开关量状态)c.数据域:(两部分内容)主设备到从设备:变量起始地址、变量个数。从设备到主设备:字节数n、数据n。d.检错:CRC-16,生成多项式Y=X^16+X^15+X^2+1。2.RTU格式(用二进制数表示数据)(1)RTU帧格式3.1.3ModBus功能码1.Modbus功能码2.功能码3:读取在一个或多个保持寄存器中取得当前的二进制值该功能码主要用于读取设备参数例:主机命令:读6BH开始的3个寄存器内容从机响应:回传6个字节数据说明(1)应用层:寄存器中存储的内容用户定义。(2)寄存器地址与寄存器:寄存器号减1为寄存器地址3.功能码4:读取一个或多个输入寄存器值主要用于读取设备测量数据从寄存器8开始读一个寄存器值4.功能6:写单个寄存器例:从寄存器地址1开始,写一个寄存器值03寄存器地址:0001H寄存器:0002H5.功能码16:写多个寄存器主机从01H地址开始写2个寄存器从机响应主机3.1.4应用举例题:有某地址为1的从设备,其变量定义如下:例1:主设备用3号命令寻址地址为1的从设备,读取寄存器地址为0000H的量程.主设备命令帧从设备响应帧变量定义主机请求从机响应量程(参数)寄存器地址0000H测量值0002H字节数2byte2byte主从地址功能码变量地址高变量数高CRC校验01H03H00H00H变量数低地址功能码01H03H字节数02H数据103HCRC校验**流量=3E8H=1000变量地址低00H01H**数据2E8H例2:主设备用4号命令寻址地为1的从设备,读取地址为0002H的测量值01H04H0002H0001H##地址功能码变量地址变量数CRC校验地址功能码字节数数据1数据2CRCCRC01H04H02H03H20H****从设备响应主设备命令帧测量值=320H=800问题:测量值有小数和正负怎么办?3.1.5CRC-16校验1.说明:(1)CRC校验=地址码+功能码+数据(2)生成多项式G(x)=X^16+X^15+X^2+1(11000000000000101)(3)生成多项式最高位总是1,所以实际中的生成多项式为1000000000000101(4)Modbus采用逆序生成多项式1010000000000001(5)CRC本质:移位异,是1与生成多项式或和2:CRC方法0211073.CRC计算程序(标准程序)数据指针数据长度CRC低位表CRC高位表auchCRCHi[0xFD]auchCRCHi[0x39]auchCRCLo[0xFD]auchCRCLo[0x39]CRCLo111111111ST00000010XORuIndex11111101auchCRCHi[0xFD]=0xC1uchCRCHi11111111XOR11000001uchCRCLo00111110uchCRCHi=auchCRCLo[0xFD]100000012ST00000111uchCRCLo00111110XORuIndex00111001auchCRCH[0x39]=0xC0uchCRCHi100000001110000000XORuchCRCLo010000001uchCRCHi=auchCRCLo[0x39]=0x12结果0x1241例:x[2]={0x02,0x07};CRC_n=CRC16(x,2);压3.2Modbus协议通讯从站软件设计(1).主站使用Modbus04号命令采集从站测量数据(2).寄存器应用层定义3.2.1从站软件设计要求寄存器内容压力温度液位流量2000HModbus寄存器实际设计考虑问题(1).Modbus命令帧结束判定方法,(2).帧间隔控制方法(3)如何解决通讯数据串位及数据残缺等异常情况对通讯的影响.3.2.2从站软件设计内容2004H2008H200CH寄存器地址1.接收数据(1)串口接收数据(2)根据主站MODUBS命令读寄存器。(2)发送数据将所读寄存器发送出去主站一次可能读一个寄存器,也可能读多个寄存器。3.2.3从站接收命令帧方法(1).设置一个定时器,定时3.5char时间(2).每接收一个数据,启动定时器定时.(3).定时时间到,说明在3.5char时间里没有通讯数据,表明帧结束,在定时中断服务程序中处理Modbus命令.定时中断帧结束,读命令回答数据启动定时器3.5char地址功能码变量地址变量数CRC校验主站发给从站读寄存器命令8byte,从站3.5char后回答数据如何确定MODBUS帧结束?帧间隔3.5char定时方法ICR1(触发寄存器)计数器PWM输出3.2.4从站程序设计(AVRMEGA64CPU)voidmain(void){unsignedchari=0;unsignedlongnum=0;OutSet1480;/*R485接收方向*/Set1480Rxd;Delays(100);_CLI();/*关中断UartInit();/*UART初始化TimeDelay=OscF*10/BaudRate0;/*根据波特率设置定时时间*/TCCR1B=(1CS11)|(1WGM12)|(1WGM13);/*设置3.5char定时器*/TIM16_WriteTCNT1(0x0000);/*清计数器TIM16_WriteICR1(TimeDelay);/*设计数触发值_SEI();/*开中断WDTCR=(1WDCE)|(1WDE);/*看门狗允许*/WDTCR=(1WDP2)|(1WDP1)|(1WDP0);/*看门狗2.2秒复位*/WDTCR=(1WDCE)|(1WDE);OpenINT0();while(1){num++;......./*处理数据采集等功能*/if(num=1000)/*若没有通讯,则定时初始化串口*/{num=0;/*防止通讯死机*/CloseINT0();/*关通讯中断*/UartInit();/*初始化串口*/OutSet1480;/*设置I/O口为输出方向*/Set1480Rxd;/*设置RS485接收方向控制*/OpenINT0();/*开通讯中断*/}}}(1).主程序voidUartInit(void){/*设置通讯波特率*/UBRR0L=(OscF/16/(BaudRate0+1))%256;UBRR0H=(OscF/16/(BaudRate0+1))/256;/*Uart0发送和接收引脚使能*/UCSR0B=(1RXEN0)|(1TXEN0);/*设置帧格式:8个数据位,1个停止位*/UCSR0C=(1URSEL0)|(1UCSZ01)|(1UCSZ00);UCSR0A=(1RXC0)|(1TXC0)|(1UDRE0)|(1FE0);}#pragmainterrupt_handlerusart0:iv_USART0_RXCvoidusart0(void){unsignedcharcombuf;combuf=UDR0;/*读通讯数据*/TIM16_WriteTCNT1(0x0000);/*清定时时间常数*/TIM16_WriteICR1(TimeDelay);/*设置定时3.5char时间常数*/TIFR|=(1ICF1);/*定时记数器加,上限捕捉*/TIMSK|=(1TICIE1);/*启动定时中断*/ReciveBuff_485[ReceiveNum_485++]=combuf;/*存储通讯数据*/}(2).串口初始化(3).UART0中断接收(只接收一个字节数据)#pragmainterrupt_handlertimedelay:iv_TIMER1_CAPTvoidtimedelay(void){unsignedinti,x;unsignedintlen;unsignedintstart;unsignedintCheckSum;unsignedintbuff[2];if(ReceiveNum_485==8){TIMSK&=~(1TICIE1);ReceiveNum_485=0;if(ReciveBuff_485[0]!=Address)return;/*非本站地址返回*/if(ReciveBuff_485[1]!=0x04)return;/*非04命令返回*/CheckSum=CRC16(ReciveBuff_485,6);/*计算接收命令的CRC*/CRC16Value.OTT[1]=ReciveBuff_485[6];/*CRC16Value.OTT[0]=ReciveBuff_485[7];if(CheckSum!=CRC16Value.TTO)return;/*CRC错返回*/len=ReciveBuff_485[4]*256+ReciveBuff_485[5];/*寄存器长度*/buff[0]=ReciveBuff_485[2];buff[1]=ReciveBuff_485[3];start=buff[0]*256+buff[1];/*寄存器启始地址*/start=start*2;/*BYTE地址*/(D).定时3.5char中断服务,帧结束unionIntToChar{U8OTT[2];U16TTO;};SendBuff_485[0]=Address;SendBuff_485[1]=0x04;SendBuff_485[2]=len*2;/*字节数*/for(i=0;i(len*2);i++){x=start+i;SendBuff_485[3+i]=LMAG_Cache[x];/*取数据*/}CheckSum=CRC16(SendBuff_485,(len*2)+3);/*计算CRC*/CRC16Value.TTO=CheckSum;SendBuff_485[(len*2)+3]=CRC16Value.OTT[1];SendBuff_485[(len*2)+4]=CRC16Value.OTT[0];SendLen_485=(len*2)+5;/*发送字节长度*/SendNum_485=0;UCSR0A|=(1TXC0);/*设置发送完成中断*/UCSR0A|=(1UDRE0);/*设置发送寄存器空中断*/UCSR0B|=(1UDRIE0);/*允许发送寄存器空中断*/}ReceiveNum_485=0;TIMSK&=~(1TICIE1);/*关闭3.5char定时中断*/}#pragmainterrupt_handl
本文标题:Modbus协议与现场总线解析
链接地址:https://www.777doc.com/doc-2306699 .html