欧姆龙modbusrtu程序怎么写

欧姆龙modbusrtu程序怎么写,第1张

欧姆龙modbus RTU程序编写步骤如下:

(1)了解协议

首先,您应该了解Modbus RTU协议,包括它的总线层次、报文格式、功能码及其对应的功能等等。

(2)定义层次

其次,在实现Modbus RTU程序之前,您需要做的另一个任务便是定义层次。

(3)开发层次

接着,需要开发总线层次所需的软件,以用于编写和维护Modbus RTU程序。

(4)编写程序

最后,将用您所开发的软件编写Modbus RTU程序,以实现您所需的功能,如可以在给定的从动装置中读取和写入数据。

给你个程序看看: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=0i<113i++)

}

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|0x80TMOD=0x20TH1=0xfdbreak

case 9600 :PCON=PCON&0x7fTMOD=0x20TH1=0xfdbreak

case 4800 :PCON=PCON&0x7fTMOD=0x20TH1=0xfabreak

case 2400 :PCON=PCON&0x7fTMOD=0x20TH1=0xf4break

case 1200 :PCON=PCON&0x7fTMOD=0x20TH1=0xe8break

case 600 :PCON=PCON&0x7fTMOD=0x20TH1=0xd0break

case 300 :PCON=PCON&0x7fTMOD=0x20TH1=0xa0break

case 110 :PCON=PCON&0x7fTMOD=0x10TH1=0xfeTL1=0xffbreak

default: PCON=PCON&0x7fTMOD=0x20TH1=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=0break

case 0x01:error1=0break

case 0x05:error1=0break

case 0x0f:error1=0break

case 0x04:error1=0break

case 0x03:error1=0break

case 0x06:error1=0break

case 0x10:error1=0break

case 0x17:error1=0break

case 0x16:error1=0break

case 0x14:error1=0break

case 0x15:error1=0break

case 0x2b:error1=0break

default:error1=1

}

if (dee.word>0&&dee.word<0x07d1) error3=0else 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=0else 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=crcn=crc>>8&0x00ff

if((receive[6]==m)&&(receive[7]==n))

return1

else

return 0

}

void Uart() interrupt 4using 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]=0x00receive[1]=0x00receive[2]=0x00

receive[3]=0x00receive[4]=0x00receive[5]=0x00

receive[6]=0x00receive[7]=0x00receive_count=0*/

}

}

}

void Beginsend(uchar Me )

{

ES=0Stor=1

TI=0

send[0]=receive[0]

while(error_check==1)

{

if(error1==1) {send[1]=receive[1]|0x80send[2]=0x01break}

if(error3==1) {send[1]=receive[1]|0x80send[2]=0x03break}

if(error2==1) {send[1]=receive[1]|0x80send[2]=0x02break}

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=0error2=0error3=0error4=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

elsereturn 0

}

void main()

{

My_function(BAUD,ADDRESS,REGISTERADDRESS ,MYREGISTER )

while(1)

}

首先你要对MODBUS熟悉,然后你要会算RTU类型的CRC校验。这个网上有算法。

函数算也行,查表也行。把计算的16字节校验补到待发送的数据后面一起发送。高位低位还要调换一下,这个你找资料看去吧。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/12193674.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-21
下一篇2023-05-21

发表评论

登录后才能评论

评论列表(0条)

    保存