《modbus(C语言程序)共11页.doc》由会员分享,可在线阅读,更多相关《modbus(C语言程序)共11页.doc(11页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、如有侵权,请联系网站删除,仅供学习与交流modbus(C语言程序)【精品文档】第 11 页modbus(C语言程序)2009-10-15 09:31:28|分类:默认分类|字号订阅#include #include/_nop_();#define OSFREQ 11059200char TimeInterval;char MyAddress;char data DI6=1,2,3,4,5,6;char data DO6=6,7,8,9,10,11;char data AI6=11,12,13,14,15,16;char data AO6=16,17,18,19,20,21;unsigned c
2、har data ReceiveData14;unsigned char data countnumber;sbit Recenable =P16;/控制端 sbit led =P27;/控制端/*-函数说明:CRC 高位字节值表-*/static unsigned char code auchCRCHi = 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 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, 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, 0
4、x40, 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,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
5、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,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01,
6、 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, 0x01, 0xC0, 0x80, 0x41
7、, 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低位字节值表-*/static unsigned char code auchCRCLo = 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,0x07, 0xC7, 0x05
8、, 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, 0xD3,0x11, 0xD1, 0xD0, 0x1
9、0, 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, 0x
10、25, 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, 0
11、x7B, 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,
12、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;/*-调用方式:unsigned int CRC16(unsigned char *puchMsg, unsigned int u
13、sDataLen)函数说明:CRC校验-*/unsigned int CRC16(unsigned char *puchMsg, unsigned int usDataLen) unsigned char uchCRCHi = 0xFF ; / 高CRC字节初始化 unsigned char uchCRCLo = 0xFF ; / 低CRC 字节初始化 unsigned uIndex ; / CRC循环中的索引 while (usDataLen-) / 传输消息缓冲区 uIndex = uchCRCHi *puchMsg+ ; / 计算CRC uchCRCHi = uchCRCLo auchC
14、RCHiuIndex ; uchCRCLo = auchCRCLouIndex ; return (uchCRCHi 3); temp=*(Myaddress+temp); temp=(Offset); if (temp&0x01) return 1; else return 0;/*-调用方式:void SendData(unsigned char *output,unsigned char Outlength)函数说明:发送数据至窗口-*/void SendData(unsigned char *output,unsigned char Outlength) ES=0; while(Out
15、length-) TI=0; ACC=*output; TB8=P; SBUF=*(output+); while(!TI); TI=0; ES=1;/*-调用方式:void Function12(unsigned char address,unsigned char len)函数说明:功能码1,2处理-*/void Function12(unsigned char address,unsigned char len) unsigned int data i; unsigned char data j; unsigned char data length; unsigned char data
16、 *send; unsigned int data temp; unsigned char data function; length=0; send=ReceiveData; function=send1; for (i=1;i=len;i+) length+; *(send+2+length)=0; for (j=0;j8;j+) *(send+2+length)=*(send+2+length)|getbit(address,function)len)break; i-; *(send+2)=length; /数据长度 temp=CRC16(send,length+3); /DI状态数据
17、 *(send+3+length)=(char)(temp8); /CRC校验高 *(send+4+length)=(char)temp; /CRC校验低 SendData(send,length+5); /调用A发送程序/*-调用方式:void Function3(unsigned char address,unsigned char len)函数说明:功能码3处理-读取寄存器-*/void Function3(unsigned char address,unsigned char len) unsigned char data i; unsigned char data *send; un
18、signed int data temp; send=ReceiveData; *(send+2)=2*len; /数据长度高 address=2*address; for(i=0;i8); *(send+4+2*len)=(char)temp; SendData(send,2*len+5); /调用A发送程序/*-调用方式:void Function4(unsigned char address,unsigned char len)函数说明:功能码处理4-读取输入寄存器-*/void Function4(unsigned char address,unsigned char len) uns
19、igned char data i; unsigned char data *send; unsigned int data temp; send=ReceiveData; *(send+2)=2*len; address=2*address; for(i=0;i8); *(send+4+2*len)=(char)temp; SendData(send,2*len+5);/*-调用方式:void Function6(unsigned char address)函数说明:写单路寄存器-*/void Function6(unsigned char address) int temp; unsign
20、ed char data *WriteData; temp=2*address; WriteData=AO; /将写入的数据进行处理 /your code to add here to deal with the write value *(WriteData+temp)=ReceiveData4; *(WriteData+temp+1)=ReceiveData5; SendData(ReceiveData,countnumber); /调用发送程序,返回与主机相同的报文/*-调用方式:void SendError(char ErrorCode)函数说明:-*/void SendError(c
21、har ErrorCode) unsigned char data *send; unsigned int data temp; send=ReceiveData; *(send+1)=ReceiveData1|0x01;/最高位置1 *(send+2)=ErrorCode; temp=CRC16(send,3); *(send+3)=(char)(temp8); *(send+4)=(char)temp; SendData(send,countnumber); /调用发送程序,返回错误代码/*-调用方式:void Deal()函数说明:接收数据处理-*/void Deal() unsigne
22、d int data temp; unsigned char data address; unsigned char data length; unsigned char data counter; unsigned char data *Pointer; Pointer=ReceiveData; counter=countnumber; if (counter=3 ) return; temp=Pointercounter-28; temp= temp|Pointercounter-1; if( temp=CRC16(Pointer,counter-2) /较验正确 address=Poin
23、ter3; length=Pointer5; if(addressNumber&0x01=1) return 1; else return 0;/设定某一位的值*unsigned char SetBit(unsigned char Character,unsigned char num,bit boolen) unsigned char code bit_value=1,2,4,8,16,32,64,128; if(boolen) return Character|bit_valuenum; else return Character&bit_valuenum;*/*-调用方式:void In
24、it_timer2(unsigned int baudrate)函数说明:定时器2的初始化-*/void Init_timer2(unsigned int baudrate) unsigned int data TimReg2; T2CON = 0x00; T2MOD = 0x00; TimReg2=65536-(OSFREQ/384/baudrate*11); RCAP2L=TimReg2&0x00ff; RCAP2H=(TimReg28); /RCAP2H=TimReg2/256 RCAP2L=0;RCAP2H=0; TL2 = RCAP2L; / TH2 = RCAP2H; / TR2=
25、1; / T2CON.2 start timer ET2=0; / 开定时器2中断/*-调用方式:void Init_SerialPort(unsigned int baudrate)函数说明:串口初始化-*/void Init_SerialPort(unsigned int baudrate) unsigned char TimReg2; SCON = 0xd0; / 方式3, 8-bit UART, enable rcvr TMOD = 0x21; / T0方式1(16位), T1方式2,8位重装 TimReg2=256-(OSFREQ/384/baudrate); TH1 = TimRe
26、g2; / 定时器1,在11.0592MHz下,波特率为9600 TL1 = TH1; TR1= 1; / TR1: 定时开始 /PS=1; / 串行中断优先 ES=1; / 接收中断/*-函数说明:主函数-*/main() EA=1; /开总中断 Init_SerialPort(9600); Init_timer2(9600); Recenable=0; /接收允许 MyAddress=0x01; /本机地址 while(1) /*-调用方式:void SeiralA() interrupt 4 using 0函数说明:通讯中断-*/void SeiralA() interrupt 4 us
27、ing 0 if(RI) if(TimeInterval2)&(TimeInterval60) countnumber=0; ReceiveDatacountnumber+=SBUF; /将接收到的数据到缓冲区内 TimeInterval=0; RI=0; ET2=1; /当接收到数据后,将定时器2开启 /*-调用方式:void SerialPortTime() interrupt 5 using 0函数说明:定时器2中断程序-*/void SerialPortTime() interrupt 5 using 0 ET2=0; /定时器2中断允许控制 TimeInterval=TimeInterval+1; if(TimeInterval4) & countnumber) Recenable=1; /发送 Deal(); /将接收到的数据进行处理 Recenable=0; /接收 countnumber=0; else ET2=1; /将定时器2打开 TF2=0; /定时器2溢出标志,软件清0
限制150内