51单片机实现Modbus从机程序.docx

上传人:b****8 文档编号:9289411 上传时间:2023-02-04 格式:DOCX 页数:14 大小:16.83KB
下载 相关 举报
51单片机实现Modbus从机程序.docx_第1页
第1页 / 共14页
51单片机实现Modbus从机程序.docx_第2页
第2页 / 共14页
51单片机实现Modbus从机程序.docx_第3页
第3页 / 共14页
51单片机实现Modbus从机程序.docx_第4页
第4页 / 共14页
51单片机实现Modbus从机程序.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

51单片机实现Modbus从机程序.docx

《51单片机实现Modbus从机程序.docx》由会员分享,可在线阅读,更多相关《51单片机实现Modbus从机程序.docx(14页珍藏版)》请在冰豆网上搜索。

51单片机实现Modbus从机程序.docx

51单片机实现Modbus从机程序

自己用单片机做的Modbus从机,可以使用STC89C52。

实现了命令码为1、2、3、4、5、6的功能,程序中有些是我们部分其他功能的函数和数据,希望大家参考下编程的思想。

uintSwitch=0xbc95;//开关状态

ucharbdataCoil1=0xff,Coil2=0xbc;//16位线圈状态

sbitCoil1_bit0=Coil1^0;

sbitCoil1_bit1=Coil1^1;

sbitCoil1_bit2=Coil1^2;

sbitCoil1_bit3=Coil1^3;

sbitCoil1_bit4=Coil1^4;

sbitCoil1_bit5=Coil1^5;

sbitCoil1_bit6=Coil1^6;

sbitCoil1_bit7=Coil1^7;

sbitCoil2_bit8=Coil2^0;

sbitCoil2_bit9=Coil2^1;

sbitCoil2_bit10=Coil2^2;

sbitCoil2_bit11=Coil2^3;

sbitCoil2_bit12=Coil2^4;

sbitCoil2_bit13=Coil2^5;

sbitCoil2_bit14=Coil2^6;

sbitCoil2_bit15=Coil2^7;

uintidataReOnlybuf[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};

uintidataReWrbuf[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};

//CRC校验查表码值

constucharcodeauchCRCHi[]={

0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,

0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,

0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,

0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,

0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,

0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,

0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,

0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,

0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,

0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,

0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,

0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,

0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,

0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,

0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,

0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,

0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,

0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,

0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,

0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,

0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,

0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,

0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,

0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,

0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,

0x80,0x41,0x00,0xC1,0x81,0x40};

constucharcodeauchCRCLo[]={

0x00,0xC0,0xC1,0x01,0xC3,0x03,0x02,0xC2,0xC6,0x06,

0x07,0xC7,0x05,0xC5,0xC4,0x04,0xCC,0x0C,0x0D,0xCD,

0x0F,0xCF,0xCE,0x0E,0x0A,0xCA,0xCB,0x0B,0xC9,0x09,

0x08,0xC8,0xD8,0x18,0x19,0xD9,0x1B,0xDB,0xDA,0x1A,

0x1E,0xDE,0xDF,0x1F,0xDD,0x1D,0x1C,0xDC,0x14,0xD4,

0xD5,0x15,0xD7,0x17,0x16,0xD6,0xD2,0x12,0x13,0xD3,

0x11,0xD1,0xD0,0x10,0xF0,0x30,0x31,0xF1,0x33,0xF3,

0xF2,0x32,0x36,0xF6,0xF7,0x37,0xF5,0x35,0x34,0xF4,

0x3C,0xFC,0xFD,0x3D,0xFF,0x3F,0x3E,0xFE,0xFA,0x3A,

0x3B,0xFB,0x39,0xF9,0xF8,0x38,0x28,0xE8,0xE9,0x29,

0xEB,0x2B,0x2A,0xEA,0xEE,0x2E,0x2F,0xEF,0x2D,0xED,

0xEC,0x2C,0xE4,0x24,0x25,0xE5,0x27,0xE7,0xE6,0x26,

0x22,0xE2,0xE3,0x23,0xE1,0x21,0x20,0xE0,0xA0,0x60,

0x61,0xA1,0x63,0xA3,0xA2,0x62,0x66,0xA6,0xA7,0x67,

0xA5,0x65,0x64,0xA4,0x6C,0xAC,0xAD,0x6D,0xAF,0x6F,

0x6E,0xAE,0xAA,0x6A,0x6B,0xAB,0x69,0xA9,0xA8,0x68,

0x78,0xB8,0xB9,0x79,0xBB,0x7B,0x7A,0xBA,0xBE,0x7E,

0x7F,0xBF,0x7D,0xBD,0xBC,0x7C,0xB4,0x74,0x75,0xB5,

0x77,0xB7,0xB6,0x76,0x72,0xB2,0xB3,0x73,0xB1,0x71,

0x70,0xB0,0x50,0x90,0x91,0x51,0x93,0x53,0x52,0x92,

0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,0x9C,0x5C,

0x5D,0x9D,0x5F,0x9F,0x9E,0x5E,0x5A,0x9A,0x9B,0x5B,

0x99,0x59,0x58,0x98,0x88,0x48,0x49,0x89,0x4B,0x8B,

0x8A,0x4A,0x4E,0x8E,0x8F,0x4F,0x8D,0x4D,0x4C,0x8C,

0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,

0x43,0x83,0x41,0x81,0x80,0x40};

