求51/pic16f877a使用modbus RTU方式通信實(shí)例
-
51/pic16f877a 使用異步串行口通過modbus RTU協(xié)議方式通信實(shí)例。我自己寫了個。老是調(diào)試不出來。比如發(fā)01 05 00 10 ff 00 8d ff控制一個腳的高低電平。幫我讀取一個數(shù)值(int date)比如發(fā)01 04 00 13 00 03/01 41 ce(讀到單個寄存器)可以讀取到int date里的數(shù)... 51/pic16f877a 使用異步串行口通過modbus RTU協(xié)議方式通信實(shí)例。我自己寫了個。老是調(diào)試不出來。比如發(fā)01 05 00 10 ff 00 8d ff控制一個腳的高低電平。幫我讀取一個數(shù)值(int date)比如發(fā)01 04 00 13 00 03/01 41 ce(讀到單個寄存器)可以讀取到int date里的數(shù), date 是RD0每高電平一次就加1)。網(wǎng)上的都是只MODBUS通信部份數(shù)據(jù)處理部是沒有的。謝謝! 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;//發(fā)送中斷標(biāo)志位清零 RI=0;//接收中斷標(biāo)志位清零 } } 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字節(jié)初始化 uchar uchCRCLo = 0xFF ; //* 低CRC 字節(jié)初始化 unsigned long uIndex ; // CRC循環(huán)中的索引 while (usDataLen--) // 傳輸消息緩沖區(qū) { 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字節(jié)初始化 uchar uchCRCLo = 0xFF ; //* 低CRC 字節(jié)初始化 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校驗(yàn)。這個網(wǎng)上有算法。 函數(shù)算也行,查表也行。把計算的16字節(jié)校驗(yàn)補(bǔ)到待發(fā)送的數(shù)據(jù)后面一起發(fā)送。高位低位還要調(diào)換一下,這個你找資料看去吧。 -
贊(6)
回復(fù)(0)
熱門問答
- 求51/pic16f877a使用modbus RTU方式通信實(shí)例
- 51/pic16f877a 使用異步串行口通過modbus RTU協(xié)議方式通信實(shí)例。我自己寫了個。老是調(diào)試不出來。比如發(fā)01 05 00 10 ff 00 8d ff控制一個腳的高低電平。幫我讀取一個數(shù)值(int date)比如發(fā)01 04 00 13 00 03/01 41 ce(讀到單個寄存器)可以讀取到int date里的數(shù)... 51/pic16f877a 使用異步串行口通過modbus RTU協(xié)議方式通信實(shí)例。我自己寫了個。老是調(diào)試不出來。比如發(fā)01 05 00 10 ff 00 8d ff控制一個腳的高低電平。幫我讀取一個數(shù)值(int date)比如發(fā)01 04 00 13 00 03/01 41 ce(讀到單個寄存器)可以讀取到int date里的數(shù), date 是RD0每高電平一次就加1)。網(wǎng)上的都是只MODBUS通信部份數(shù)據(jù)處理部是沒有的。謝謝! QQ:358618924 展開
2010-11-06 08:35:33
483
1
- 西門子plc modbus rtu 與臺達(dá)變頻器通信實(shí)例
- 我要實(shí)際案例,有程序的那種!!有的話發(fā)送到471971458@qq.com,謝謝?。?!
2012-05-30 04:35:41
458
1
- modbus rtu串口通信
- 公司買了一個溫度巡檢儀,功能有限,我想通過自己做的軟件來增強(qiáng)巡檢儀的功能,但對串口通信編程知之甚少?,F(xiàn)通過監(jiān)控原程序得到以下數(shù)據(jù):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... 公司買了一個溫度巡檢儀,功能有限,我想通過自己做的軟件來增強(qiáng)巡檢儀的功能,但對串口通信編程知之甚少?,F(xiàn)通過監(jiān)控原程序得到以下數(shù)據(jù):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 從中能不能翻譯出什么東西?? 后來我又根據(jù)已有資料及網(wǎng)上相關(guān)程序編寫了以下通訊程序: Private Sub Command1_Click() '發(fā)請求 Dim btSend(23) As Byte btSend(0) = &H1 '目標(biāo)站號 btSend(1) = &H3 '功能碼 btSend(2) = &H0 'I0.0地址(0000)高字節(jié) btSend(3) = &H1 'i0.0地址(0000)低字節(jié) btSend(4) = &H0 '讀取個數(shù)高字節(jié) btSend(5) = &H1 '讀取個數(shù)低字節(jié) 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 '二進(jìn)制收發(fā) .InBufferSize = 512 .OutBufferSize = 512 If (Not .PortOpen) Then .PortOpen = True End With End Sub 能收到4個亂碼,應(yīng)該是錯誤標(biāo)示,原程序待CRC驗(yàn)證,我驗(yàn)證不出,所以先刪除了。期望大俠們幫我修改下程序 展開
2009-07-05 16:19:26
438
2
- modbus rtu通信的一些問題
- 問題一:相關(guān)資料上說modbus rtu通信數(shù)據(jù)中每個字節(jié)包括” 1個起始位、8個數(shù)據(jù)位、 1個奇偶校驗(yàn)位、1~2個停止位“,加起來每個字節(jié)就有12位了。不是一個字節(jié)只有8位的嗎? 問題二:無符號十六位二進(jìn)制數(shù)據(jù)乘以100,再除以256,這個運(yùn)算是起到什么作用呢?
2013-01-29 03:23:16
451
2
- modbus RTU模式的通信問題
- modbus RTU模式的通信通訊格式要求 地址 功能碼 數(shù)據(jù) CRC校驗(yàn) 數(shù)據(jù)長度 1個字節(jié) 1個字節(jié) N個字節(jié) 2個字節(jié) 如發(fā)送的數(shù)據(jù)... modbus RTU模式的通信通訊格式要求 地址 功能碼 數(shù)據(jù) CRC校驗(yàn) 數(shù)據(jù)長度 1個字節(jié) 1個字節(jié) N個字節(jié) 2個字節(jié) 如發(fā)送的數(shù)據(jù)為: 03 01 00 00 10 校驗(yàn)高位校驗(yàn)低位 我的問題是: 1、我理解地址03使用1個字節(jié)數(shù)據(jù)長度表示,是用1個字節(jié)表示0,再使用一個字節(jié)表示3,但再就使用了兩個字節(jié)的數(shù)據(jù)長度了,和通訊要求的格式不符。還有一種理解就是使用1個字節(jié)的直接表示03,其而進(jìn)制碼為000000011,如果地址是20,其二進(jìn)制碼為00010100,但這種理解出現(xiàn)個疑問,很多設(shè)備同時支持ASCII或RTU兩種方式,當(dāng)發(fā)送RTU的地址和ASCII方式的起始符相同時如都為03,接受方怎么判斷他是RTU發(fā)送的地址,還是ASCII起始符。 2、RTU方式判斷幀消息結(jié)束時是3.5字符時間,我想知道在物理層如何判斷的,如消息發(fā)送完后,在物理層485雙絞上,其電壓持續(xù)3.5字符長度+15V即判斷消息發(fā)送完成或是其電壓持續(xù)3.5字符長度-15V判斷消息發(fā)送完成。還是雙絞線上為其他狀態(tài)來判斷消息完成。485通訊線上沒有通訊時A、 B線狀態(tài)是什么。 請教各位了? 展開
2013-04-08 23:05:15
376
2
- modbus RTU一般怎么使用?
2014-12-21 03:05:50
479
2
- s7-1200進(jìn)行modbus RTU 通信需要什么硬件
2014-03-05 22:37:38
319
2
- 如何使Wonderware intouch建立modbus rtu通信
2017-09-26 03:23:52
453
1
- modbus rtu通信有16位數(shù)據(jù)位的嗎
2015-08-16 04:27:59
417
1
- 求助三菱FX2N PLC Modbus rtu 通信問題
2017-12-13 00:43:29
416
1
- 求助三菱FX2N PLC Modbus rtu 通信問題
2018-12-06 17:26:32
439
0
- 如何使Wonderware intouch建立modbus rtu通信
2018-11-25 01:36:13
315
0
- 如何使Wonderware intouch建立modbus rtu通信
2017-08-10 12:55:47
355
1
- modbus通信RTU和ASCII兩種傳輸方式的區(qū)別?
2012-12-05 14:35:01
453
2
- s7-200 modbus RTU通信可以帶多少個從站?
- 如題:小弟遇到一個工程,本地為1個PLC控制柜,遠(yuǎn)程是100多個數(shù)字量輸入模塊(Modbus rtu),之前是從本地的控制箱拉線的到每一個現(xiàn)場控制和采集一些開關(guān)量,現(xiàn)在想提GX率節(jié)約成本,想問問1個PLC主站能帶100個從站嗎?還有能帶的話怎么樣編程能節(jié)約通信時間... 如題:小弟遇到一個工程,本地為1個PLC控制柜,遠(yuǎn)程是100多個數(shù)字量輸入模塊(Modbus rtu),之前是從本地的控制箱拉線的到每一個現(xiàn)場控制和采集一些開關(guān)量,現(xiàn)在想提GX率節(jié)約成本,想問問1個PLC主站能帶100個從站嗎?還有能帶的話怎么樣編程能節(jié)約通信時間?求大俠指點(diǎn)或者能提供更加合理的方案(在節(jié)約成本的前提下) 展開
2017-12-15 08:46:08
458
1
- modbus RTU和modbus TCP能同時使用么
2017-08-14 04:39:33
479
1
- 四信水利RTU支持什么通信方式?
2017-02-20 05:55:34
432
1
- RS485通過modbus rtu協(xié)議通信和通過pc加載器協(xié)議通信
2012-04-09 22:05:47
387
2
- modbus rtu是什么?
2012-10-13 03:39:38
495
2
- modbus rtu協(xié)議
- 儀表的modbus rtu 協(xié)議的保持寄存器地址是從40001,但是OPC軟件上的modbus rtu 協(xié)議卻是400001開始,我不知道怎么獲取儀表上的數(shù)據(jù),我軟件上我要怎么跟儀表地址對起來。
2011-12-24 07:10:01
639
4
4月突出貢獻(xiàn)榜
推薦主頁
最新話題





參與評論
登錄后參與評論