|
晶振12M 波特率9200 可与组态王通信 组态王IO设备选择西门子S7-200 MODBUS(RTU)或支持MODBUS 协义的PLC
编译器为KEIL3
单片机型号:STC11F60XE
- #include<reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define _irol_(a,b) (a<<b)|(a>>16-b)
- #define BIT(A) (1<<A )
- #define D0 DW0[0]
- #define D1 DW0[1]
- #define D2 DW0[2]
- #define D3 DW0[3]
- #define D4 DW0[4]
- #define D5 DW0[5]
- #define D6 DW0[6]
- #define D7 DW0[7]
- #define D8 DW0[8]
- #define D9 DW0[9]
- #define D10 DW0[10]
- #define D11 DW0[11]
- #define D12 DW0[12]
- #define D13 DW0[13]
- #define D14 DW0[14]
- #define D15 DW0[15]
- #define D16 DW0[16]
- #define D17 DW0[17]
- #define D18 DW0[18]
- #define D19 DW0[19]
- #define D20 DW0[20]
- #define D21 DW0[21]
- #define D22 DW0[22]
- #define D23 DW0[23]
- #define D24 DW0[24]
- #define D25 DW0[25]
- #define D26 DW0[26]
- #define D27 DW0[27]
- #define D28 DW0[28]
- #define D29 DW0[29]
- #define D30 DW0[30]
- #define D31 DW0[31]
- unsigned long bdata M00=0xAAAADCBA;
- unsigned int idata DW0[32]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30} ;//_at_ 0x0000
-
- /*sbit p10=P1^0;
- sbit p11=P1^1; */
- sbit p12=P1^2;
- sbit p13=P1^3;
- sbit p14=P1^4;
-
- uchar ac;
- uchar at;//结束接收计时;
- uint b;
- uchar *p;
- uchar uartR[80]={2};//接收缓冲区;
- bit fcbz;//启动发送标志,发送结束需清零;
- bit fcz;//发送中标志位;
- uchar fc;//发送数据个数;
- uchar fc1;//发送数据现在数;
- bit a1;//数据接收中标志位;
- bit a2;//数据接收结束标志位;
- bit crc1;//crc校验正确位;1有效;
- sfr BRT=0X9C;
- sfr AUXR1=0XA2;
- sfr AUXR=0X8E;
- uchar code suzhu[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x7f};
- sbit P07=P0^7;
- void delay(uint a) //延时函数;
- {
- while(a--);
- }
- void time0() interrupt 1 //定时器0中断服务程序,用于提供通信接收空闲结束时钟等;
- {
- TH0=0XFE;
- TL0=0X0C;
- if(a1)
- {
- at++;
- if(at>=100) //50毫秒无数据流,完成接收;
- {a1=0;
- a2=1;
- at=0;
- }
- }
- if(M00&BIT(0))
- {
- b++;
- if(b==1000)
- {
- b=0;
- if(M00&BIT(1))M00&=~BIT(1);
- else M00|=BIT(1);
- }
- if(M00&BIT(1))P07=!P07;
- else P07=1;
- }
- else P07=1;
- }
- void uartinit() //串口初始化;
- {
- SCON=0X50;
- PCON = 0x80;
- AUXR=0X15;
- BRT=217;
- EA=1;
- ES=1;
- }
- uint crc16(unsigned char *p,A) //调用时把校验数据首地址送给指针p,校验数据个数送给A;
- {
- uint code pp[256]={0x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241,
- 0xC601,0x06C0,0x0780,0xC741,0x0500,0xC5C1,0xC481,0x0440,
- 0xCC01,0x0CC0,0x0D80,0xCD41,0x0F00,0xCFC1,0xCE81,0x0E40,
- 0x0A00,0xCAC1,0xCB81,0x0B40,0xC901,0x09C0,0x0880,0xC841,
- 0xD801,0x18C0,0x1980,0xD941,0x1B00,0xDBC1,0xDA81,0x1A40,
- 0x1E00,0xDEC1,0xDF81,0x1F40,0xDD01,0x1DC0,0x1C80,0xDC41,
- 0x1400,0xD4C1,0xD581,0x1540,0xD701,0x17C0,0x1680,0xD641,
- 0xD201,0x12C0,0x1380,0xD341,0x1100,0xD1C1,0xD081,0x1040,
- 0xF001,0x30C0,0x3180,0xF141,0x3300,0xF3C1,0xF281,0x3240,
- 0x3600,0xF6C1,0xF781,0x3740,0xF501,0x35C0,0x3480,0xF441,
- 0x3C00,0xFCC1,0xFD81,0x3D40,0xFF01,0x3FC0,0x3E80,0xFE41,
- 0xFA01,0x3AC0,0x3B80,0xFB41,0x3900,0xF9C1,0xF881,0x3840,
- 0x2800,0xE8C1,0xE981,0x2940,0xEB01,0x2BC0,0x2A80,0xEA41,
- 0xEE01,0x2EC0,0x2F80,0xEF41,0x2D00,0xEDC1,0xEC81,0x2C40,
- 0xE401,0x24C0,0x2580,0xE541,0x2700,0xE7C1,0xE681,0x2640,
- 0x2200,0xE2C1,0xE381,0x2340,0xE101,0x21C0,0x2080,0xE041,
- 0xA001,0x60C0,0x6180,0xA141,0x6300,0xA3C1,0xA281,0x6240,
- 0x6600,0xA6C1,0xA781,0x6740,0xA501,0x65C0,0x6480,0xA441,
- 0x6C00,0xACC1,0xAD81,0x6D40,0xAF01,0x6FC0,0x6E80,0xAE41,
- 0xAA01,0x6AC0,0x6B80,0xAB41,0x6900,0xA9C1,0xA881,0x6840,
- 0x7800,0xB8C1,0xB981,0x7940,0xBB01,0x7BC0,0x7A80,0xBA41,
- 0xBE01,0x7EC0,0x7F80,0xBF41,0x7D00,0xBDC1,0xBC81,0x7C40,
- 0xB401,0x74C0,0x7580,0xB541,0x7700,0xB7C1,0xB681,0x7640,
- 0x7200,0xB2C1,0xB381,0x7340,0xB101,0x71C0,0x7080,0xB041,
- 0x5000,0x90C1,0x9181,0x5140,0x9301,0x53C0,0x5280,0x9241,
- 0x9601,0x56C0,0x5780,0x9741,0x5500,0x95C1,0x9481,0x5440,
- 0x9C01,0x5CC0,0x5D80,0x9D41,0x5F00,0x9FC1,0x9E81,0x5E40,
- 0x5A00,0x9AC1,0x9B81,0x5B40,0x9901,0x59C0,0x5880,0x9841,
- 0x8801,0x48C0,0x4980,0x8941,0x4B00,0x8BC1,0x8A81,0x4A40,
- 0x4E00,0x8EC1,0x8F81,0x4F40,0x8D01,0x4DC0,0x4C80,0x8C41,
- 0x4400,0x84C1,0x8581,0x4540,0x8701,0x47C0,0x4680,0x8641,
- 0x8201,0x42C0,0x4380,0x8341,0x4100,0x81C1,0x8081,0x4040};
- uchar i;
- uint arc, crc;
- crc=0xffff;
- for (i=0;i<A;i++ )
- {
- arc= (p[i]^crc)&0x00ff;
- crc=_irol_(crc,8);
- crc= crc & 0x00ff;
- crc= crc^pp[arc];
- }
- return(crc);
- }
- void modbus1(unsigned char *p,unsigned long M00) //功能码1(读线圈)处理函数;
- {
- unsigned int A,B;
- unsigned char i,y,u;
-
- B=p[4];
- B=B<<8|p[5];//取线圈个数;
- A=p[2];
- A=A<<8|p[3]; //取线圈地址;
- if(B>0&&B<33)
- {
- if(A>=0&&A+B<33)
- {
- fc=B/8;
- for(i=0;i<fc;i++)
- {
- u=0;
- for(y=0;y<8;y++)
- {
- u>>=1;
- if((M00>>A)&0x01 )u|=0x80;
- A++;
- }
- p[i+3]=u;
- }
- if(B%8)
- {
- fc+=1;
- u=0;
- for(y=0;y<B%8;y++)
- {
- if((M00>>A)&0x01 )u|=0x01<<y;
- A++;
- }
- p[fc+2]=u;
- }
- p[2]=fc;
- fc+=3;
- }
- else
- {
- p[1]=0x81;
- p[2]=0x02;
- fc=3;
- }
- }
- else
- {
- p[1]=0x81;
- p[2]=0x03;
- fc=3;
- }
- }
- void modbus2(unsigned char *p,unsigned long M00)//功能码2(读输入离散)处理函数;
- {
- unsigned int A,B;
- unsigned char i,y,u;
-
- B=p[4];
- B=B<<8|p[5];//取IO离散个数;
- A=p[2];
- A=A<<8|p[3];//取IO离散地址;
- if(B>0&&B<33)
- {
- if(A>=0&&A+B<33)
- {
- fc=B/8;
- for(i=0;i<fc;i++)
- {
- u=0;
- for(y=0;y<8;y++)
- {
- u>>=1;
- if((M00>>A)&0x01 )u|=0x80;
- A++;
- }
- p[i+3]=u;
- }
- if(B%8)
- {
- fc+=1;
- u=0;
- for(y=0;y<B%8;y++)
- {
- if((M00>>A)&0x01 )u|=0x01<<y;
- A++;
- }
-
- p[fc+2]=u;
- }
- p[2]=fc;
- fc+=3;
- }
- else
- {
- p[1]=0x82;
- p[2]=0x02;
- fc=3;
- }
- }
- else
- {
- p[1]=0x82;
- p[2]=0x03;
- fc=3;
- }
- }
- void modbus3(unsigned char *p,unsigned int *p0)//功能码3(读保持寄存器)处理函数;
- {
- unsigned int A,B;
- unsigned char i;
- unsigned int *p1;
- p1=p+3;
- B=p[4];
- B=B<<8|p[5]; //取保持寄存器数量;
- A=p[2];
- A=A<<8|p[3];//取保持寄存器地址;
- if(B>0&&B<33)
- {
- if(A>=0&&A+B<33)
- {
- for(i=0;i<B;i++)
- {
- p1[i]=p0[A+i];
- }
- p[2]=B*2;
- fc=B*2+3;
-
- }
- else
- {
- p[1]=0x83;
- p[2]=0x02;
- fc=3;
- }
- }
- else
- {
- p[1]=0x83;
- p[2]=0x03;
- fc=3;
- }
- }
- void modbus4(unsigned char *p,unsigned int *p0 ) //功能码4(读输入寄存器)处理函数;
- {
- unsigned int A,B;
- unsigned char i;
- unsigned int *p1;
- p1=p+3;
- B=p[4];
- B=B<<8|p[5]; //取输入寄存器个数;
- A=p[2];
- A=A<<8|p[3]; //取输入寄存器地址;
- if(B>0&&B<33)
- {
- if(A>=0&&A+B<33)
- {
- for(i=0;i<B;i++)
- {
- p1[i]=p0[A+i];
- }
- p[2]=B*2;
- fc=B*2+3;
- }
- else
- {
- p[1]=0x84;
- p[2]=0x02;
- fc=3;
- }
- }
- else
- {
- p[1]=0x84;
- p[2]=0x03;
- fc=3;
- }
- }
- void modbus5(unsigned char *p,unsigned long *p1)//功能码5(写单个线圈)处理函数;
- {
- unsigned int A,B,i;
- B=p[4];
- B=B<<8|p[5];//取线圈状态;
- A=p[2];
- A=A<<8|p[3];//取线圈地址;
- if(B==0X0000||B==0XFF00)
- {
- if(A>=0&&A<32)
- {
- i=1;
- if(B==0XFF00)
- {
- p1[0]|=i<<A;
- }
- else M00&=~(i<<A);
- fc=6;
- }
- else
- {
- p[1]=0x85;
- p[2]=0x02;
- fc=3;
- }
- }
- else
- {
- p[1]=0x85;
- p[2]=0x03;
- fc=3;
- }
- }
- void modbus6(unsigned char *p,unsigned int *p1)//功能码6(写单个寄存器)处理函数;
- {
- unsigned int A,B;
- B=p[4];
- B=B<<8|p[5];//取寄存器值;
- A=p[2];
- A=A<<8|p[3];//取寄存器地址;
- if(B>=0X00||B<=0XFFFF)
- {
- if(A>=0&&A<32)
- {
- p1[A]=B;
- fc=6;
- }
- else
- {
- p[1]=0x86;
- p[2]=0x02;
- fc=3;
- }
- }
- else
- {
- p[1]=0x86;
- p[2]=0x03;
- fc=3;
- }
- }
- void modbus15(unsigned char *p,unsigned long *M00)//功能码15(写多个线圈)处理函数;
- {
- unsigned int A,B;
- unsigned char i,y,u;
- unsigned long l;
-
- B=p[4];
- B=B<<8|p[5]; //取线圈个数;
- A=p[2];
- A=A<<8|p[3];//取线圈地址;
- if(B>0&&B<33)
- {
- if(A>=0&&A+B<33)
- {
- l=1;
- fc=B/8;
- for(i=0;i<fc;i++)
- {
- u=p[i+7];
- for(y=0;y<8;y++)
- {
- if((u>>y)&0x01 )M00[0]|=l<<A;
- else M00[0]&=~(l<<A);
- A++;
- }
- }
- if(B%8)
- {
- if(fc)
- {
- fc+=1;
- u=p[fc+6];
- }
- else u=p[7];
- for(y=0;y<B%8;y++)
- {
- if((u>>y)&0x01 )M00[0]|=l<<A;
- else M00[0]&=~(l<<A);
- A++;
- }
- }
- fc=6;
- p14=0;
- }
- else
- {
- p[1]=0x8F;
- p[2]=0x02;
- fc=3;
- }
- }
- else
- {
- p[1]=0x8F;
- p[2]=0x03;
- fc=3;
- }
- }
- void modbus16(unsigned char *p,unsigned int *p1)
- {
- unsigned int A,B;
- unsigned int *p0;
- p0=p+7;
- B=p[4];
- B=B<<8|p[5];//取寄存器数量;
- A=p[2];
- A=A<<8|p[3];//取寄存器地址;
- if(B>0&&B<33)
- {
- if(A>=0&&A+B<33)
- {
- p1+=A;
- while(B--)
- {
- p1[0]=p0[0];
- p1++;
- p0++;
- }
- fc=6;
- }
- else
- {
- p[1]=0x90;
- p[2]=0x02;
- fc=3;
- fcbz=1;
- }
- }
- else
- {
- p[1]=0x90;
- p[2]=0x03;
- fc=3;
- fcbz=1;
- }
- }
- /*void modbus23(unsigned char *p,unsigned int *p1)
- {
- unsigned int A,B,AW,BW;
- unsigned int *p0;
- // unsigned char u;
- B=p[4];
- B=B<<8|p[5];//取读寄存器数量;
- A=p[2];
- A=A<<8|p[8]; //取读寄存器地址;
- BW=p[8];
- BW=BW<<8|p[9];//取写寄存器数量;
- AW=p[6];
- AW=AW<<8|p[7]; //取写寄存器地址;
- if(B>0&&B<33&&BW>0&&BW<33)
- {
- if(A>=0&&A+B<33&&AW>=0&&AW+BW<33)
- {
- unsigned char i;
- p1+=AW;
- p0=p+11;
- do
- {
- p1[0]=p0[0];
- p1++;
- p0++;
- }while(BW--);
- ////////////////////c=(B&0X00FF)*2;
- p0=p+3;
- p1=p1-AW-BW;
- p1+=A;
- for(i=0;i<B;i++)
- {
- p1[i]=p0[A+i];
- }
- }
- else
- {
- p[1]=0x97;
- p[2]=0x02;
- fc=3;
- }
- }
- else
- {
- p[1]=0x97;
- p[2]=0x03;
- fc=3;
- }
- }*/
- void modata(uchar *p,ac)
- {
- unsigned int a,b;
- p13=0;
- a=p[ac];
- a=(a<<8)|p[ac-1];
- b=crc16(p,ac-1);
- if(a!=b)goto pp;
- p12=0;
- fcbz=1;
- switch(p[1]) //功能码判断与服务函数调用;
- {
- case 1: //读线圈;
- modbus1(uartR, M00);
- break;
- case 2://读输入离散;
- modbus2(uartR, M00);
- break;
- case 3://读保持寄存器;
- modbus3(uartR,DW0);
- break;
- case 4://读输入寄存器;
- modbus4(uartR,DW0);
- break;
- case 5://写单个线圈;
- modbus5(uartR, &M00);
- break;
- case 6://写单个数据寄存器;
- modbus6(uartR, DW0);
- break;
- case 15://写多个连续线圈;
- modbus15(uartR,&M00);
- break;
- case 16://写多个连续寄存器;
- modbus16(uartR,DW0);
- break;
- // case 23://读写寄存器;
- // modbus23(uartR,DW0);
- break;
- default:
- p[1]+=0x80;
- p[2]=0x01;
- fc=3;
- }
- pp:;
- }
- modbushy(unsigned char *p ,a)//通讯回应;
- {
- unsigned int b;
- b=crc16(p,a);
- p[a]=b;
- a+=1;
- p[a]=b>>8;
- fc=a;
- SBUF=p[0];
- }
- void uart() interrupt 4 //串口中断函数;
- {
- uchar ua;
- if(RI)
- {
- RI=0;
- ua=SBUF;
- if(!a1)
- {
- if(ua==2)
- {a1=1;
- ac=0;
- at=0;
- uartR[0]=ua;
- }
- }
- else
- {
- RI=0;
- ac++;
- uartR[ac]=ua;
- at=0; //清零结束接收计时器;
- }
- }
- else
- {
- TI=0;
- if(fc--)
- {
- fc1++;
- SBUF=uartR[fc1];
- }
- else fc1=0,fc=0;
- }
- }
- void sumaguan(uint c)
- {
- P2|=0x0f;
- P1=suzhu[c%10];
- P2&=~1;
- delay(300);
- P2|=0x0f;
- P1=suzhu[c%100/10];
- P2&=~4;
- delay(300);
- P2|=0x0f;
- P1=suzhu[c%1000/100];
- //if(b1)P1&=~0x80;
- P2&=~2;
- delay(300);
- P2|=0x0f;
- P1=suzhu[c/1000];
- P2&=~8;
- delay(300);
- }
-
- void main()
- {
- TH0=0XFE;
- TL0=0X0C;
- TMOD=0X01;
- TR0=1;
- EA=1;
- ET0=1;
- uartinit();
- while(1)
- {
- if(!(M00&BIT(0)))M00&=~BIT(1);
- //sumaguan(D1);
- if(a2)modata(uartR,ac),a2=0;
- if(fcbz)modbushy(uartR ,fc),fcbz=0;
- }
- }
复制代码
|
|