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

📄 file18.c

📁 H6152读Mifare射频卡通信.zip
💻 C
字号:
/*********************************************************************************************
*                               读卡器与主机的通信                                          *                                                              *
*                  *****************MODULE.CAN*****************                             *
*                              读卡器控制器为AT89C51                                        *                                                            *
**********************************************************************************************/  
 

#include<reg51.h>
#include<string.h>
#define uchar unsigned char 
#define uint unsigned int
#define _BUFSIZER 0x0bff  //缓冲区长度
#define _INTRPSW 0x27     //中断屏蔽
#define _CANADD  0        //CAN接口芯片地址
#define _BUFSIZEC 0x0bff 
#define WREN 0x06
#define WRSR 0x01
#define WRDI 0x04
#define RDSR 0x05
#define WRITE 0x02
#define READ  0x03

sbit SO=P1^3;//X5045接口
sbit SI=P1^2;
sbit SCK=P1^1;
sbit CS=P1^0;
//读写X5045的函数
void wren_cmd(void);
void wrsr_cmd(uchar status_reg);
void wrdi_cmd(void);
uchar rdsr_cmd(void);
void inputbyte(uchar byt);
uchar outbyte(void);
void writebyte(uint addr,uchar val);
uchar readbyte(uint addr);
//RS232操作函数
void INIT232();
void RS232Send(void);
void RSSave(void);
void RS232_Write(void);
void RS232_Read(uchar*buf);
void RS232_Send(uchar *buf);
uchar Buffer[12];
uchar RS232_Receive(uchar*buf);
uchar xdata bufRS[_BUFSIZER];
uchar ChkEndR();
uchar bufRS_R[14];
uchar bufRS_S[12];
uchar RSEnd=0;//发送结束标示
uchar EndSend=0;
uchar ECC=0;
uchar dbr=0;
uchar c0s=0;//要发送的字节为0xc0,发送后0xdb置位
uchar dbs=0;//要发送的字节为0xdb,发送后0xdb置位
uchar des_r=0;//缓冲区写入读出指针
uchar sou_r=0;
uchar posr=0;
uchar poss=0;
uint lenR=_BUFSIZER;
uint ChgPoint(uint adr,uint len);
//CAN总线操作函数
uchar xdata bufC[_BUFSIZEC];
uchar CheckCS=0;
uint des_c=0;
uint sou_c=0;
uchar xdata *canport=_CANADD;
uint lenC=_BUFSIZEC;
void can_write();
void can_Read(uchar*buf);
void rst_wdog(void);
void INITCAN();
uchar ChkEndC();
uchar can_Receive(uchar*buf);
void can_Send(uchar*buf);
//读写X5045
void wren_cmd(void)
{
SCK=0;
CS=0;
inputbyte(WREN);
SCK=0;
CS=1;
}
void wrdi_cmd(void)
{
SCK=0;
CS=0;
inputbyte(WRDI);
SCK=0;
CS=1;
}
void wrsr_cmd(uchar status_reg)
{
wren_cmd();
SCK=0;
CS=0;
inputbyte(WRSR);
inputbyte(status_reg);
SCK=0;
CS=1;
wrdi_cmd();
}
void inputbyte(uchar byt)
{
uchar i;
for(i=0;i<8;i++)
{
SCK=0;
SI=(bit)(byt&0x80);
SCK=1;
byt=byt<<1;
 }
}
uchar outbyte(void)
{
uchar i;
uchar byt=0;
SO=1;
for(i=0;i<8;i++)
{
 byt=byt<<1;
SCK=1;
SCK=0;
byt=SO;
 }
return (byt);
}
//写入一个字节
void writebyte(uint addr,uchar val)
{ 
uchar temp;
temp=0x02;
if((addr>>8)&0x01)temp|=8;
wren_cmd();
SCK=0;
CS=0;
inputbyte(temp);
inputbyte(addr&0xff);
inputbyte(val);
CS=1;
wrdi_cmd();
}
//读一个字节
uchar readbyte(uint addr)
{
uchar val;
SCK=0;
CS=0;
val=0x03;
if((addr>>8)&0x01)val|=8;
inputbyte(val);
inputbyte(addr&0xff);
val=outbyte();
SCK=0;
CS=1;
return (val);
}
//
uint ChgPoint(uint adr,uint len)
{
adr++;
if(adr>=len)
adr=0;
return(adr);
}
//RS232初始化
void INIT232()
{
TMOD=0x20;
TH1=250;
TL1=250;
TR1=1;
PCON=0x80;
SCON=0x50;
EA=1;
ES=1;
}

