PC与三菱PLC串口通讯实例简介PC与PLC之间的通讯,按硬件接口分类主要分为串口通讯和网口通讯:RS-232CRS-422ARS-485UDP串口通讯TCP网口通讯目录010203040506三菱PLC数据操作元件三菱PLC元件首地址PLC数据类型和储存格式PC与三菱PLC串口通讯操作SCI与三菱PLC串口通讯流程程序实现1.三菱PLC数据操作对象元件1.三菱PLC操作元件分为位元件和字元件□位元件主要有:X、Y、M、S、T、C...□字元件主要有:D...2.元件说明□输入继电器”X”是可编程控制器从外部的输入开关接受信号的窗口(只能读不能写,输入寄存器必须由外部信号驱动);□输出继电器”Y”是可编程控制器驱动外部负载的窗口;□辅助继电器”M”是可编程控制器内部辅助继电器软元件;□状态”S”是可编程控制器内部状态继电器软元件;□定时器”T”是可编程控制器定时溢出软元件;□计数器”C”是可编程控制器计数溢出软元件;□数据寄存器”D”是可编程控制器保存数据的软元件(FX系列可编程控制器的数据寄存器是16位(最高位是正负位),组合2个寄存器可以处理32位(最高位是正负位)的数值)。2.三菱PLC元件首地址读取PLC主要内部元件地址如下:D:address*2+1000H;M:address*2+0100H;X:address+0080H;Y:address+00A0H;T:address+00C0H;C:address*2+01C0H;S:address*3;.............注意:address为十进制数...............例1:D0的地址为0*2+1000H算一算:1.D123的地址?2.M40的地址?3.Y13的地址?1000H+123*2=1000H+F6H=10F6H0100H+40*2=0100H+50H=0150H00A0H+13=00A0H+DH=00ADH3.PLC数据类型和储存格式数据类型表数据类型代码字长(位)输入范围二进制位bool10或1字节byte80~255字word160~65535双字Dword320~(2^32-1)字符Char8ASCII码31~3F带符号的整数int16-32768~32767带符号的双字长整型Dint32-2^31~(2^-1)实数Real32.......2.PLC数据储存格式整数(int型)三菱PLC普通数据为int型(-32768~32767)如:PLC寄存器数据格式:0、1.....32766、32767、32768、32769、65535实际数据:0、1.....32766、32767、-32768、-32767、-1读取PLC的数据为:34303030383030308000H-32768浮点数(real型32位)读取PLC的数据为:32334239464333443DFCB923H转换成二进制:001111011111110010111001001000110:判断正负数(0为正数;1为负数)01111011:指数11111001011100100100011:数值3.PLC数据类型储存格式2143213.PLC数据类型和储存格式指数:01111011b=123d123-127=-4PLC在储存数值时,第一位都为1,所以不保存在数据里,在分析数据时要加上1.数值:111111001011100100100011=1*1/(2^4)+1*1/(2^5)+1*1/(2^5)+1*1/(2^5)+1*1/(2^5)+1*1/(2^5)+0*1/(2^5)+...1*/(2^27)=0.12343.举一反三1.把12.34转换成PLC写入的数据?2.把0.79转换成PLC写入的数据?413137303435343137303344344133464.PC与PLC串口通讯操作一.对位元件和字元件状态读操作发送格式:命令格式:STXCMD0ADDLENEXTCHK解释:起始符读命令元件起始位个数停止符校验码数字代码格式:0x020x30............0x03......0x30是读操作指令;CMDD是读位元件或字元件的4位起始地址,高位先发,低位后发,以ASCII码的格式发送;LEN是一次读取位元件或字元件的字节个数,最多可以读取0xff个字节的元件,以ASCII码的格式发送;CHK是两位和校验,将CMD0,ADD,LEN,EXT三项进行和累计,将和累计的最低位两位转化为ASCII。4.PC与PLC串口通讯操作响应格式:响应信息格式:STXDATAETXCHK解释:起始符返回的数据停止符校验码数字代码格式:0x02......0x03......DATA为我们前面读取的数据(读取DATA数据时遵循低位先发,高位后发的原则,所以我们解析数据的时候需要注意高低位的转换);CHK位DATA,EXT两项和累计的最后两位转化为ASCII码。例2:读取D2寄存器的数据读取码:0x30D2的寄存器地址:2*2+1000H=1004H(0x31、0x30、0x30、0x34)个数:0x30、0x34校验码:30+31+30+30+34+30+34+03=15C(0x35、0x43)发送数据:0x020x300x310x300x300x340x300x340x030x350x43响应:0x020x320x340x420x390x460x430x330x440x030x450x340.1234练练手:1.读取D123寄存器的数据?2.读取Y13的值?023031304636303403373417...100230303041443031033739返回:023032033635000010004.PC与PLC串口通讯操作二.对位元件和字元件状态写操作发送格式:命令格式:STXCMD1ADDLENDATAEXTCHK解释:起始符写命令元件起始地址位数写入的数据停止符校验码数字代码:0x020x31.................0x03......0x31是写操作指令;DATA是待写入PLC缓冲区的数据,低位先发,高位后发,以ASCII码的形似发送;其他的和读指令一样。响应格式:返回06,表示写入成功;返回15,表示写入失败。例3:把12.23写入D10寄存器里写命令:0x31首地址:10*2+1000H=1014H(0x31、0x30、0x31、0x34)个数:0x30、0x34写入的数据:0x31、0x32、0x41、0x46、0x34、0x33、0x34、0x314.PC与PLC串口通讯操作校验码:31+31+30+31+34+30+34+31+32+41+46+34+33+34+31+03=314H(0x31、0x34)发送数据:0x020x310x310x300x310x340x300x340x310x320x410x460x340x330x340x310x030x310x34如果响应反馈是06表示写入成功,否则写入失败。练练手:1.把1.2写入寄存器D6的的数据?2.把1写入Y1寄存器中?Y1:0000000002313030413130313032034339023131303043303431324146343334310331345.SCI与三菱PLC串口通讯流程一.设置变量写入变量:首地址、写入个数、校验码、发送的数据、接受数据......读取变量:首地址、读取个数、校验码、读取的数据.....二.把操作PLC的指令赋值给变量新建一个脚本,把要操作PLC的命令赋值给发送的数据。三.发送赋值的变量给PLC1.新建一个串口算子设置发送数据的变量、设置发送数据格式:ASCII编码、字符串格式。2.配置串口参数波特率:9600停止位:1奇偶校验:偶数据位:7四.接受PLC响应的数据新建一个脚本,解析响应的数据。6.程序实现一.读数据操作1.读取设置CustomVar.Fx_Raddr=0//读取首地址小于255CustomVar.Fx_Rnum=2//读取个数小于162.转换成发送数据格式vars=0201003//02和03为十六进制·ASCII(02H:Ctrl+B;03H:Ctrl+PauseBreak)vartemp=newArray();//创建一个数组temp.length=4;//设置数组长度Ra=(CustomVar.Fx_Raddr*2).toString(16).toUpperCase();//首地址转换成十六进制字符串if(Ra.length2)//少于两位补0{Ra=0+Ra;}Rn=(CustomVar.Fx_Rnum*4).toString(16).toUpperCase();//个数转换成十六进制字符串if(Rn.length2)//少于两位补0{Rn=0+Rn;}a=Ra+Rn;6.程序实现for(i=0;i4;i++){if(parseInt(a.substr(i,1),16)=9)//0~9加48;A~F加55(0的ASCII码30H,30H转换十进制为48;{A的ASCII码41H,41H转换十进制为55)temp[i]=parseInt(a.substr(i,1),16)+48;}else{temp[i]=parseInt(a.substr(i,1),16)+55;}}a=(48+49+48+3+temp[0]+temp[1]+temp[2]+temp[3]).toString(16);//数据值累加并转换成十六进制字符CustomVar.Fx_Rchk=a.substr(a.length-2,2).toUpperCase();//取后两位作为和校验CustomVar.Fx_RS=s.substr(0,4)+Ra+Rn+s.substr(4,1)+CustomVar.Fx_Rchk;//发送的字符串6.程序实现3.转换响应返回的数据vartemp=newArray();temp.length=CustomVar.Fx_Rnum*8;for(i=0;iCustomVar.Fx_Rnum*8;i++){if(串口_2.DataArray[1+i]=57)//判断接收的每位数据是否小于等于57{temp[i]=(串口_2.DataArray[i+1]-0x30).toString(16).toUpperCase();//把接收的数据转换成十六}进制字符串else{temp[i]=(串口_2.DataArray[i+1]-0x30-0x7).toString(16).toUpperCase();}}for(i2=0;i2CustomVar.Fx_Rnum;i2++){a=temp[2+i2*8]+temp[3+i2*8]+temp[0+i2*8]+temp[1+i2*8]+temp[6+i2*8]+temp[7+i2*8]+temp[4+i2*8]+temp[5+i2*8];//把字符串累加CustomVar.Fx_R[i2]=HextoReal(a);//调用函数,并赋值赋值}6.程序实现//..................................................................................把取出的十六进制转换成实属函数functionHextoReal(h){vari3,i4,i5,i6,b,b1,s,e,m,m1;h=h.substr(4,4)+h.substr(0,4);//低四位先发,高四位后发b=;for(i3=0;i38;i3++)//把十六进制转换成实数{temp[i3]=parseInt(h.substr(i3,1),16);}for(i4=0;i48;i4++)//把实数转换成二进制{b1=temp[i4].toString(2);for(i5=b1.length;i54;i5++){b1=0+b1;//补码}b=b+b1;}6.程序实现s=b.substr(0,1);//正负数值e=parseI