求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 展开
全部评论(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
参与评论
登录后参与评论