教案-18第章rs485通信和modbus协议_第1页
教案-18第章rs485通信和modbus协议_第2页
教案-18第章rs485通信和modbus协议_第3页
教案-18第章rs485通信和modbus协议_第4页
教案-18第章rs485通信和modbus协议_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

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

文档简介

18RS485通信和Modbus协式进行。最初采用的方式是RS232接口,由于工业现场比较复杂,各RS232接口只能实现点对点通信,不具备联网功能,最大传输距离也只能达到几RS485则解决了这些问题,数据信号采用1200米,并且允许多个收发设备接到同一条总线上。随着工业应用通信越来越多,1979年施Modbus协议,现在工业中使用RS485通信场合很多都采用Modbus协议本节课要讲解一下RS485通信和Modbus协议。单单使用一块KST-51开发板是不能够进行RS485实验的,应很多同学的要485通信模块。RS485通RS485RS232RS2321、接口的信号电平值较高,达到十几V,容易损坏接口电路的,而且TTL电平不兼容,因此和单片机电路接起来的话必须加转换电路。2Kb/s传输容易产生干扰,并且性能也比较弱。451、在讲A/D的时候,讲过差分信号输入的概念,同时也介绍了差分输RS485ABD+和D-来表示。逻辑“1”以两线之间的电压差为+(0.2~6)V表示,逻辑“0”以两线间的电压差为-(0.2~6)V来表示,是一种典型的差分通信。2、RS48510Mb/s有的RS485来看,有可以挂32、64、128、256等不同个设备的驱动器。RS485的接口非常简单RS232所使用的MAX232是类似的只需要一个RS485转换器,就可以直接和单片机的UART串行接口连接起来,并且完UARTRS485RS485类的很多,这节课以MAX485为例讲解RS485通信,如18-1图18- MAX485硬件接。MAX485是美信()推出的一款常用RS485转换器。其中5脚和8脚是电源引脚,67485AB14脚分别接到单片机的RXD和TXD引脚上,直接使用单片机UART进行数据接收和发送。而2脚和3脚就是方向引脚了,其中2脚是低电平使能,3脚是高电平使能输出驱动器把这两个引脚连到一起,平时不发送数据的时候,保持这两个引脚是低电平,让MAX485处于接收状态,当需要发送数据的时候,RS485的性能,需要在靠近MAX485的A和B引脚之间并接一个电阻,1001K都可以。。在这里还要介绍一下如何使用KST-51单片机开发板进行扩展实验。的开发板只能把基本的功能给做出来提供实验练习但是学习32个插针,这32个插针就是把单片机的32个IO引脚全部都引出来了。在原理图上体现出来的就是的J4、J5、J6、J7这4个器件,如图18-2所示。图18- 单片机扩展接32个IO口不是所有的IOP3.2、P3.4、P3.6引脚,这三个引脚是不可用的。比如P3.2这个引脚,如果用来扩展,发送的信号如果和DS18B20DS18B203IO口29IO口,都可以使用杜邦线接上插针,扩展出来使用。当然了,IO口应用于扩展功能了,板子上的相应的功能就实现不了了,也,在进行RS485实验中,通信用的引脚必须是P3.0和P3.1,此外还有一个方向控制引脚,使用杜邦线将其连接到P1.7上去。RS485的另外一端,大家可以使用一个USB转485模块绞线把开发板和模块上的A和B分别对应连起来,USB那头电脑,然后就可以进行通信了。,13章的实用串口通信的方法和程序后,做这种串口通信的方法就很简单了基本是一致的使用实用串口通信的思路做了一个简单的程序,485UartWrite()485方向引RITI就已经置位并且马上进入中断(如果中断使能的话)函数了,接收的时SBUF写入一个字节数据时,UART硬件会在完成上一个停止位的发送后,再开始新字节的发送,485485重新处于接收状态时就有问题了,因为这时候最后的UartWrite()函数内DelayX10us(5)这个操作,这是人为的增加了延时50us,这50us的时间正好让#include<reg52.h>#includesbitRS485_DIR=P1^7;//RS485==令 cntRxd= pdatabufRxd[40]; ConfigUART(unsignedint {RS485_DIR=0;//RS485设置为接收方向 =0x50; //配置串口为模式1 &=0x0F; //清零T1的控制位 |=0x20; //配置T1为模式2TH1=256-(11059200/12/32)/ TL1=TH1; ET1=0; //T1中断 = TR1= } UartRead(unsignedchar *buf,unsigned charlen)//串口数据函数,数据接收指针buf,数据长度len,返回值为实际到的数据长度{ charif >cntRxd)//长度大于接收到的数据长度时{len=cntRxd;//长度设置为实际接收到的数据长}for(i=0;i<len;i++){ =bufRxd[i];} = //返回实际长} DelayX10us(unsignedchar //延时函数,延时时间{do}

}while(-- UartWrite(unsignedchar*buf,unsigned charlen)//串口数据写入函数,buflen{RS485_DIR= while(len {flagOnceTxd=0; =*buf;while} RS485_DIR=0; //RS485设置为接收} //串口驱动函数,检测接收到令并执行相应动{ charlen; charbuf[30];if //有命令到达时,处理该命{}

=len=UartRead(buf,sizeof(buf)-2);//将接收到令 ='\r'; ='\n';UartWrite(buf,} UartRxMonitor(unsigned //串口接收函{ unsignedcharcntbkp =0; unsignedcharidletmr=if(cntRxd> //接收计数器大于零时,总线空闲时{

if(cntbkp!= {cntbkp=cntRxd;idletmr=0;

{

if(idletmr< {idletmr+=if >= 30ms}}}{

{cmdArrived=1;} =}} InterruptUART()interrupt {if {RI= if(cntRxd<sizeof(bufRxd)){bufRxd[cntRxd++]=SBUF;}}if {TI=0; flagOnceTxd=1; }} T0RH= T0RL= ConfigTimer0(unsignedintConfigUART(unsignedintUartRxMonitor(unsignedchar {EA= ConfigUART(9600);{}} ConfigTimer0(unsignedint { longtmp=11059200/12; tmp=(tmp*ms)/ tmp=65536- tmp=tmp+ =>>=TMOD&=0xF0;//清零T0的控制位TMOD|=0x01;T01TH0=T0RH;T0重载值TL0=T0RL;ET0= TR0= } InterruptTimer0()interrupt {TH0=T0RH; TL0=T0RL; }现在看这种串口程序是不是感觉很简单了呢?串口通信程 反复杂的东西,现在就会感到简单了。的程序模块用的是COM4,而USB转485虚拟的是COM5,通信的时候用的是COM5口,如图18-3所示。图18- RS485串行通Modbus通信协议介UART、I2C、SPI这些通信协议,都是最底层的协议,是“位”级别的协议。而在学3章实用串口通信程序的时候,通过串口发给单片机三条指令,让单片机做了三件不同的事情,分别是"buzzon"、 off"、和"showstr"。随着系统复杂性的增们希望可以实现更多的指令。而指令越来越多,带来的就是非常杂乱无章,尤其是这个人喜欢 off"而另外一个人喜欢写成"onbuzz""off 导致不同开发写出来的代码指令不兼容不同厂家的产品不能挂到一条总线UART、I2C、SPI通信协议不同的是,这种通信协议是字节级别的,叫做应用层Modbus协议。Modbus协议特Modbus业标准。有了它,不同厂商生产的控制设备可以连成工业网络,进行集中。络进行通信的。它描述了控制器请求其他设备的过程,如何回应来自其他设在进行多机通信的时候,Modbus协议规定每个控制器必须要知道他们的设备地Modbus协议发出。Modbus(PLC、人机界面、控制面板、驱动程序、输入输出设备)都能使用Modbus协议来启动操作一些网关允许在几种使用Modbus协议的总线或网络之间的通信如图18-418-4Modbus,Modbus协议的整体架构和格式比较复杂和庞大,在的课程里重点,1.2.2RTU协议帧数Modbus有两种通信传输方式,一种是ASCII模式,一种是RTU模式。由于ASCII模式的数据字节是7bit数据位,51单片机无法实现,而且应用也相对较一条典型的RTU数据帧如图18-5所示。18-5RTU,和实用串口通信程序类似一次发送的数据帧必须是作为续的数据流进行传输。在实用串口通信程序中采用的方法是定义30ms,如果Modbus的RTU模式规定不同数据帧之间的间隔是3.5个字节通信时间以一帧数据的延续。这将会导致一个错误,因此大家看RTU数据帧最后还有16bitCRC校验。,起始位和结束符:图18-5上代表的是一个数据帧,前后都至少有3.5个字节3.5个字节以上的时间,而真正有意义的第一个字节是设备地址。如果地址是0x00,则认为是一个广播命令,就是所有的从机设备都要执行的指功能代码:在第二个字节功能代码字节中,Modbus规定了部分功能代码,去,甚至都不用去看,直到你有用到的那天再过来查这个表格即可,如表18-1所示。18-1Modbus取得一组逻辑线圈的当前状态取得一组开关输入的当前状态取得8个线圈的通断状态这8短报文适宜于迅速状回送校把校验报文送从机,以对通信处PC辑任务,仅在含有功能码9ModBus事务 484 可使主机模拟编程器功能修改PC 484定期控询该从机是否已完成其程序操MICROPC辑通用参数显示扩展器文件中的数据信写入通用参数把通用参数写入扩展文件,或修留作作数据:跟在功能代码后边的是n8bit的数据。这个n值的到底是多少,是能码是0x03,也就是读保持寄存器,那么主机发送数据n2N*n的组成部2N*2N*18-6所示。18-6接收到数据后同样会把前边的字节进行CRC计算计算完了再和发过来的CRC2个停止位(无校验位时)。Modbus多机通信例手,比较方便的下发多个字节的数据,如图18-7所示。先来就图中的设置18-7ModbusUSB485COM59600,无校验位,8位,11。写寄存器的时候,如果要把01写到一个地址是0000的寄存器地址里,点一下“写入”,就会出现发送指令:010600000001480A。来分析一下0000表示的是要写入的寄存器的地址,0001就是要写入的数据,480A就是CRC这是自动算出来了而根据Modbus协议当写寄存器的时候,从机成功完成该指令的操作后,会把主机发送的指令直接返回的调试精灵会接收到这样一帧数据:010600000001480A。,假如现在要从寄存器地址0002开始寄存器,并且的数量是2个。点一下“读出”,就会出现发送指令:01030002000265CB01是设备地址,03是功能码,代表写寄存器这个功能,0002就是读寄存器的起始地到的数据是:01030400000000FA3301是设备地址,0300的寄存器的数据,而FA33就是CRC校验了似乎越来越了,所谓的Modbus这种通信协议,无非就是主机下发了不Modbus功能码那么多相应的功能在程序中定义了一个数组regGroup[5],相当于5个寄存器,此外又定义了第6个寄存器,控制蜂鸣器,通过下发不同的。就是数组regGroup对应的值。其中地址0x00000x0004对应的就是regGroup数组中的元素,写入的同时把数字又显示到的LCD1602液晶上,而0x00050x00,蜂鸣器就不响,写入任何其他数字,蜂鸣器就报警单片机的主要工作也就是解析串口接收的数据执行不同操作,也就是主RS485.C这个文件中了。#include<reg52.h>#includesbitRS485_DIR=P1^7;//RS485bitflagOnceTxd= bitcmdArrived= //命令到达标志,即接收到上位机下发 cntRxd= pdatabufRxd[40]; bit LcdShowStr(unsignedchar x,unsigned chary,constunsignedchar intGetCRC16(unsigned unsigned ConfigUART(unsignedint {RS485_DIR=0;//RS485设置为接收方向 =0x50; //配置串口为模式1 &=0x0F; //清零T1的控制位 |=0x20; //配置T1为模式2TH1=256-(11059200/12/32)/ TL1=TH1; ET1=0; //T1中断 = TR1= } UartRead(unsignedchar *buf,unsigned charlen)//串口数据函数,数据接收指针buf,数据长度len,返回值为实际到的数据长度{ charif >cntRxd)//长度大于接收到的数据长度时{len=cntRxd;//长度设置为实际接收到的数据长}for(i=0;i<len;i++){ =bufRxd[i];} = //返回实际长} DelayX10us(unsignedchar //延时函数,延时时间{do}while(--} UartWrite(unsignedchar*buf,unsigned charlen)//串口数据写入函数,buflen{RS485_DIR= while(len {flagOnceTxd=0; =*buf;while} RS485_DIR=0; //RS485设置为接收} //串口驱动函数,检测接收到令并执行相应动{ charcrch,crcl;if //有命令到达时,处理该命{

=len=UartRead(buf,sizeof(buf));//将接收到令到if(buf[0]== {crc=GetCRC16(buf,len-2);CRCcrch=crc>>8;crcl=crc&0xFF;if((buf[len-2]==crch)&&(buf[len-1]==)CRC{

{ //一个或连续的寄存if((buf[2]==0x00)&&(buf[3]<=0x05)) 0x0000~0x0005{if(buf[3]<={i=cnt//提取待的寄存器数=//数据的字节数,为寄存器数*2,因Modbus定义的寄存器为16len{++]= ++]=regGroup[i++];

}}

//地址0x05{//数据的字节;

=2; = =

}}

len=功能码最置

{buf[1]=0x83; buf[2]= len=3;} if((buf[2]==0x00)&&(buf[3]<=0x05)) 0x0000~0x0005{if(buf[3]<={ >>4;//显示到液晶上=cnt-0xA+=cnt+'0'; &0x0F;

i=buf[3];regGroup[i]=cnt=regGrouif >=cnt=regGrouif >==cnt-0xA+=cnt+

;0,

='\0'} }

//地址0x05{ }len-=2;-功能码最置

{buf[1]= buf[2]=0x02; len=3;}

|=0x80; = //设置len=3;}crc=GetCRC16(buf,len);//计算CRC校验值 =crc>>8; //CRC高字节 =crc&0xFF; //CRC低字节 }}}} UartRxMonitor(unsigned //串口接收函{ unsignedcharcntbkp =0; unsignedcharidletmr=if(cntRxd> //接收计数器大于零时,总线空闲时{

if(cntbkp!= {cntbkp=cntRxd;idletmr=0;

{

if(idletmr< {idletmr+=if >= //空闲时间超过4{}}}}{

cmdArrived=1; =}} InterruptUART()interrupt {if {RI= if(cntRxd<sizeof(bufRxd)){bufRxd[cntRxd++]=SBUF;}}if {TI=0; flagOnceTxd=1; }} #define sbitLCD1602_RS=P1^0;sbitLCD1602_RW=P1^1;sbitLCD1602_E={ =={=LCD1602_E=sta=LCD1602_DB;//状态}while(sta=0} {=====} LcdWriteDat(unsignedchar {=====} LcdShowStr(unsignedcharx, y,constunsigned { charif(y== =0x00+x;0x00

=0x40+x;0x40LcdWriteCmd(addr|0x80);while(*str!= 符{}} {

温馨提示

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

评论

0/150

提交评论