《modbus(C语言程序)(30页).doc》由会员分享,可在线阅读,更多相关《modbus(C语言程序)(30页).doc(32页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、-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 char data ReceiveData14;unsigned char data countn
2、umber;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, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x0
3、1, 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,0x00, 0xC1, 0x81, 0x
4、40, 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, 0
5、x81, 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, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00,
6、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, 0x00, 0xC1,0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
7、 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, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,0x0F,
8、 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, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,0xF2, 0x32
9、, 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, 0xE
10、3, 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, 0x
11、BD, 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, 0
12、x88, 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 usDataLen)函数说明:CRC校验-*/unsigned int CRC16(unsigne
13、d 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 auchCRCHiuIndex ; uchCRCLo = auchCRCLouIndex ; return
14、 (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(Outlength-) TI=0; ACC=*output; TB8=P; SBUF=*(output
15、+); 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 *send; unsigned int data temp; unsigned char da
16、ta 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状态数据 *(send+3+length)=(char)(temp8); /CRC校验高 *(send+
17、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; unsigned int data temp; send=ReceiveData; *(send+2
18、)=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) unsigned char data i; unsigned char data *send; uns
19、igned 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; unsigned char data *WriteData; temp=2*address; WriteDa
20、ta=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(char ErrorCode) unsigned char data *send; unsigne
21、d 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() unsigned int data temp; unsigned char data address; uns
22、igned 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=Pointer3; length=Pointer5; if(addressNumber&0x01=1)
23、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 Init_timer2(unsigned int baudrate)函数说明:定时器2的初始化-*/
24、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=1; / T2CON.2 start timer ET2=0; / 开定时器2中断/*-调用方式
25、: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 = TimReg2; / 定时器1,在11.0592MHz下,波特率为9600 TL1 = TH1; TR1=
26、 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 using 0 if(RI) if(TimeInterval2)&(TimeInterval60)
27、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第 32 页-