1、51单片机实现Modbus从机程序自己用单片机做的Modbus从机,可以使用STC89C52。实现了命令码为1、2、3、4、5、6的功能,程序中有些是我们部分其他功能的函数和数据,希望大家参考下编程的思想。uint Switch=0xbc95;/开关状态uchar bdata Coil1=0xff,Coil2=0xbc;/16位线圈状态sbit Coil1_bit0=Coil10;sbit Coil1_bit1=Coil11;sbit Coil1_bit2=Coil12;sbit Coil1_bit3=Coil13;sbit Coil1_bit4=Coil14;sbit Coil1_bit5=
2、Coil15;sbit Coil1_bit6=Coil16;sbit Coil1_bit7=Coil17;sbit Coil2_bit8=Coil20;sbit Coil2_bit9=Coil21;sbit Coil2_bit10=Coil22;sbit Coil2_bit11=Coil23;sbit Coil2_bit12=Coil24;sbit Coil2_bit13=Coil25;sbit Coil2_bit14=Coil26;sbit Coil2_bit15=Coil27;uint idata ReOnlybuf=0x00,0x01,0x02,0x03,0x04,0x05,0x06,0
3、x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f;uint idata ReWrbuf=0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f;/CRC校验查表码值const uchar code auchCRCHi = 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41
4、, 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
5、, 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
6、, 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
7、, 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
8、, 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; const uchar code auchCRCLo = 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6,
9、 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,
10、 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,
11、 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,
12、 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,
13、 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校验子函
14、数Input:要校验的数组起始地址 长度Output:16位校验码(高位在前)*/uint crccheck(uchar *puchMsg, uchar usDataLen) uchar uchCRCHi = 0xFF ; uchar uchCRCLo = 0xFF ; uchar uIndex ; while (usDataLen-) uIndex = uchCRCHi *puchMsg+ ; uchCRCHi = uchCRCLo auchCRCHiuIndex ; uchCRCLo = auchCRCLouIndex ; return (uchCRCHi 8 | uchCRCLo) ;
15、/*Function:读线圈状态子函数Input:无Output:无*/void ReadCoil(void) uint StartAddress,tempAddress; uchar CoilNum,i,ByteNum,j; uchar CoilVal; bit exit=0; StartAddress=resvbuf2; StartAddress=StartAddress|resvbuf3; tempAddress=StartAddress; CoilNum=resvbuf5;/读取的位数 ByteNum=CoilNum/8; if(CoilNum%8!=0) ByteNum+; Send
16、buf2=ByteNum;/返回的字节数 if(resvbuf1=0x01) for(i=0;iByteNum;i+) Sendbufi+3=0; for(j=0;j8;j+) CoilVal=GetCoilVal(StartAddress); Sendbufi+3|=CoilVal=tempAddress+CoilNum) exit=1; break; if(exit=1) break; else if(resvbuf1=0x02) for(i=0;iByteNum;i+) Sendbufi+3=0; for(j=0;j8;j+) CoilVal=GetSWVal(StartAddress)
17、; Sendbufi+3|=CoilVal=tempAddress+CoilNum) exit=1; break; if(exit=1) break; SendCount=5+ByteNum; SendData();/*Function:读寄存器状态子函数Input:无Output:无*/void ReadRegisters(void) uint StartAddress; uchar ByteCount,i; StartAddress=resvbuf2; StartAddress=StartAddress8|resvbuf3; ByteCount=resvbuf5*2; Sendbuf2=r
18、esvbuf5; if(resvbuf1=0x03) for(i=0;i8; StartAddress+; else if(resvbuf1=0x04) for(i=0;iByteCount;i+=2) Sendbufi+4=ReOnlybufStartAddress; Sendbufi+3=ReOnlybufStartAddress; StartAddress+; SendCount=ByteCount+5; SendData();/*Function:强制单线圈子函数Input:无Output:无*/void ForceSingalCoil(void) uint Address,OnOff
19、; bit temp,CoilVal; Address=resvbuf28|resvbuf3; OnOff=resvbuf48|resvbuf5; if(OnOff=0x0000) CoilVal=0; temp=SetCoilVal(Address,CoilVal); else if(OnOff=0xFF00) CoilVal=1; temp=SetCoilVal(Address,CoilVal); if(temp=1) Sendbuf2=resvbuf2; Sendbuf3=resvbuf3; Sendbuf4=resvbuf4; Sendbuf5=resvbuf5; SendCount=
20、8; SendData(); else Error=1;/*Function:强制单寄存器子函数Input:无Output:无*/void SetOneRegisterVal() uint R_Address,RegisterVal; bit temp1; R_Address=resvbuf2; R_Address=R_Address8|resvbuf3; RegisterVal=resvbuf4; RegisterVal=RegisterVal8|resvbuf5; temp1=SetRegisterVal(R_Address,RegisterVal); if(temp1=1) Sendbu
21、f2=resvbuf2; Sendbuf3=resvbuf3; Sendbuf4=resvbuf4; Sendbuf5=resvbuf5; SendCount=8; SendData(); else Error=1; /*Function:读线圈值子函数Input:线圈地址Output:线圈的值*/uchar GetCoilVal(uint Address) uint CoilAddress; uchar CoilVal=0; CoilAddress=Address; switch(CoilAddress&0x0f) case 0: CoilVal=Coil1_bit0;break; case
22、 1: CoilVal=Coil1_bit1;break; case 2: CoilVal=Coil1_bit2;break; case 3: CoilVal=Coil1_bit3;break; case 4: CoilVal=Coil1_bit4;break; case 5: CoilVal=Coil1_bit5;break; case 6: CoilVal=Coil1_bit6;break; case 7: CoilVal=Coil1_bit7;break; case 8: CoilVal=Coil2_bit8;break; case 9: CoilVal=Coil2_bit9;break
23、; case 10: CoilVal=Coil2_bit10;break; case 11: CoilVal=Coil2_bit11;break; case 12: CoilVal=Coil2_bit12;break; case 13: CoilVal=Coil2_bit13;break; case 14: CoilVal=Coil2_bit14;break; case 15: CoilVal=Coil2_bit15;break; default: break; return CoilVal;/*Function:读开关值子函数Input:开关地址Output:开关值*/uchar GetSW
24、Val(uint Address1) uchar CoilVal; uchar SW1,SW2=0xff; SW1=P2; Switch=SW21&0x01;break; case 2: CoilVal=Switch2&0x01;break; case 3: CoilVal=Switch3&0x01;break; case 4: CoilVal=Switch4&0x01;break; case 5: CoilVal=Switch5&0x01;break; case 6: CoilVal=Switch6&0x01;break; case 7: CoilVal=Switch7&0x01;break
25、; case 8: CoilVal=Switch8&0x01;break; case 9: CoilVal=Switch9&0x01;break; case 10: CoilVal=Switch10&0x01;break; case 11: CoilVal=Switch11&0x01;break; case 12: CoilVal=Switch12&0x01;break; case 13: CoilVal=Switch13&0x01;break; case 14: CoilVal=Switch14&0x01;break; case 15: CoilVal=Switch15&0x01;break
26、; default: break; return CoilVal;/*Function:强制单线圈值子函数Input:线圈地址,强制值Output:结果值*/bit SetCoilVal(uint Address,bit Val) bit result=1; switch(Address&0x0f) case 0: Coil1_bit0=Val;break; case 1: Coil1_bit1=Val;break; case 2: Coil1_bit2=Val;break; case 3: Coil1_bit3=Val;break; case 4: Coil1_bit4=Val;break; case 5: Coil1_bit5=Val;break; case 6: Coil1_bit6=Val;break; case 7: Coil1_bit7=Val;break; case 8: Coil2_
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1