C语言编写modbus协议Word下载.docx
《C语言编写modbus协议Word下载.docx》由会员分享,可在线阅读,更多相关《C语言编写modbus协议Word下载.docx(21页珍藏版)》请在冰豆网上搜索。
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
uint8testCoil;
//用于测试位地址1
uint16testRegister;
//用于测试字址址16
uint8localAddr=1;
//单片机控制板的地址
uint8sendCount;
//发送字节个数
uint8receCount;
//接收到的字节个数
uint8sendPosi;
//发送位置
uint16crc16(uint8*puchMsg,uint16usDataLen)
{
uint8uchCRCHi=0xFF;
/*高CRC字节初始化*/
uint8uchCRCLo=0xFF;
/*低CRC字节初始化*/
uint32uIndex;
/*CRC循环中的索引*/
while(usDataLen--)/*传输消息缓冲区*/
uIndex=uchCRCHi^*puchMsg++;
/*计算CRC*/
uchCRCHi=uchCRCLo^auchCRCHi[uIndex];
uchCRCLo=auchCRCLo[uIndex];
}
return(uchCRCHi<
<
8|uchCRCLo);
}//uint16crc16(uint8*puchMsg,uint16usDataLen)
//开始发送
voidbeginSend(void)
b485Send=1;
//设为发送
sendPosi=0;
if(sendCount>
1)
sendCount--;
ACC=sendBuf[0];
TB8=P;
SBUF=sendBuf[0];
}//voidbeginSend(void)
//读线圈状态
voidreadCoil(void)
uint8addr;
uint8tempAddr;
uint8byteCount;
uint8bitCount;
uint16crcData;
uint8position;
uint8i,k;
uint8result;
uint16tempData;
uint8exit=0;
//addr=(receBuf[2]<
8)+receBuf[3];
//tempAddr=addr&
0xfff;
addr=receBuf[3];
tempAddr=addr;
//bitCount=(receBuf[4]<
8)+receBuf[5];
//读取的位个数
bitCount=receBuf[5];
byteCount=bitCount/8;
//字节个数
if(bitCount%8!
=0)
byteCount++;
for(k=0;
k<
byteCount;
k++)
{//字节位置
position=k+3;
sendBuf[position]=0;
for(i=0;
i<
8;
i++)
getCoilVal(tempAddr,&
tempData);
sendBuf[position]|=tempData<
i;
tempAddr++;
if(tempAddr>
=addr+bitCount)
{//读完
exit=1;
break;
if(exit==1)
sendBuf[0]=localAddr;
sendBuf[1]=0x01;
sendBuf[2]=byteCount;
byteCount+=3;
crcData=crc16(sendBuf,byteCount);
sendBuf[byteCount]=crcData>
>
sendBuf[byteCount]=crcData&
0xff;
sendCount=byteCount+1;
beginSend();
}//voidreadCoil(void)
/读寄存器
voidreadRegisters(void)
uint16result;
uint8readCount;
uint8finsh;
//1完成0出错
uint16i;
uint16tempData=0;
//readCount=(receBuf[4]<
//要读的个数
readCount=receBuf[5];
byteCount=readCount*2;
i+=2,tempAddr++)
getRegisterVal(tempAddr,&
sendBuf[i+3]=tempData>
sendBuf[i+4]=tempData&
sendBuf[1]=3;
}//voidreadRegisters(void)
//强制单个线圈
voidforceSingleCoil(void)
uint8onOff;
uint8i;
//onOff=(receBuf[4]<
onOff=receBuf[4];
//if(onOff==0xff00)
if(onOff==0xff)
{//设为ON
tempData=1;
//elseif(onOff==0x0000)
elseif(onOff==0x00)
{//设为OFF
tempData=0;
setCoilVal(tempAddr,tempData);
receCount;
sendBuf[i]=receBuf[i];
sendCount=receCount;
}//voidforceSingleCoil(void)
//设置多个寄存器
voidpresetMultipleRegisters(void)
uint8setCount;
//为1时完成为0时出错
tempAddr=addr&
//setCount=(receBuf[4]<
setCount=receBuf[5];
byteCount=receBuf[6];
setCount;
i++,tempAddr++)
tempData=(receBuf[i*2+7]<
8)+receBuf[i*2+8];
setRegisterVal(tempAddr,tempData);
sendBuf[1]=16;
sendBuf[2]=addr>
sendBuf[3]=addr&
sendBuf[4]=setCount>
sendBuf[5]=setCount&
crcData=crc16(sendBuf,6);
sendBuf[6]=crcData>
sendBuf[7]=crcData&
sendCount=8;
}//voidpresetMultipleRegisters(void)
//检查uart0数据
voidcheckComm0Modbus(void)
if(receCount>
4)
switch(receBuf[1])
case1:
//读取线圈状态(读取点16位以内)
case3:
//读取保持寄存器(一个或多个)
case5:
case6:
//设置单个寄存器
=8)
{//接收完成一组数据
//应该关闭接收中断
if(receBuf[0]==localAddr&
&
checkoutError==0)
crcData=crc16(receBuf,6);
if(crcData==receBuf[7]+(receBuf[6]<
8))
{//校验正确
if(receBuf[1]==1)
{//读取线圈状态(读取点16位以内)
readCoil();
elseif(receBuf[1]==3)
{//读取保持寄存器(一个或多个)
readRegisters();
elseif(receBuf[1]==5)
{//强制单个线圈
forceSingleCoil();
elseif(receBuf[1]==6)
//presetSingleRegister();
receCount=0;
checkoutError=0;
case15:
//设置多个线圈
tempData=receBuf[6];
tempData+=9;
//数据个数
=tempData)
crcData=crc16(receBuf,tempData-2);
if(crcData==(receBuf[tempData-2]<
8)+receBuf[tempData-1])
//forceMultipleCoils();
case16:
tempData=(receBuf[4]<
tempData=tempData*2;
presetMultipleRegisters();
default:
}//voidcheckComm0(void)
//取线圈状态返回0表示成功
uint16getCoilVal(uint16addr,uint16*tempData)
uint16result=0;
uint16tempAddr;
//只取低8位地址
switch(tempAddr&
0xff)
case0:
*tempData=testCoil;
case2:
case4:
case7:
case8:
case9:
case10:
case11:
case12:
case13:
case14:
returnresult;
}//uint16getCoilVal(uint16addr,uint16*data)
//设定线圈状态返回0表示成功
uint16setCoilVal(uint16addr,uint16tempData)
testCoil=tempData;
}//uint16setCoilVal(uint16addr,uint16data)
//取寄存器值返回0表示成功
uint16getRegisterVal(uint16addr,uint16*tempData)
*tempData=testRegister;
}//uint16getRegisterVal(uint16addr,uint16&
data)
//设置寄存器值返回0表示成功
uint16setRegisterVal(uint16addr,uint16tempData)
testRegister=tempData;
}//uin