1、自己用单片机做的Modbus从机,可以使用STC89C52。实现了命令码为1、2、3、4、5、6的功能,程序中有些是我们部分其他功能的函数和数据,希望大家参考下编程的思想。 uint Switch=0xbc95;//开关状态 uchar bdata Coil1=0xff,Coil2=0xbc;//16位线圈状态 sbit Coil1_bit0=Coil1^0; sbit Coil1_bit1=Coil1^1; sbit Coil1_bit2=Coil1^2; sbit Coil1_bit3=Coil1^3; sbit Coil1_bit4=Coil1^4; sbit Coi
2、l1_bit5=Coil1^5; sbit Coil1_bit6=Coil1^6; sbit Coil1_bit7=Coil1^7; sbit Coil2_bit8=Coil2^0; sbit Coil2_bit9=Coil2^1; sbit Coil2_bit10=Coil2^2; sbit Coil2_bit11=Coil2^3; sbit Coil2_bit12=Coil2^4; sbit Coil2_bit13=Coil2^5; sbit Coil2_bit14=Coil2^6; sbit Coil2_bit15=Coil2^7; uint idata ReO
3、nlybuf[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,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,
4、 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, 0
5、xC0, 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, 0xC
6、0, 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,
7、 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, 0
8、x80, 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, 0x8
9、0, 0x41, 0x00, 0xC1, 0x81, 0x40}; const uchar code auchCRCLo[] = { 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, 0
10、xDB, 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, 0x3
11、F, 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,
12、 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, 0
13、xB6, 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, 0x8
14、A, 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位校验码(高位在前) *********************************
15、/ uint crccheck(uchar *puchMsg, uchar usDataLen) { uchar uchCRCHi = 0xFF ; uchar uchCRCLo = 0xFF ; uchar uIndex ; while (usDataLen--) { uIndex = uchCRCHi ^ *puchMsg++ ; uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ; uchCRCLo = auchCRCLo[uIndex] ; } return (u
16、chCRCHi << 8 | uchCRCLo) ; } /******************************************** Function:读线圈状态子函数 Input:无 Output:无 ********************************************/ void ReadCoil(void) { uint StartAddress,tempAddress; uchar CoilNum,i,ByteNum,j; uchar CoilVal; bit exit=0; StartAddress=res
17、vbuf[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 18、CoilVal=GetCoilVal(StartAddress);
Sendbuf[i+3]|=CoilVal< 19、0;
for(j=0;j<8;j++)
{
CoilVal=GetSWVal(StartAddress);
Sendbuf[i+3]|=CoilVal< 20、
Function:读寄存器状态子函数
Input:无
Output:无
********************************************/
void ReadRegisters(void)
{
uint StartAddress;
uchar ByteCount,i;
StartAddress=resvbuf[2];
StartAddress=StartAddress<<8|resvbuf[3];
ByteCount=resvbuf[5]*2;
Sendbuf[2 21、]=resvbuf[5];
if(resvbuf[1]==0x03)
for(i=0;i 22、nlybuf[StartAddress];
StartAddress++;
}
SendCount=ByteCount+5;
SendData();
}
/********************************************
Function:强制单线圈子函数
Input:无
Output:无
********************************************/
void ForceSingalCoil(void)
{
uint Address,OnOff;
bit temp,CoilVal;
Addr 23、ess=resvbuf[2]<<8|resvbuf[3];
OnOff=resvbuf[4]<<8|resvbuf[5];
if(OnOff==0x0000)
{
CoilVal=0;
temp=SetCoilVal(Address,CoilVal);
}
else if(OnOff==0xFF00)
{
CoilVal=1;
temp=SetCoilVal(Address,CoilVal);
}
if(temp==1)
{
Sendbuf[2]=resvbuf[2];
Sendbuf[3]=resvbuf[3];
24、Sendbuf[4]=resvbuf[4];
Sendbuf[5]=resvbuf[5];
SendCount=8;
SendData();
}
else
Error=1;
}
/********************************************
Function:强制单寄存器子函数
Input:无
Output:无
********************************************/
void SetOneRegisterVal()
{
uint R_Address,RegisterVal;
25、
bit temp1;
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]=r 26、esvbuf[5];
SendCount=8;
SendData();
}
else
Error=1;
}
/********************************************
Function:读线圈值子函数
Input:线圈地址
Output:线圈的值
********************************************/
uchar GetCoilVal(uint Address)
{
uint CoilAddress;
uchar CoilVal=0;
CoilAddress=Add 27、ress;
switch(CoilAddress&0x0f)
{
case 0: CoilVal=Coil1_bit0;break;
case 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;brea 28、k;
case 7: CoilVal=Coil1_bit7;break;
case 8: CoilVal=Coil2_bit8;break;
case 9: CoilVal=Coil2_bit9;break;
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_b 29、it14;break;
case 15: CoilVal=Coil2_bit15;break;
default: break;
}
return CoilVal;
}
/********************************************
Function:读开关值子函数
Input:开关地址
Output:开关值
********************************************/
uchar GetSWVal(uint Address1)
{
uchar CoilVal;
uchar SW1,SW2= 30、0xff;
SW1=P2;
Switch=SW2<<8|SW1;
switch(Address1&0x0f)
{
case 0: CoilVal=Switch&0x01;break;
case 1: CoilVal=Switch>>1&0x01;break;
case 2: CoilVal=Switch>>2&0x01;break;
case 3: CoilVal=Switch>>3&0x01;break;
case 4: CoilVal=Switch>>4&0x01;break;
case 5: CoilVal=Switch>> 31、5&0x01;break;
case 6: CoilVal=Switch>>6&0x01;break;
case 7: CoilVal=Switch>>7&0x01;break;
case 8: CoilVal=Switch>>8&0x01;break;
case 9: CoilVal=Switch>>9&0x01;break;
case 10: CoilVal=Switch>>10&0x01;break;
case 11: CoilVal=Switch>>11&0x01;break;
case 12: CoilVal=Switch>>12&0 32、x01;break;
case 13: CoilVal=Switch>>13&0x01;break;
case 14: CoilVal=Switch>>14&0x01;break;
case 15: CoilVal=Switch>>15&0x01;break;
default: break;
}
return CoilVal;
}
/********************************************
Function:强制单线圈值子函数
Input:线圈地址,强制值
Output:结果值
******************** 33、/
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_ 34、bit5=Val;break;
case 6: Coil1_bit6=Val;break;
case 7: Coil1_bit7=Val;break;
case 8: Coil2_bit8=Val;break;
case 9: Coil2_bit9=Val;break;
case 10: Coil2_bit10=Val;break;
case 11: Coil2_bit11=Val;break;
case 12: Coil2_bit12=Val;break;
case 13: Coil2_bit13=Val;break;
case 35、14: Coil2_bit14=Val;break;
case 15: Coil2_bit15=Val;break;
default: result=0;break;
}
P1=Coil1;
return result;
}
/********************************************
Function:设置单寄存器值子函数
Input:寄存器地址,值
Output:结果值
********************************************/
bit SetRegisterVal(uint Address1,uint Val1)
{
uchar Addr;
bit result1=1;
Addr=Address1&0x0f;
if(Addr<16)
ReWrbuf[Addr]=Val1;
else
result1=0;
return result1;
}