//接收串行数据
uchar RS232_Receive(uchar*buf)
{
if(des_r==sou_r)
return 0;
RS232_Read(buf);
return 1;
}
//读缓冲区
void RS232_Read(uchar*buf)
{
uchar i;
uchar temp;
uint p;
p=sou_r;
for(i=0;i<3;i++)
p=ChgPoint(p,lenR);
temp=bufRS[p]+4;
for(i=0;i<temp;i++)
{
*buf=bufRS[sou_r];
buf++;
sou_r=ChgPoint(sou_r,lenR);
  }
}

//发送数据
void RS232_Send(uchar *buf) 
{
uchar i;
uchar temp;
if(RSEnd)
return;
for(i=0;i<12;i++)
{
temp=*buf;
bufRS_S[i]=temp;
buf++;
}
RSEnd=1;
RS232Send();
} 
//发送串口数据
void RS232Send()
{
uchar i;
uchar temp;
uchar pp=0;
if(c0s==1)
{
c0s=0;
SBUF=0xdc;
return;
}
if(dbs==1)
{
dbs=0;
SBUF=0xdd;
return;
}
if(poss!=0)
{
pp=poss-1;
if(pp==(bufRS_S[3]+4))//帧结束
{
SBUF=0xc0;
poss=0;
ECC=0;
EndSend=1;
return;
}
if(poss==(bufRS_S[3]+4))//ECC校验
{
for(i=0;i<poss;i++)
ECC=ECC^bufRS_S[i];
if(ECC==0xdb)
dbs=1;
if(ECC==0xc0)
c0s=1;
ECC=0xdc;
}
SBUF=ECC;
poss++;
return;
}
temp=bufRS_S[poss];//保存字节
if(temp==0xdb)
dbs=1;
if(temp==0xc0)
c0s=1;
temp=0xdb;
}

//发送中断
uchar ChkEnd()
{
return(RSEnd) ;
}

//串口中断
void RSINTR()interrupt 4 using 2
{
ES=0;
if(TI==1)
{
TI=0;
if(RSEnd)
RS232Send();
if(EndSend)
{
RSEnd=0;
EndSend=0;
  }
}
if(RI==1)
RS232_Write();
ES=1;
}
//写缓冲区
void RS232_Write()
{
uchar temp;
temp=SBUF;
RI=0;
if(dbr==1)
{
dbr=0;
if(temp==0xdd)  //0xdb=0xdbdd
{
bufRS_R[posr]=0xdb;//存入0xdb
posr++;
if(posr>13)
{
dbr=0;
posr=0;
}
return;
}
if(temp==0xdc)    //0xc0=0xdbdc
{
bufRS_R[posr]=0xc0;
posr++;
if(posr>13)
{
dbr=0;
posr=0;
}
return;
}
posr=0;//出现错误,清空串口输入缓冲区
return;
}

if(temp==0xc0)
{
RSSave();
return;
}
if(temp==0xdb)
{
dbr=1;//接收字节为0xdb,置标志位
return;
}
bufRS_R[posr]=temp;//保存数据
posr++;
if(posr>13)
{
dbr=0;
posr=0;
  }
}
//接收缓冲区数据
void RSSave()
{
uchar temp=0;
uchar i; 
uint p;
if(posr<6)     //帧长度过短则出错
{
posr=0;
return;
}
if(posr!=(bufRS_R[3]+5))   //数据场长度与帧长中数据长度位不同则出错
{
posr=0;
return;
}
for(i=0;i<posr;i++)
temp=temp^bufRS_R[i];
if(temp!=0)     //ECC校验错
{
posr=0;
return;
}
p=des_r;
for(i=0;i<(posr-2);i++)
{
p=ChgPoint(p,lenR);
if(p==sou_r)
{
posr=0;
return;
 }
}
for(i=0;i<(posr-1);i++)//保存帧信息
{
temp=bufRS_R[i];
bufRS[des_r]=temp;
des_r=ChgPoint(des_r,lenR);
}
posr=0;//清空接收缓冲区
}


