|
楼主 |
发表于 2011-11-18 14:16:15
|
显示全部楼层
#include "reg51.h"
#define uchar unsigned char
#define uint unsigned int
#define ufloat unsigned float
#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 R 0x52 //读标志
#define W 0x57 //写标志
#define MyAddr 0x01 //下位机地址
bit RecvOk,CRCOk; //接收完毕状态位 ,CRC校验判断位
uchar Rbuf[11],Tbuf[37]; //接收和发送缓存区
uchar Rptr,Tptr,Tnum,T; //接收指针,发送指针,发送数据个数
uchar last; //下位机地址,ms延时,接收数据存放
uchar crc; //CRC校验
idata uchar U_art;
uchar DatB[17]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10}; //存放字节数据
uint DatW[11]={0x0000,0x1111,0x2222,0x3333,0x4444,0x5555,0x6666,0x7777,0x8888,0x9999,0xaaaa}; //存放字型数据
uchar ML;
/**************串口中断***************/
void Uart() interrupt 4 using 1
{
uint j;
if(RI)
{
RI=0;
U_art++;
switch(U_art)
{
case 1: Rbuf[0]=SBUF;
if(Rbuf[0]!=ENQ) U_art=0;
break;
case 2: Rbuf[1]=SBUF;break;
case 3: Rbuf[2]=SBUF;break;
case 4: Rbuf[3]=SBUF; crc=0;
for(j=0;j<4;j++)
crc^=Rbuf[j];
if(Rbuf[2]==EOT)
if(crc==0)
RecvOk=1;
else
U_art=0;
break;
case 5: Rbuf[4]=SBUF;break;
case 6: Rbuf[5]=SBUF;break;
case 7: Rbuf[6]=SBUF;break;
case 8: Rbuf[7]=SBUF;crc=0;
for(j=0;j<8;j++)
crc^=Rbuf[j];
if(Rbuf[6]==EOT)
if(crc==0)
{Rptr=8;RecvOk=1;}
else U_art=0;
break;
case 9: Rbuf[8]=SBUF;crc=0;
for(j=0;j<9;j++)
crc^=Rbuf[j];
if(Rbuf[7]==EOT)
if(crc==0)
{Rptr=9;RecvOk=1;}
else U_art=0;
break;
case 10:Rbuf[9]=SBUF;break;
case 11:Rbuf[10]=SBUF; crc=0;
for(j=0;j<11;j++)
crc^=Rbuf[j];
if(Rbuf[9]==EOT)
if(crc==0)
{Rptr=11;RecvOk=1;}
else U_art=0;
break;
}
}
// else if(TI)
// {TI=0;}
}
/***************初始化RS232********************/
void init_rs232(void) //波特率9600
{
TMOD = 0x21;
SCON = 0x50;
TH1 = 0xFA;
TL1 = TH1;
PCON = 0x00;
EA = 1;
ES = 1;
TR1 = 1;
}
/**************ms延时************************/
void Delay_ms(uint count)
{
uint i,j;
for(i=0;i<count;i++)
for(j=0;j<120;j++);
}
/****************协议处理*****************/
void Process()
{
uint i,n,ptr,num,k;
//对PC的查询命令进行应答
if(Rbuf[1]==MyAddr)
{
Tbuf[0]=ACK;
Tbuf[1]=MyAddr;
Tbuf[2]=ETX;
crc=0;
for(i=0;i<3;i++)
crc^=Tbuf;
Tbuf[3]=crc;
Tptr=0;
Tnum=4;
T=1;
}
else if(Rbuf[1]==R)
{
n=Rbuf[5];
ptr=Rbuf[3]; //低位地址->ptr
switch(Rbuf[2]) // 判断数据类型
{
case DB: //读取字节数据
for(i=ptr;i<ptr+n;i++)
{
DatB=DatB+1;
Tbuf[3+i-ptr]=DatB;
}
break;
case DW:
num=n/2;
for(i=ptr;i<ptr+num;i++)
{
k=2*i;
DatW=DatW+10;
Tbuf[3+k-2*ptr]=DatW;
Tbuf[4+k-2*ptr]=(DatW>>8);
}
break;
default: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;
Tbuf[4+n]=crc;
Tptr=0;
Tnum=n+5;
T=1;
}
//向单片机写数据的处理
else if(Rbuf[1]==W)
{
// n=Rbuf[4];
// ptr=Rbuf[3]; //低位地址->ptr
// n=Rptr-7;
// switch(Rbuf[2]) // 判断数据类型
// {
// case DB: //读取字节数据
// for(i=0;i<n;i++)
// {
ML=Rbuf[5+i];
// }
// break;
// case DW:
// for(i=0;i<n;i++)
// {
// k=2*i;
// DatW[ptr+i]=Rbuf[6+k];
// DatW[ptr+i]=(DatW[ptr+i]<<8);
// DatW[ptr+i]=Rbuf[5+k];
// }
// break;
// default:break;
// }
Tbuf[0]=ACK;
Tbuf[1]=0x00;
Tbuf[2]=ETX;
crc=0;
for(i=0;i<3;i++)
crc^=Tbuf;
Tbuf[3]=crc;
Tptr=0;
Tnum=4;
T=1;
}
}
/***********************主函数*****************/
void main(void)
{
uint i;
Delay_ms(1000);
RecvOk=0;
init_rs232();
while(1)
{
if(RecvOk)
{
U_art=0;
RecvOk=0;
Process();
if(T==1)
{
T=0;
for(i=0;i<Tnum;i++)
{
SBUF=Tbuf;
Delay_ms(2);
while(!TI)
TI=0;
}
}
}
}
} |
|