- /*
- 单片机与组态王进行数据通讯(HEX模式)
- 测试通过
- 赵学军
- */
- #include <reg51.h>
- #define byte unsigned char
- #define word unsigned int
- #define ENQ 0x05 //询问
- #define ACK 0x06 //确认
- #define NAK 0x15 //否认
- #define EOT 0x04 //发送结束
- #define ETX 0x03 //应答结束
- #define DB 0x01 //字节
- #define DW 0x02 //字
- #define DF 0x03 //浮点
- #define BufMax 30
- #define time0 -100000
- bit RecvOk,CRCok;
- bit LED;
- sbit LIT=P0^0;
- byte idata Rbuf[BufMax],Tbuf[BufMax];
- byte data Rptr,Tptr,Tnum;
- byte data MyAddr,DelayMs,last,ReadMe;
- byte idata DatB[8];
- word idata DatW[8];
- float idata DatF[8];
- void CheckCRC()
- {
- byte i,n,crc;
- n=Rptr;
- crc=ENQ;
- for(i=0;i<n;i++) crc^=Rbuf[i];
- if(crc==0) CRCok=1;
- else CRCok=0;
- }
- void Uart() interrupt 4 using 1
- {
- byte m;
- if(RI) //ENQ.......EOT,CRC
- {
- RI=0;m=SBUF;
- if(last==ENQ &&(m==MyAddr ||m=='R' || m=='W')) Rptr=0;
- if(Rptr<BufMax)
- {
- Rbuf[Rptr]=m; Rptr++;
- }
- if(last==EOT) RecvOk=1;
- last=m;
- }
- else
- {
- TI=0;
- if(Tnum>0)
- {
- SBUF=Tbuf[Tptr];
- if(++Tptr>=BufMax) Tptr=0;
- Tnum--;
- }
- else if(ReadMe==2)
- {
- SM2=1; ReadMe=0;
- }
- }
- }
- void Timer1() interrupt 1 using 2
- {
- TH0=time0>>8; TL0=time0&0xff;
- if(DelayMs>0) DelayMs--;
- else SM2=1;
- }
- void main()
- {
- byte n,i,*p,crc,k;
- word ptr,num;
- IE=0x92;SCON=0xD0; SM2=1; TB8=0;
- TMOD=0x21; PCON=0x80;
- TH1=-2; TL1=-2; TR1=1;
- TH0=time0>>8; TL0=time0&0xff; TR0=1;
- Tptr=0; Tnum=0; Rptr=0;
- ReadMe=0; RecvOk=0;MyAddr=0;
- DatB[0]=123;DatB[1]=234;DatB[2]=111; DatB[3]=222;
- DatW[0]=1234;DatW[1]=5678;DatW[2]=7890;DatW[3]=17890;
- DatF[0]=12.34; DatF[1]=123.4; DatF[2]=1234.5;
- while(1)
- {
- DatB[1]=P1;
- if(RecvOk)
- {
- RecvOk=0; CheckCRC();
- if(Rbuf[0]==MyAddr && CRCok==1 && SM2==1) //对PC的查询命令进行应答
- {
- LED=!LED; LIT=LED;
- Tbuf[0]=ACK; Tbuf[1]=MyAddr; Tbuf[2]=ETX;
- crc=0; for(i=0;i<3;i++) crc^=Tbuf[i];
- Tbuf[3]=crc;
- Tptr=0; Tnum=4; TI=1;
- DelayMs=10; ReadMe=1;
- SM2=0;
- }
- else if(SM2==0 && CRCok==1) //在应答后进行数据传送控制
- {
- ReadMe=2;
- n=Rbuf[4];
- ptr=Rbuf[3]<<8 | Rbuf[2];
- if(Rbuf[0]=='R')
- {
- switch(Rbuf[1])
- {
- case DB:num=n;
- DatB[0]++;
- p=(byte*)DatB+ptr;
- for(i=0;i<num;i++)
- {
- k=i;
- Tbuf[3+k]=p[k];
- }
- break;
- case DW:num=n/2;
- DatW[0]++;
- p=(byte*)DatW+ptr*2;
- for(i=0;i<num;i++)
- {
- k=i*2;
- Tbuf[3+k]=p[k+1];
- Tbuf[4+k]=p[k];
- }
- break;
- case DF:num=n/4;
- DatF[0]+=0.01;
- p=(byte*)DatF+ptr*4;
- for(i=0;i<num;i++)
- {
- k=4*i;
- Tbuf[6+k]=p[k];
- Tbuf[5+k]=p[k+1];
- Tbuf[4+k]=p[k+2];
- Tbuf[3+k]=p[k+3];
- }
- break;
- }
- Tbuf[0]=ACK; Tbuf[1]=n&0xff; Tbuf[2]=n>>8;
- Tbuf[3+n]=ETX;
- crc=0; for(i=0;i<4+n;i++) crc^=Tbuf[i];
- Tbuf[4+n]=crc;
- Tptr=0; Tnum=n+5; TI=1;
- }
- else if(Rbuf[0]=='W')
- {
- n=Rptr-6;
- switch(Rbuf[1])
- {
- case DB:num=n;
- p=(byte*)DatB+ptr;
- for(i=0;i<num;i++)
- {
- k=i;
- p[i]=Rbuf[k+4];
- }
- break;
- case DW:num=n/2;
- p=(byte*)DatW+ptr*2;
- for(i=0;i<num;i++)
- {
- k=i*2;
- p[k+1]=Rbuf[k+4];
- p[k]=Rbuf[k+5];
- }
- break;
- case DF:num=n/4;
- p=(byte*)DatF+ptr*4;
- for(i=0;i<num;i++)
- {
- k=4*i;
- p[k+3]=Rbuf[k+4];
- p[k+2]=Rbuf[k+5];
- p[k+1]=Rbuf[k+6];
- p[k]=Rbuf[k+7];
- }
- break;
- }
- Tbuf[0]=ACK; Tbuf[1]=MyAddr; Tbuf[2]=ETX;
- crc=0; for(i=0;i<3;i++) crc^=Tbuf[i];
- Tbuf[3]=crc;
- Tptr=0; Tnum=4; TI=1;
- }
- }
- }
- }
- }
复制代码 |