51单片机实现Modbus从机程序.docx
- 文档编号:26820972
- 上传时间:2023-06-23
- 格式:DOCX
- 页数:14
- 大小:16.85KB
51单片机实现Modbus从机程序.docx
《51单片机实现Modbus从机程序.docx》由会员分享,可在线阅读,更多相关《51单片机实现Modbus从机程序.docx(14页珍藏版)》请在冰豆网上搜索。
51单片机实现Modbus从机程序
自己用单片机做的Modbus从机,可以使用STC89C52。
实现了命令码为1、2、3、4、5、6的功能,程序中有些是我们局部其他功能的函数和数据,希望大家参考下编程的思想。
uintSwitch=0*bc95;//开关状态
ucharbdataCoil1=0*ff,Coil2=0*bc;//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[]={0*00,0*01,0*02,0*03,0*04,0*05,0*06,0*07,0*08,0*09,0*0a,0*0b,0*0c,0*0d,0*0e,0*0f};
uintidataReWrbuf[]={0*00,0*01,0*02,0*03,0*04,0*05,0*06,0*07,0*08,0*09,0*0a,0*0b,0*0c,0*0d,0*0e,0*0f};
//CRC校验查表码值
constucharcodeauchCRCHi[]={
0*00,0*C1,0*81,0*40,0*01,0*C0,0*80,0*41,0*01,0*C0,
0*80,0*41,0*00,0*C1,0*81,0*40,0*01,0*C0,0*80,0*41,
0*00,0*C1,0*81,0*40,0*00,0*C1,0*81,0*40,0*01,0*C0,
0*80,0*41,0*01,0*C0,0*80,0*41,0*00,0*C1,0*81,0*40,
0*00,0*C1,0*81,0*40,0*01,0*C0,0*80,0*41,0*00,0*C1,
0*81,0*40,0*01,0*C0,0*80,0*41,0*01,0*C0,0*80,0*41,
0*00,0*C1,0*81,0*40,0*01,0*C0,0*80,0*41,0*00,0*C1,
0*81,0*40,0*00,0*C1,0*81,0*40,0*01,0*C0,0*80,0*41,
0*00,0*C1,0*81,0*40,0*01,0*C0,0*80,0*41,0*01,0*C0,
0*80,0*41,0*00,0*C1,0*81,0*40,0*00,0*C1,0*81,0*40,
0*01,0*C0,0*80,0*41,0*01,0*C0,0*80,0*41,0*00,0*C1,
0*81,0*40,0*01,0*C0,0*80,0*41,0*00,0*C1,0*81,0*40,
0*00,0*C1,0*81,0*40,0*01,0*C0,0*80,0*41,0*01,0*C0,
0*80,0*41,0*00,0*C1,0*81,0*40,0*00,0*C1,0*81,0*40,
0*01,0*C0,0*80,0*41,0*00,0*C1,0*81,0*40,0*01,0*C0,
0*80,0*41,0*01,0*C0,0*80,0*41,0*00,0*C1,0*81,0*40,
0*00,0*C1,0*81,0*40,0*01,0*C0,0*80,0*41,0*01,0*C0,
0*80,0*41,0*00,0*C1,0*81,0*40,0*01,0*C0,0*80,0*41,
0*00,0*C1,0*81,0*40,0*00,0*C1,0*81,0*40,0*01,0*C0,
0*80,0*41,0*00,0*C1,0*81,0*40,0*01,0*C0,0*80,0*41,
0*01,0*C0,0*80,0*41,0*00,0*C1,0*81,0*40,0*01,0*C0,
0*80,0*41,0*00,0*C1,0*81,0*40,0*00,0*C1,0*81,0*40,
0*01,0*C0,0*80,0*41,0*01,0*C0,0*80,0*41,0*00,0*C1,
0*81,0*40,0*00,0*C1,0*81,0*40,0*01,0*C0,0*80,0*41,
0*00,0*C1,0*81,0*40,0*01,0*C0,0*80,0*41,0*01,0*C0,
0*80,0*41,0*00,0*C1,0*81,0*40};
constucharcodeauchCRCLo[]={
0*00,0*C0,0*C1,0*01,0*C3,0*03,0*02,0*C2,0*C6,0*06,
0*07,0*C7,0*05,0*C5,0*C4,0*04,0*CC,0*0C,0*0D,0*CD,
0*0F,0*CF,0*CE,0*0E,0*0A,0*CA,0*CB,0*0B,0*C9,0*09,
0*08,0*C8,0*D8,0*18,0*19,0*D9,0*1B,0*DB,0*DA,0*1A,
0*1E,0*DE,0*DF,0*1F,0*DD,0*1D,0*1C,0*DC,0*14,0*D4,
0*D5,0*15,0*D7,0*17,0*16,0*D6,0*D2,0*12,0*13,0*D3,
0*11,0*D1,0*D0,0*10,0*F0,0*30,0*31,0*F1,0*33,0*F3,
0*F2,0*32,0*36,0*F6,0*F7,0*37,0*F5,0*35,0*34,0*F4,
0*3C,0*FC,0*FD,0*3D,0*FF,0*3F,0*3E,0*FE,0*FA,0*3A,
0*3B,0*FB,0*39,0*F9,0*F8,0*38,0*28,0*E8,0*E9,0*29,
0*EB,0*2B,0*2A,0*EA,0*EE,0*2E,0*2F,0*EF,0*2D,0*ED,
0*EC,0*2C,0*E4,0*24,0*25,0*E5,0*27,0*E7,0*E6,0*26,
0*22,0*E2,0*E3,0*23,0*E1,0*21,0*20,0*E0,0*A0,0*60,
0*61,0*A1,0*63,0*A3,0*A2,0*62,0*66,0*A6,0*A7,0*67,
0*A5,0*65,0*64,0*A4,0*6C,0*AC,0*AD,0*6D,0*AF,0*6F,
0*6E,0*AE,0*AA,0*6A,0*6B,0*AB,0*69,0*A9,0*A8,0*68,
0*78,0*B8,0*B9,0*79,0*BB,0*7B,0*7A,0*BA,0*BE,0*7E,
0*7F,0*BF,0*7D,0*BD,0*BC,0*7C,0*B4,0*74,0*75,0*B5,
0*77,0*B7,0*B6,0*76,0*72,0*B2,0*B3,0*73,0*B1,0*71,
0*70,0*B0,0*50,0*90,0*91,0*51,0*93,0*53,0*52,0*92,
0*96,0*56,0*57,0*97,0*55,0*95,0*94,0*54,0*9C,0*5C,
0*5D,0*9D,0*5F,0*9F,0*9E,0*5E,0*5A,0*9A,0*9B,0*5B,
0*99,0*59,0*58,0*98,0*88,0*48,0*49,0*89,0*4B,0*8B,
0*8A,0*4A,0*4E,0*8E,0*8F,0*4F,0*8D,0*4D,0*4C,0*8C,
0*44,0*84,0*85,0*45,0*87,0*47,0*46,0*86,0*82,0*42,
0*43,0*83,0*41,0*81,0*80,0*40};
/********************************************
Function:
CRC校验子函数
Input:
要校验的数组起始地址长度
Output:
16位校验码〔高位在前〕
********************************************/
uintcrccheck(uchar*puchMsg,ucharusDataLen)
{
ucharuchCRCHi=0*FF;
ucharuchCRCLo=0*FF;
ucharuInde*;
while(usDataLen--)
{
uInde*=uchCRCHi^*puchMsg++;
uchCRCHi=uchCRCLo^auchCRCHi[uInde*];
uchCRCLo=auchCRCLo[uInde*];
}
return(uchCRCHi<<8|uchCRCLo);
}
/********************************************
Function:
读线圈状态子函数
Input:
无
Output:
无
********************************************/
voidReadCoil(void)
{
uintStartAddress,tempAddress;
ucharCoilNum,i,ByteNum,j;
ucharCoilVal;
bite*it=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]==0*01)
{
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) { e*it=1; break; } } if(e*it==1) break; } } elseif(resvbuf[1]==0*02) { 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) { e*it=1; break; } } if(e*it==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]==0*03) for(i=0;i { Sendbuf[i+4]=ReWrbuf[StartAddress]&0*ff; Sendbuf[i+3]=ReWrbuf[StartAddress]>>8; StartAddress++; } elseif(resvbuf[1]==0*04) 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==0*0000) { CoilVal=0; temp=SetCoilVal(Address,CoilVal); } elseif(OnOff==0*FF00) { 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&0*0f) { 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=0*ff; SW1=P2; Switch=SW2<<8|SW1; switch(Address1&0*0f) { case0: CoilVal=Switch&0*01;break; case1: CoilVal=Switch>>1&0*01;break; case2: CoilVal=Switch>>2&0*01;break; case3: CoilVal=Switch>>3&0*01;break; case4: CoilVal=Switch>>4&0*01;break; case5: CoilVal=Switch>>5&0*01;break; case6: CoilVal=Switch>>6&0*01;break; case7: CoilVal=Switch>>7&0*01;break; case8: CoilVal=Switch>>8&0*01;break; case9: CoilVal=Switch>>9&0*01;break; case10: CoilVal=Switch>>10&0*01;break; case11: CoilVal=Switch>>11&0*01;break; case12: CoilVal=Switch>>12&0*01;break; case13: CoilVal=Switch>>13&0*01;break; case14: CoilVal=Switch>>14&0*01;break; case15: CoilVal=Switch>>15&0*01;break; default: break; } returnCoilVal; } /******************************************** Function: 强制单线圈值子函数 Input: 线圈地址,强制值 Output: 结果值 ********************************************/ bitSetCoilVal(uintAddress,bitVal) { bitresult=1; switch(Address&0*0f) { 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_bit8=Val
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 51 单片机 实现 Modbus 程序