⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 组态通讯协议hex(完全版).c

📁 51单片机和组态王的通信示例
💻 C
字号:
/*
  单片机与组态王进行数据通讯(HEX模式)
         2005-11-18测试通过
               赵学军
*/

#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;
		  }
	   }
	}
  }
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -