仪器网(yiqi.com)欢迎您!

| 注册 登录
网站首页-资讯-专题- 微头条-话题-产品- 品牌库-搜索-供应商- 展会-招标-采购- 社区-知识-技术-资料库-方案-直播- 视频

问答社区

求51/pic16f877a使用modbus RTU方式通信实例

_a9_free685 2010-11-06 08:35:33 412  浏览
  • 51/pic16f877a 使用异步串行口通过modbus RTU协议方式通信实例。我自己写了个。老是调试不出来。比如发01 05 00 10 ff 00 8d ff控制一个脚的高低电平。帮我读取一个数值(int date)比如发01 04 00 13 00 03/01 41 ce(读到单个寄存器)可以读取到int date里的数... 51/pic16f877a 使用异步串行口通过modbus RTU协议方式通信实例。我自己写了个。老是调试不出来。比如发01 05 00 10 ff 00 8d ff控制一个脚的高低电平。帮我读取一个数值(int date)比如发01 04 00 13 00 03/01 41 ce(读到单个寄存器)可以读取到int date里的数, date 是RD0每高电平一次就加1)。网上的都是只MODBUS通信部份数据处理部是没有的。谢谢! QQ:358618924 展开

参与评论

全部评论(1条)

  • 廖若星辰2 2010-11-07 00:00:00
    给你个程序看看:89S52的。 #include"reg51.h" #include"modbus.h" uchar m=0,n=0; uint crc=0; uint myaw=0; void delay(uint w) { uchar i; while(w--) for(i=0;i<113;i++); } void My_function(uint My_baud,uchar My_address,uint My_registeraddess,uint My_register) {myaddress= My_address;
    My_register_address=My_registeraddess;
    My_register_num=My_register;
    if(flag)
    {
    switch(My_baud)
    {
    case 19200 :PCON=PCON|0x80;TMOD=0x20; TH1=0xfd;break;
    case 9600 :PCON=PCON&0x7f; TMOD=0x20; TH1=0xfd;break;
    case 4800 :PCON=PCON&0x7f; TMOD=0x20; TH1=0xfa;break;
    case 2400 :PCON=PCON&0x7f; TMOD=0x20; TH1=0xf4;break;
    case 1200 :PCON=PCON&0x7f; TMOD=0x20; TH1=0xe8;break;
    case 600 :PCON=PCON&0x7f; TMOD=0x20; TH1=0xd0;break;
    case 300 :PCON=PCON&0x7f; TMOD=0x20; TH1=0xa0;break;

    case 110 :PCON=PCON&0x7f; TMOD=0x10; TH1=0xfe;TL1=0xff;break;
    default: PCON=PCON&0x7f;TMOD=0x20; TH1=0xfd;
    } SCON=0xd0; IE=0x90; Stor=0; TR1=1; flag=0; TI=0;//发送中断标志位清零 RI=0;//接收中断标志位清零 } } void My_receive() { dee.byte.Hi=receive[2]; dee.byte.Lo=receive[3]; switch(receive[1]) { case 0x02:error1=0;break; case 0x01:error1=0;break; case 0x05:error1=0;break; case 0x0f:error1=0;break; case 0x04:error1=0;break; case 0x03:error1=0;break; case 0x06:error1=0;break; case 0x10:error1=0;break; case 0x17:error1=0;break; case 0x16:error1=0;break; case 0x14:error1=0;break; case 0x15:error1=0;break; case 0x2b:error1=0;break; default:error1=1; } if (dee.word>0&&dee.word<0x07d1) error3=0; else error3=1; if (dee.word==My_register_address) { dee.byte.Hi=receive[4]; dee.byte.Lo=receive[5]; if(dee.word==My_register_num) error2=0; else error2=1; } else error2=1; if(error1==1||error2==1||error3==1) error_check=1; else error_check=0; } uint crc16(uchar *puchMsg, uint usDataLen) { uchar uchCRCHi = 0xFF ; //* 高CRC字节初始化 uchar uchCRCLo = 0xFF ; //* 低CRC 字节初始化 unsigned long uIndex ; // CRC循环中的索引 while (usDataLen--) // 传输消息缓冲区 { uIndex = uchCRCHi ^ *puchMsg++ ; // 计算CRC uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ; uchCRCLo = auchCRCLo[uIndex] ; } return (uchCRCHi | uchCRCLo<<8); } bit check_modbus(uchar *puchMsg, uint usDataLen) { uchar uchCRCHi = 0xFF ; //* 高CRC字节初始化 uchar uchCRCLo = 0xFF ; //* 低CRC 字节初始化 crc=crc16( puchMsg, usDataLen); m=crc;n=crc>>8&0x00ff; if((receive[6]==m)&&(receive[7]==n)) return 1 ; else return 0; } void Uart() interrupt 4 using 1 { if(RI) { receive[receive_count]=SBUF; RI=0; receive_count++; } if(8==receive_count) { jieshou=1; receive_count=0; if(check_modbus(receive,6)==1&&myaddress==receive[0]) { My_receive(); if(error_check==1) Beginsend(3); } else { /*receive[0]=0x00;receive[1]=0x00;receive[2]=0x00; receive[3]=0x00;receive[4]=0x00;receive[5]=0x00; receive[6]=0x00;receive[7]=0x00;receive_count=0;*/ } ; }; } void Beginsend(uchar Me ) { ES=0; Stor=1; TI=0; send[0]=receive[0]; while(error_check==1) { if(error1==1) {send[1]=receive[1]|0x80;send[2]=0x01;break;} if(error3==1) {send[1]=receive[1]|0x80;send[2]=0x03;break;} if(error2==1) {send[1]=receive[1]|0x80;send[2]=0x02;break;} break; } myaw=crc16(send,Me); send[3] =myaw&0x00ff; send[4] =myaw>>8&0x00ff; /*if(jiaoyan(send[0])==0) TB8=1; else TB8=0; delay(2);*/ SBUF=send[0] ; /* while(TI==0); TI=0; delay(20); if(jiaoyan(send[1])==0) TB8=1; else TB8=0; delay(2);*/ SBUF=send[1] ; while(TI==0); TI=0;/* if(jiaoyan(send[2])==0) TB8=1; else TB8=0; delay(2);*/ SBUF=send[2] ; while(TI==0); TI=0; delay(20);/* if(jiaoyan(send[3])==0) TB8=1; else TB8=0; delay(2);*/ SBUF=send[3] ; while(TI==0); TI=0; delay(20);/* if(jiaoyan(send[4])==0) TB8=1; else TB8=0; delay(20);*/ SBUF=send[4] ; while(TI==0); TI=0; ES=1; yifasong=1; Stor=0; error1=0;error2=0;error3=0;error4=0; } bit jiaoyan(uchar Me) { uchar w=0; if(Me&0x01==1) w++; if(Me&0x02==1) w++; if(Me&0x04==1) w++; if(Me&0x08==1) w++; if(Me&0x10==1) w++; if(Me&0x20==1) w++; if(Me&0x40==1) w++; if(Me&0x80==1) w++; if(0==w%2) return 1; else return 0; } void main() { My_function(BAUD,ADDRESS,REGISTERADDRESS ,MYREGISTER ) ; while(1); } 首先你要对MODBUS熟悉,然后你要会算RTU类型的CRC校验。这个网上有算法。 函数算也行,查表也行。把计算的16字节校验补到待发送的数据后面一起发送。高位低位还要调换一下,这个你找资料看去吧。

    赞(6)

    回复(0)

    评论

获取验证码
我已经阅读并接受《仪器网服务协议》

热门问答

求51/pic16f877a使用modbus RTU方式通信实例
51/pic16f877a 使用异步串行口通过modbus RTU协议方式通信实例。我自己写了个。老是调试不出来。比如发01 05 00 10 ff 00 8d ff控制一个脚的高低电平。帮我读取一个数值(int date)比如发01 04 00 13 00 03/01 41 ce(读到单个寄存器)可以读取到int date里的数... 51/pic16f877a 使用异步串行口通过modbus RTU协议方式通信实例。我自己写了个。老是调试不出来。比如发01 05 00 10 ff 00 8d ff控制一个脚的高低电平。帮我读取一个数值(int date)比如发01 04 00 13 00 03/01 41 ce(读到单个寄存器)可以读取到int date里的数, date 是RD0每高电平一次就加1)。网上的都是只MODBUS通信部份数据处理部是没有的。谢谢! QQ:358618924 展开
2010-11-06 08:35:33 412 1
西门子plc modbus rtu 与台达变频器通信实例
我要实际案例,有程序的那种!!有的话发送到471971458@qq.com,谢谢!!!
2012-05-30 04:35:41 390 1
modbus rtu串口通信
公司买了一个温度巡检仪,功能有限,我想通过自己做的软件来增强巡检仪的功能,但对串口通信编程知之甚少。现通过监控原程序得到以下数据:write requests: 01 03 00 01 00 01 D5 CA 01 01 00 50 00 20 3D C3 01 03 00 60 00 10 44 18 read requests: 01 03... 公司买了一个温度巡检仪,功能有限,我想通过自己做的软件来增强巡检仪的功能,但对串口通信编程知之甚少。现通过监控原程序得到以下数据:write requests: 01 03 00 01 00 01 D5 CA 01 01 00 50 00 20 3D C3 01 03 00 60 00 10 44 18 read requests: 01 03 02 00 02 39 85 01 01 04 00 00 00 00 FB D1 01 03 20 4E 20 4E 20 4E 20 4E 20 4E 20 4E 20 4E 20 4E 20 4E 20 4E 20 4E 20 4E 20 4E 20 4E 20 4E 20 4E 20 AE 38 从中能不能翻译出什么东西?? 后来我又根据已有资料及网上相关程序编写了以下通讯程序: Private Sub Command1_Click() '发请求 Dim btSend(23) As Byte btSend(0) = &H1 '目标站号 btSend(1) = &H3 '功能码 btSend(2) = &H0 'I0.0地址(0000)高字节 btSend(3) = &H1 'i0.0地址(0000)低字节 btSend(4) = &H0 '读取个数高字节 btSend(5) = &H1 '读取个数低字节 btSend(6) = &HD5 btSend(7) = &HCA btSend(8) = &H1 btSend(9) = &H1 btSend(10) = &H0 btSend(11) = &H50 btSend(12) = &H0 btSend(13) = &H20 btSend(14) = &H3D btSend(15) = &HC3 btSend(16) = &H1 btSend(17) = &H3 btSend(18) = &H0 btSend(19) = &H60 btSend(20) = &H0 btSend(21) = &H10 btSend(22) = &H44 btSend(23) = &H18 ComK3.Output = CVar(btSend) Dim btReceive As Variant With ComK3 Do DoEvents Loop Until .InBufferCount = 5 .InputLen = 30 btReceive = .Input Text1.Text = Hex$(btReceive(1)) Text2.Text = Hex$(btReceive(2)) Text3.Text = Hex$(btReceive(3)) Text4.Text = Hex$(btReceive(4)) ' Text5.Text = Hex$(btReceive(5)) 'Text6.Text = Hex$(btReceive(6)) ' Text7.Text = Hex$(btReceive(7)) ' Text8.Text = Hex$(btReceive(8)) ' Text9.Text = Hex$(btReceive(9)) ' Text10.Text = Hex$(btReceive(10)) ' Text11.Text = Hex$(btReceive(11)) ' Text12.Text = Hex$(btReceive(12)) ' Text13.Text = Hex$(btReceive(13)) ' Text14.Text = Hex$(btReceive(14)) ' Text15.Text = Hex$(btReceive(15)) ' Text16.Text = Hex$(btReceive(16)) ' End If End With End Sub Private Sub Form_Load() With ComK3 .CommPort = 1 .Settings = "9600,N,8,2" .InputMode = comInputModeBinary '二进制收发 .InBufferSize = 512 .OutBufferSize = 512 If (Not .PortOpen) Then .PortOpen = True End With End Sub 能收到4个乱码,应该是错误标示,原程序待CRC验证,我验证不出,所以先删除了。期望大侠们帮我修改下程序 展开
2009-07-05 16:19:26 358 2
modbus rtu通信的一些问题
问题一:相关资料上说modbus rtu通信数据中每个字节包括” 1个起始位、8个数据位、 1个奇偶校验位、1~2个停止位“,加起来每个字节就有12位了。不是一个字节只有8位的吗? 问题二:无符号十六位二进制数据乘以100,再除以256,这个运算是起到什么作用呢?
2013-01-29 03:23:16 376 2
modbus RTU模式的通信问题
modbus RTU模式的通信通讯格式要求 地址 功能码 数据 CRC校验 数据长度 1个字节 1个字节 N个字节 2个字节 如发送的数据... modbus RTU模式的通信通讯格式要求 地址 功能码 数据 CRC校验 数据长度 1个字节 1个字节 N个字节 2个字节 如发送的数据为: 03 01 00 00 10 校验高位校验低位 我的问题是: 1、我理解地址03使用1个字节数据长度表示,是用1个字节表示0,再使用一个字节表示3,但再就使用了两个字节的数据长度了,和通讯要求的格式不符。还有一种理解就是使用1个字节的直接表示03,其而进制码为000000011,如果地址是20,其二进制码为00010100,但这种理解出现个疑问,很多设备同时支持ASCII或RTU两种方式,当发送RTU的地址和ASCII方式的起始符相同时如都为03,接受方怎么判断他是RTU发送的地址,还是ASCII起始符。 2、RTU方式判断帧消息结束时是3.5字符时间,我想知道在物理层如何判断的,如消息发送完后,在物理层485双绞上,其电压持续3.5字符长度+15V即判断消息发送完成或是其电压持续3.5字符长度-15V判断消息发送完成。还是双绞线上为其他状态来判断消息完成。485通讯线上没有通讯时A、 B线状态是什么。 请教各位了? 展开
2013-04-08 23:05:15 310 2
modbus RTU一般怎么使用?
 