/********************************************

Function:

CRC校验子函数

Input:

要校验的数组起始地址长度

Output:

16位校验码(高位在前)

********************************************/

uintcrccheck(uchar*puchMsg,ucharusDataLen)

{

ucharuchCRCHi=0xFF;

ucharuchCRCLo=0xFF;

ucharuIndex;

while(usDataLen--)

{

uIndex=uchCRCHi^*puchMsg++;

uchCRCHi=uchCRCLo^auchCRCHi[uIndex];

uchCRCLo=auchCRCLo[uIndex];

}

return(uchCRCHi<<8|uchCRCLo);

}

/********************************************

Function:

读线圈状态子函数

Input:

Output:

********************************************/

voidReadCoil(void)

{

uintStartAddress,tempAddress;

ucharCoilNum,i,ByteNum,j;

ucharCoilVal;

bitexit=0;

StartAddress=resvbuf[2];

StartAddress=StartAddress|resvbuf[3];

tempAddress=StartAddress;

CoilNum=resvbuf[5];//读取的位数

ByteNum=CoilNum/8;

if(CoilNum%8!

=0)

ByteNum++;

Sendbuf[2]=ByteNum;//返回的字节数

if(resvbuf[1]==0x01)

{

for(i=0;i

{

Sendbuf[i+3]=0;

for(j=0;j<8;j++)

{

CoilVal=GetCoilVal(StartAddress);

Sendbuf[i+3]|=CoilVal<

StartAddress++;

if(StartAddress>=tempAddress+CoilNum)

{

exit=1;

break;

}

}

if(exit==1)

break;

}

}

elseif(resvbuf[1]==0x02)

{

for(i=0;i

{

Sendbuf[i+3]=0;

for(j=0;j<8;j++)

{

CoilVal=GetSWVal(StartAddress);

Sendbuf[i+3]|=CoilVal<

StartAddress++;

if(StartAddress>=tempAddress+CoilNum)

{

exit=1;

break;

}

}

if(exit==1)

break;

}

}

SendCount=5+ByteNum;

SendData();

}

/********************************************

Function:

读寄存器状态子函数

Input:

Output:

********************************************/

voidReadRegisters(void)

{

uintStartAddress;

ucharByteCount,i;

StartAddress=resvbuf[2];

StartAddress=StartAddress<<8|resvbuf[3];

ByteCount=resvbuf[5]*2;

Sendbuf[2]=resvbuf[5];

if(resvbuf[1]==0x03)

for(i=0;i

{

Sendbuf[i+4]=ReWrbuf[StartAddress]&0xff;

Sendbuf[i+3]=ReWrbuf[StartAddress]>>8;

StartAddress++;

}

elseif(resvbuf[1]==0x04)

for(i=0;i

{

Sendbuf[i+4]=ReOnlybuf[StartAddress];

Sendbuf[i+3]=ReOnlybuf[StartAddress];

StartAddress++;

}

SendCount=ByteCount+5;

SendData();

}

/********************************************

Function:

强制单线圈子函数

Input:

Output:

********************************************/

voidForceSingalCoil(void)

{

uintAddress,OnOff;

bittemp,CoilVal;

Address=resvbuf[2]<<8|resvbuf[3];

OnOff=resvbuf[4]<<8|resvbuf[5];

if(OnOff==0x0000)

{

CoilVal=0;

temp=SetCoilVal(Address,CoilVal);

}

elseif(OnOff==0xFF00)

{

CoilVal=1;

temp=SetCoilVal(Address,CoilVal);

}

if(temp==1)

{

Sendbuf[2]=resvbuf[2];

Sendbuf[3]=resvbuf[3];

Sendbuf[4]=resvbuf[4];

Sendbuf[5]=resvbuf[5];

SendCount=8;

SendData();

}

else

Error=1;

}

/********************************************

Function:

强制单寄存器子函数

Input:

Output:

********************************************/

voidSetOneRegisterVal()

{

uintR_Address,RegisterVal;

bittemp1;

R_Address=resvbuf[2];

R_Address=R_Address<<8|resvbuf[3];

RegisterVal=resvbuf[4];

RegisterVal=RegisterVal<<8|resvbuf[5];

temp1=SetRegisterVal(R_Address,RegisterVal);

if(temp1==1)

{

Sendbuf[2]=resvbuf[2];

Sendbuf[3]=resvbuf[3];

Sendbuf[4]=resvbuf[4];

Sendbuf[5]=resvbuf[5];

SendCount=8;

SendData();

}

else

Error=1;

}

/********************************************

Function:

读线圈值子函数

Input:

线圈地址

Output:

线圈的值

********************************************/

ucharGetCoilVal(uintAddress)

{

uintCoilAddress;

ucharCoilVal=0;

CoilAddress=Address;

switch(CoilAddress&0x0f)

{

case0:

CoilVal=Coil1_bit0;break;

case1:

CoilVal=Coil1_bit1;break;

case2:

CoilVal=Coil1_bit2;break;

case3:

CoilVal=Coil1_bit3;break;

case4:

CoilVal=Coil1_bit4;break;

case5:

CoilVal=Coil1_bit5;break;

case6:

CoilVal=Coil1_bit6;break;

case7:

CoilVal=Coil1_bit7;break;

case8:

CoilVal=Coil2_bit8;break;

case9:

CoilVal=Coil2_bit9;break;

case10:

CoilVal=Coil2_bit10;break;

case11:

CoilVal=Coil2_bit11;break;

case12:

CoilVal=Coil2_bit12;break;

case13:

CoilVal=Coil2_bit13;break;

case14:

CoilVal=Coil2_bit14;break;

case15:

CoilVal=Coil2_bit15;break;

default:

break;

}

returnCoilVal;

}

/********************************************

Function:

读开关值子函数

Input:

开关地址

Output:

开关值

********************************************/

ucharGetSWVal(uintAddress1)

{

ucharCoilVal;

ucharSW1,SW2=0xff;

SW1=P2;

Switch=SW2<<8|SW1;

switch(Address1&0x0f)

{

case0:

CoilVal=Switch&0x01;break;

case1:

CoilVal=Switch>>1&0x01;break;

case2:

CoilVal=Switch>>2&0x01;break;

case3:

CoilVal=Switch>>3&0x01;break;

case4:

CoilVal=Switch>>4&0x01;break;

case5:

CoilVal=Switch>>5&0x01;break;

case6:

CoilVal=Switch>>6&0x01;break;

case7:

CoilVal=Switch>>7&0x01;break;

case8:

CoilVal=Switch>>8&0x01;break;

case9:

CoilVal=Switch>>9&0x01;break;

case10:

CoilVal=Switch>>10&0x01;break;

case11:

CoilVal=Switch>>11&0x01;break;

case12:

CoilVal=Switch>>12&0x01;break;

case13:

CoilVal=Switch>>13&0x01;break;

case14:

CoilVal=Switch>>14&0x01;break;

case15:

CoilVal=Switch>>15&0x01;break;

default:

break;

}

returnCoilVal;

}

/********************************************

Function:

强制单线圈值子函数

Input:

线圈地址,强制值

Output:

结果值

********************************************/

bitSetCoilVal(uintAddress,bitVal)

{

bitresult=1;

switch(Address&0x0f)

{

case0:

Coil1_bit0=Val;break;

case1:

Coil1_bit1=Val;break;

case2:

Coil1_bit2=Val;break;

case3:

Coil1_bit3=Val;break;

case4:

Coil1_bit4=Val;break;

case5:

Coil1_bit5=Val;break;

case6:

Coil1_bit6=Val;break;

case7:

Coil1_bit7=Val;break;

case8:

Coil2_

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1