//CAN初始化
void INITCAN()
{
uchar i;
uchar dev=0;
P1=0xff;
dev=(P1>>2)&0x3c;
P3=0xff;
dev=dev|((P3<<5)&0x01);
dev=dev|((P3<<3)&0x02);//本机设备号
*canport=0x09;//单验收滤波器,复位状态
*(canport+31)=0x80;// PeliCan,启用CLKOUT引脚,供应时钟频率为晶振的1/2
for(i=0;i<8;i++)
*(canport+16+i)=0xff;//验收代码和屏蔽代码均被置为0xff
*(canport+18)=dev;//本机设备号写入验收代码,即协议中规定的DesDevID 
*(canport+22)=0;//验收屏蔽位
*(canport+6)=0x71;//总线定时器0
*(canport+7)=0xb4;//总线定时器1
*(canport+8)=0x1a;//输出控制
*(canport+4)=_INTRPSW;
*canport=0x08;//正常状态
} 
//接收缓冲区数据
uchar can_Receive(uchar*buf)
{
uchar i;
uint p;
uchar temp;
if(des_c==sou_c)
return 0;           //无数据送入则返回
p=sou_c;
for(i=0;i<3;i++)
p=ChgPoint(p,lenC);    //总长度
temp=bufC[p]+4;
for(i=0;i<temp;i++)   //读入数据
{
p=bufC[sou_c];
*buf=p;
buf++;
sou_c=ChgPoint(sou_c,lenC);
 }
  return 1;
}
//向CAN总线发数据
void Can_Send(uchar *buf)
{
uchar temp;
uchar i;
uchar te;
rst_wdog();
te=*buf;
*(canport+19)=te;//目的设备地址,DesDevID
buf++;
te=*buf;
*(canport+18)=te;//源设备地址,SouDevID
buf++;
te=*buf;
*(canport+17)=te;//命令字,Type
buf++;
te=*buf;
*(canport+16)=te|0x80;//数据长度,Length
buf++;
*(canport+20)=0;//保留位
for(i=0;i<temp;i++)
{
te=*buf;
buf++;
*(canport+21+i)=te;//写入数据
}
*(canport+1)=0x01;//发送信息
CheckCS=1;

}

uchar ChkEndC()
{
return(CheckCS);
}

//CAN产生INTO中断
void CanINTR()interrupt 0 using 1
{
uchar sta;
uchar temp;
EX0=0;
sta=*(canport+3);//读中断寄存器
temp=sta&0x20;
if(temp==0x20)//消极错误中断,错误报警中断均导致重启
INITCAN();
temp=sta&0x04;
if(temp==0x04)
INITCAN();
temp=sta&0x02;
if(temp==0x02)//发送中断处理
CheckCS=0;
temp=sta&0x01;
if(temp==0x01)//接收中断,接收数据
EX0=1;
can_write();
}
//写缓冲区
void can_Write()
{
uchar temp;
uchar i;
uint p=0;
temp=*(canport+16)&0x0f;//获得长度
p=des_c;
for(i=0;i<(temp+3);i++)
{
p=ChgPoint(p,lenC);
if(p==sou_c)   //缓冲区溢出则丢弃该帧
{
*(canport+1)=0x04;
return;
  }
}
bufC[des_c]=*(canport+19);//写入DesDevID
des_c=ChgPoint(des_c,lenC);//des_c++
bufC[des_c]=*(canport+18);//写入souDevID
des_c=ChgPoint(des_c,lenC);
bufC[des_c]=*(canport+17);//写入Type
des_c=ChgPoint(des_c,lenC);
bufC[des_c]=temp;//写入Length
des_c=ChgPoint(des_c,lenC);
for(i=0;i<temp;i++)
{
bufC[des_c]=*(canport+21+i);//写入Data
des_c=ChgPoint(des_c,lenC);

 }

*(canport+1)=0x04;//释放缓冲区

}

void main()
{
uchar aa;
P1=0xf0;
aa=rdsr_cmd();
aa=aa&0x30;
if(aa!=0)
{
wren_cmd();
wrsr_cmd(0);
}
INIT232();
INITCAN();
IT0=1;
EX0=1;
ES=1;
EA=1;
while(1)
{
rst_wdog();
if(!ChkEndR())
{
if(can_Receive(Buffer)) //接收CAN总线信息
RS232_Send(Buffer);//将接收到的信息发送至串口
}
if(!ChkEndC())
{
 if(RS232_Receive(Buffer))//接收串口信息
Can_Send(Buffer);//将接收到的信息发送至CAN总线
  }
 }

}  
                     

⌨️ 快捷键说明

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