单片机modbus例程解析.doc

上传人:白大夫 文档编号:3398109 上传时间:2019-08-21 格式:DOC 页数:18 大小:77.50KB
返回 下载 相关 举报
单片机modbus例程解析.doc_第1页
第1页 / 共18页
亲,该文档总共18页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《单片机modbus例程解析.doc》由会员分享,可在线阅读,更多相关《单片机modbus例程解析.doc(18页珍藏版)》请在三一文库上搜索。

1、单片机modbus例程解析#include#defineuint8unsignedchar#defineuint16unsignedint#defineFOSC16000000uint16BAUD=9600;uint16TEMP_Alert=1000;/字地址0-255(只取低8位)/位地址0-255(只取低8位)/*CRC高位字节值表*/constuint8codeauchCRCHi=0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0/*/,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x

2、00,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,0x

3、00,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,0x

4、01,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,0x

5、01,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;/*CRC低位字节值表*/constuint

6、8codeauchCRCLo=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,0x

7、D2,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,0x

8、27,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,0x

9、B4,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,0x

10、8D,0x4D,0x4C,0x8C,0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,0x43,0x83,0x41,0x81,0x80,0x40;uint16TempRegister;/用于测试字址址16uint8localAddr=0x01;/单片机控制板的地址uint8sendCount;/发送字节个数uint8receCount;/接收到的字节个数/uint8sendPosi;/发送位置uint8xdatareceBuf1;uint8xdatasendBuf1;voidcheckComm0Modbus(void);uint16getReg

11、isterVal(uint16addr,uint16*tempData);uint16setRegisterVal(uint16addr,uint16tempData);voidswitch_BAUD(uint16value);/*波特率调整函数*/函数功能:调整串口通信波特率/串口工作在工作方式1,即8位波特率可变模式/*/voidswitch_BAUD(uint16value)switch(value)case0x0001:BAUD=9600;break;case0x0002:BAUD=14400;break;case0x0003:BAUD=19200;break;TR1=0;/停止定时器

12、1ES=0;/关闭串口中断TH1=TL1=-(FOSC/12/32/BAUD);/设置波特率TR1=1;/开启定时器1ES=1;/使能串口中断/*end*/*CRC校验码生成函数*/函数功能:生成CRC校验码/本代码中使用查表法,以提高运算速度/*/uint16crc16(uint8*puchMsg,uint16usDataLen)uint8uchCRCHi=0xFF;/*高CRC字节初始化*/uint8uchCRCLo=0xFF;/*低CRC字节初始化*/uint16uIndex;/*end*/*串口发送函数*/函数功能:将数据包通过串口发送至主机/有待修改。.。./*/开始发送voidBe

13、gin_send(void)uint16i=0;while(sendCount-)SBUF=sendBufi+;while(!TI);/*end*/*从机响应主机问询函数,funcTIoncode:03,读取多个寄存器值*/函数功能:丛机根据串口接收到的数据包receBuf里面的内容,根据被读取寄存器/的起始地址和读取的寄存器个数,去读相应的寄存器的值,并将读取的数据以MODBUS/响应数据的标准格式打包,经过串口发送到主机。数据包格式同上。/*/询问数据包格式:/receBuf0receBuf1receBuf2receBuf3receBuf4receBuf5receBuf6receBuf7/

14、询问数据格式:receBuf=从站地址,功能码,起始地址高位,起始地址低位,寄存器数高位,寄存器数低位,校验码低位,校验码高位/响应数据包格式:/sendBuf0sendBuf1sendBuf2sendBuf3sendBuf4sendBuf5。.receBuf6receBuf7/响应数据格式:receBuf=从站地址,功能码,字节计数,数据1,数据2,数据3,。.校验码低位,校验码高位voidreadRegisters(void)uint8addr;uint8tempAddr;uint16crcData;uint8readCount;uint8byteCount;uint16i;uint16t

15、empData=0;/addr=(receBuf28)+receBuf3;/tempAddr=addraddr=receBuf3;tempAddr=addr;/readCount=(receBuf48)+receBuf5;/要读的个数readCount=receBuf5;byteCount=readCount*2;/每个寄存器内容占高,低两个字节for(i=0;igetRegisterVal(tempAddr,sendBufi+3=tempData8;sendBufi+4=tempDatasendBuf0=localAddr;sendBuf1=3;/funcTIoncode:03sendBuf

16、2=byteCount;byteCount+=3;/加上前面的地址,功能码,地址共3+byteCount个字节crcData=crc16(sendBuf,byteCount);sendBufbyteCount=crcData/CRC代码低位在前byteCount+;sendBufbyteCount=crcData8;/高位在后sendCount=byteCount+1;/例如byteCount=49,则sendBuf中实际上有49+1个元素待发Begin_send();/voidreadRegisters(void)/*end*/*从机响应主机问询函数,funcTIoncode:16,设置多个