2014-12-21 03:05:50 415 2
如何使Wonderware intouch建立modbus rtu通信
 
2017-08-10 12:55:47 297 1
如何使Wonderware intouch建立modbus rtu通信
 
2018-11-25 01:36:13 269 0
求助三菱FX2N PLC Modbus rtu 通信问题
 
2018-12-06 17:26:32 368 0
求助三菱FX2N PLC Modbus rtu 通信问题
 
2017-12-13 00:43:29 346 1
modbus rtu通信有16位数据位的吗
 
2015-08-16 04:27:59 351 1
如何使Wonderware intouch建立modbus rtu通信
 
2017-09-26 03:23:52 407 1
s7-1200进行modbus RTU 通信需要什么硬件
 
2014-03-05 22:37:38 251 2
s7-200 modbus RTU通信可以带多少个从站?
如题:小弟遇到一个工程,本地为1个PLC控制柜,远程是100多个数字量输入模块(Modbus rtu),之前是从本地的控制箱拉线的到每一个现场控制和采集一些开关量,现在想提GX率节约成本,想问问1个PLC主站能带100个从站吗?还有能带的话怎么样编程能节约通信时间... 如题:小弟遇到一个工程,本地为1个PLC控制柜,远程是100多个数字量输入模块(Modbus rtu),之前是从本地的控制箱拉线的到每一个现场控制和采集一些开关量,现在想提GX率节约成本,想问问1个PLC主站能带100个从站吗?还有能带的话怎么样编程能节约通信时间?求大侠指点或者能提供更加合理的方案(在节约成本的前提下) 展开
2017-12-15 08:46:08 380 1
modbus通信RTU和ASCII两种传输方式的区别?
 
2012-12-05 14:35:01 375 2
modbus RTU和modbus TCP能同时使用么
 
2017-08-14 04:39:33 417 1
四信水利RTU支持什么通信方式?
 
2017-02-20 05:55:34 349 1
RS485通过modbus rtu协议通信和通过pc加载器协议通信
 
2012-04-09 22:05:47 309 2
modbus rtu协议
仪表的modbus rtu 协议的保持寄存器地址是从40001,但是OPC软件上的modbus rtu 协议却是400001开始,我不知道怎么获取仪表上的数据,我软件上我要怎么跟仪表地址对起来。
2011-12-24 07:10:01 519 4
modbus rtu是什么?
 
2012-10-13 03:39:38 399 2

11月突出贡献榜

推荐主页

最新话题