17、寄存器值*/函数功能:丛机根据串口接收到的数据包receBuf里面的内容,根据被强制寄存器/的起始地址,去设置相应寄存器的值,响应数据包同询问数据包/的内容相同,经过串口发送到主机。/*/询问数据包格式:/receBuf0receBuf1receBuf2receBuf3receBuf4receBuf5receBuf6receBuf7receBuf8。.receBuf9receBuf10/询问数据格式:receBuf=从站地址,功能码,起始地址高位,起始地址低位,寄存器数高位,寄存器数低位,字节计数,数据高位,数据低位,。.校验码低位,校验码高位/响应数据包内容为除去询问数据包中的字节计数和数据

18、高低位的其他内容voidpresetMulTIpleRegisters(void)uint8addr;uint8tempAddr;uint8byteCount;uint8setCount;uint16crcData;uint16tempData;uint8i;/addr=(receBuf28)+receBuf3;/tempAddr=addraddr=receBuf3;tempAddr=addr/setCount=(receBuf48)+receBuf5;setCount=receBuf5;byteCount=receBuf6;for(i=0;itempData=(receBufi*2+78)+

19、receBufi*2+8;/待设置寄存器值setRegisterVal(tempAddr,tempData);sendBuf0=localAddr;sendBuf1=16;/functioncode:16sendBuf2=addr8;/寄存器地址高位sendBuf3=addr/寄存器地址低位sendBuf4=setCount8;/待设置寄存器数量高位sendBuf5=setCount/待设置寄存器数量低位crcData=crc16(sendBuf,6);/生成CRC校验码sendBuf6=crcData/CRC代码低位在前sendBuf7=crcData8;/高位在后sendCount=8;B

20、egin_send();/voidpresetMultipleRegisters(void)/*end*/*查询uart接收的数据包内容函数*/函数功能:丛机根据串口接收到的数据包receBuf1里面的内容,即functioncode执行/相应的命令/*/voidcheckComm0Modbus(void)uint16crcData;uint16tempData;if(receCount4)switch(receBuf1)case3:/读取保持寄存器(一个或多个)if(receCount=8)/从询问数据包格式可知,receCount应该等于8/接收完成一组数据/应该关闭接收中断if(rece

21、Buf0=localAddr)/核对地址crcData=crc16(receBuf,6);/核对校验码if(crcData=receBuf7+(receBuf68)if(receBuf1=3)/读取保持寄存器(一个或多个)readRegisters();receCount=0;break;case16:/设置多个寄存器tempData=(receBuf48)+receBuf5;tempData=tempData*2;/数据个数tempData+=9;/从询问数据包格式可知,receCount应该等于9+byteCountif(receCount=tempData)if(receBuf0=loc

22、alAddr)crcData=crc16(receBuf,tempData-2);if(crcData=(receBuftempData-28)+receBuftempData-1)presetMultipleRegisters();receCount=0;break;default:break;/voidcheckComm0(void)/*end*/*读取寄存器内容函数*/函数功能:根据寄存器地址读取相应寄存器内容/*/取寄存器值返回0表示成功uint16getRegisterVal(uint16addr,uint16*tempData)uint16result=0;uint16tempAd

23、dr;tempAddr=addrswitch(tempAddrcase0x00:*tempData=TempRegister;break;/读取01开关A温度case0x01:*tempData=TempRegister;break;/读取01开关A温度case0x02:*tempData=TempRegister;break;/读取01开关A温度case0x03:*tempData=TempRegister;break;/读取01开关周边温度case0x04:*tempData=TempRegister;break;/读取02开关A温度case0x05:*tempData=TempRegis

24、ter;break;/读取02开关A温度case0x06:*tempData=TempRegister;break;/读取02开关A温度case0x07:*tempData=TempRegister;break;/读取02开关周边温度case0x08:*tempData=TempRegister;break;/读取03开关A温度case0x09:*tempData=TempRegister;break;/读取03开关A温度case0x0a:*tempData=TempRegister;break;/读取03开关A温度case0x0b:*tempData=TempRegister;break;/

25、读取03开关周边温度case0x0c:*tempData=TempRegister;break;/读取04开关A温度case0x0d:*tempData=TempRegister;break;/读取04开关A温度case0x0e:*tempData=TempRegister;break;/读取04开关A温度case0x0f:*tempData=TempRegister;break;/读取04开关周边温度case0x10:*tempData=TempRegister;break;/读取05开关A温度case0x11:*tempData=TempRegister;break;/读取05开关A温度c

26、ase0x12:*tempData=TempRegister;break;/读取05开关A温度case0x13:*tempData=TempRegister;break;/读取05开关周边温度case0x14:*tempData=TempRegister;break;/读取06开关A温度case0x15:*tempData=TempRegister;break;/读取06开关A温度case0x16:*tempData=TempRegister;break;/读取06开关A温度case0x17:*tempData=TempRegister;break;/读取06开关周边温度case0x18:*t

27、empData=TempRegister;break;/读取07开关A温度case0x19:*tempData=TempRegister;break;/读取07开关A温度case0x1a:*tempData=TempRegister;break;/读取07开关A温度case0x1b:*tempData=TempRegister;break;/读取07开关周边温度case0x1c:*tempData=TempRegister;break;/读取08开关A温度case0x1d:*tempData=TempRegister;break;/读取08开关A温度case0x1e:*tempData=Tem

28、pRegister;break;/读取08开关A温度case0x1f:*tempData=TempRegister;break;/读取08开关周边温度case0x20:*tempData=TempRegister;break;/读取09开关A温度case0x21:*tempData=TempRegister;break;/读取09开关A温度case0x22:*tempData=TempRegister;break;/读取09开关A温度case0x23:*tempData=TempRegister;break;/读取09开关周边温度case0x24:*tempData=TempRegister;

29、break;/读取10开关A温度case0x25:*tempData=TempRegister;break;/读取10开关A温度case0x26:*tempData=TempRegister;break;/读取10开关A温度case0x27:*tempData=TempRegister;break;/读取10开关周边温度case0x28:*tempData=TempRegister;break;/读取11开关A温度case0x29:*tempData=TempRegister;break;/读取11开关A温度case0x2a:*tempData=TempRegister;break;/读取11

30、开关A温度case0x2b:*tempData=TempRegister;break;/读取11开关周边温度case0x2c:*tempData=TempRegister;break;/读取12开关A温度case0x2d:*tempData=TempRegister;break;/读取12开关A温度case0x2e:*tempData=TempRegister;break;/读取12开关A温度case0x2f:*tempData=TempRegister;break;/读取12开关周边温度case0x30:*tempData=TempRegister;break;/读取13开关A温度case0

31、x31:*tempData=TempRegister;break;/读取13开关A温度case0x32:*tempData=TempRegister;break;/读取13开关A温度case0x33:*tempData=TempRegister;break;/读取13开关周边温度case0x34:*tempData=TempRegister;break;/读取14开关A温度case0x35:*tempData=TempRegister;break;/读取14开关A温度case0x36:*tempData=TempRegister;break;/读取14开关A温度case0x37:*tempDa

32、ta=TempRegister;break;/读取14开关周边温度case0x38:*tempData=TempRegister;break;/读取15开关A温度case0x39:*tempData=TempRegister;break;/读取15开关A温度case0x3a:*tempData=TempRegister;break;/读取15开关A温度case0x3b:*tempData=TempRegister;break;/读取15开关周边温度case0x3c:*tempData=TempRegister;break;/读取16开关A温度case0x3d:*tempData=TempReg

33、ister;break;/读取16开关A温度case0x3e:*tempData=TempRegister;break;/读取16开关A温度case0x3f:*tempData=TempRegister;break;/读取16开关周边温度case0x40:*tempData=TempRegister;break;/读取17开关A温度case0x41:*tempData=TempRegister;break;/读取17开关A温度case0x42:*tempData=TempRegister;break;/读取17开关A温度case0x43:*tempData=TempRegister;break

34、;/读取17开关周边温度case0x44:*tempData=TempRegister;break;/读取18开关A温度case0x45:*tempData=TempRegister;break;/读取18开关A温度case0x46:*tempData=TempRegister;break;/读取18开关A温度case0x47:*tempData=TempRegister;break;/读取18开关周边温度case0x48:*tempData=TempRegister;break;/读取19开关A温度case0x49:*tempData=TempRegister;break;/读取19开关A温

35、度case0x4a:*tempData=TempRegister;break;/读取19开关A温度case0x4b:*tempData=TempRegister;break;/读取19开关周边温度case0x4c:*tempData=TempRegister;break;/读取20开关A温度case0x4d:*tempData=TempRegister;break;/读取20开关A温度case0x4e:*tempData=TempRegister;break;/读取20开关A温度case0x4f:*tempData=TempRegister;break;/读取20开关周边温度case0x50:

36、*tempData=TempRegister;break;/读取21开关A温度case0x51:*tempData=TempRegister;break;/读取21开关A温度case0x52:*tempData=TempRegister;break;/读取21开关A温度case0x53:*tempData=TempRegister;break;/读取21开关周边温度case0x54:*tempData=TempRegister;break;/读取22开关A温度case0x55:*tempData=TempRegister;break;/读取22开关A温度case0x56:*tempData=T

37、empRegister;break;/读取22开关A温度case0x57:*tempData=TempRegister;break;/读取22开关周边温度case0x58:*tempData=TempRegister;break;/读取23开关A温度case0x59:*tempData=TempRegister;break;/读取23开关A温度case0x5a:*tempData=TempRegister;break;/读取23开关A温度case0x5b:*tempData=TempRegister;break;/读取23开关周边温度case0x5c:*tempData=TempRegiste

38、r;break;/读取24开关A温度case0x5d:*tempData=TempRegister;break;/读取24开关A温度case0x5e:*tempData=TempRegister;break;/读取24开关A温度case0x5f:*tempData=TempRegister;break;/读取24开关周边温度case0x60:*tempData=TempRegister;break;/读取25开关A温度case0x61:*tempData=TempRegister;break;/读取25开关A温度case0x62:*tempData=TempRegister;break;/读取

39、25开关A温度case0x63:*tempData=TempRegister;break;/读取25开关周边温度case0x64:*tempData=TempRegister;break;/读取26开关A温度case0x65:*tempData=TempRegister;break;/读取26开关A温度case0x66:*tempData=TempRegister;break;/读取26开关A温度case0x67:*tempData=TempRegister;break;/读取26开关周边温度case0x68:*tempData=TempRegister;break;/读取27开关A温度cas

40、e0x69:*tempData=TempRegister;break;/读取27开关A温度case0x6a:*tempData=TempRegister;break;/读取27开关A温度case0x6b:*tempData=TempRegister;break;/读取27开关周边温度case0x6c:*tempData=TempRegister;break;/读取28开关A温度case0x6d:*tempData=TempRegister;break;/读取28开关A温度case0x6e:*tempData=TempRegister;break;/读取28开关A温度case0x6f:*tempData=TempRegister;break;/读取28开关周边温度case0x70:*tempData=TempRegister;break;/读取29开关A温度case0x71:*tempData=TempRegister;break;/读取29开关A温度case0

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

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1