📄 rfid.c
字号:
/*H4001只读卡读码程序*/
/******************头文件********************/
#include <AT89X52.h>
#include <absacc.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit RF_DATA_IN=P1^2; //接收来至U2270B的数据"Output"
/****************全局变量***********************/
uchar data Read_RF_Data[11]; //暂存从U2270B上接收的数据
extern uchar data ID_Data[6]; //暂存经效验后的正确数据
uint data TIMER_1=0;
bit Check_Data_bit; //效验请求标志位
bit flag_card;//卡存在标志,1代表存在,0代表不存在
uint count;//数据读取最大次数
extern bit READ_SUCESS; //读取数据检验正确标志,1代表正确,0代表错误
/****************函数列表***********************/
void Recive_RF_Data(void);
void Check_Data(void);
void Clern_Number(void);
void delay1ms(uint count);
void print_data_hex(uchar,uchar);
void print(uchar,uchar *);
void inital();
void pcf8563();
void test_ID();
void wcmd(uchar);
void wdat(uchar);
void pcf8563_read();
display_RFID()
{
print(0x80,"EM4001卡号 "); //空格表示显示空格
print_data_hex(0x90,ID_Data[0]);
print_data_hex(0x91,ID_Data[1]);
print_data_hex(0x92,ID_Data[2]);
print_data_hex(0x93,ID_Data[3]);
print_data_hex(0x94,ID_Data[4]);
print(0x95," ");
}
void Data_start(void)
{
TMOD=0x11; //T0方式1,T1工作于方式2
TH1=0x00; //初始化T1计时器
TL1=0x00;
TR1=0;
TH0=0x00; //初始化T0计时器
TL0=0x00;
TR0=0;
EA=1; //开放总中断
ET0=0;ET1=0;
}
/**********************************************/
/*主函数*/
/**********************************************/
/*void main(void)
{
delay1ms(100);
P1_1=1;
P1_0=1;
P3_1=1;
inital();
Data_start();
flag_card=0;
while(1)
{
test_ID();
if(flag_card==1)
{
Recive_RF_Data(); //调用接收RF数据函数
if(flag_card==1)
{
if(Check_Data_bit==1 ) //如果此位为1,有一组数据申请效验
{
Check_Data_bit=0;
Check_Data(); //调用数据效验函数
display_RFID();
Clern_Number();
}
else
{
Clern_Number();
// print(0x88,"fail");
// pcf8563();
}
}
else pcf8563();
flag_card=0;
}
else pcf8563();
}
} */
void RFID_2(void)
{
test_ID();
if(flag_card==1)
{
Recive_RF_Data(); //调用接收RF数据函数
if(flag_card==1)
{
if(Check_Data_bit==1 ) //如果此位为1,有一组数据申请效验
{
Check_Data_bit=0;
Check_Data(); //调用数据效验函数
display_RFID();
}
else
pcf8563_read();
}
else pcf8563_read();
}
else pcf8563_read();
}
void RFID()
{
count=0;
READ_SUCESS=0;
flag_card=0;
Check_Data_bit=0;
Recive_RF_Data(); //调用接收RF数据函数
if(flag_card==1)
{
if(Check_Data_bit==1 ) //如果此位为1,有一组数据申请效验
{
print(0x88,"校验····");
Check_Data_bit=0;
Check_Data(); //调用数据效验函数
if(READ_SUCESS==1)
{
display_RFID();
}
else
{
inital();
print (0x80,"检验错误");
print(0x90,"请重新读取");
}
}
else
{
READ_SUCESS=0;
inital();
print(0x80,"读取失败");
print(0x88,"请将卡片放在图示");
print(0x98,"读卡区域内");
}
}
else
{
READ_SUCESS=0;
inital();
print(0x80,"未检测到卡");
print(0x88,"请将卡片放在图示");
print(0x98,"读卡区域内");
}
}
void test_ID()//检测是否有卡存在
{
TH0=(65526-2000)/256; //在1毫秒时间内检测高电平
TL0=(65526-2000)%256;
TF0=0;
TR0=1;
while(RF_DATA_IN==0)
{
if(TF0==1)
{
flag_card=0;//1毫秒内没有电平信号,认为卡不存在,置标志位0
TR0=0;
TF0=0;
goto go1;
}
}
flag_card=1;//检测到电平跳变,卡存在,置标志位
TR0=0;
go1:_nop_();
}
/*********************************************/
/*接收RF数据*/
/*********************************************/
void Recive_RF_Data()
{
uchar pc;
uchar temp1;
uchar ByteCounter; //字节计数器
uchar *PData;
uchar BitCounter; //位计数器
////////////////////初始化变量值
uint temp2;
uchar header;
uchar temp;
PData=Read_RF_Data;
count=0;
test_ID();//检测卡是否存在
if(flag_card==0)
goto str2;
str1:
count++;
if(count>=500)
{
READ_SUCESS=0;//读取次数超过100次,读取失败
goto str2;
}
header=0;
temp=0;
temp1=0;
ByteCounter=0;
BitCounter=5;
pc=4;
TH0=0x00;
TL0=0x00;
TR0=0;
TR0=1;
if(RF_DATA_IN==1) //首先检测9个1,曼彻斯特编码0对应下跳变,1对应上跳变,故在检测1时必须检测到一个持续一个周期的低电平,并且随后伴有高电平跳变
{
while(RF_DATA_IN==1 && TF0==0);
if(TF0==1)
{
flag_card=0;
goto str2; //如果卡片突然移走,自动退出
}
TH0=0x00;
TL0=0x00;
TF0=0;
while(RF_DATA_IN==0 && TF0==0); //当电平由高向低变跳时启动计时器
TR0=0; //电平变高时停止计数
if(TF0==1)
{
flag_card=0;
goto str2; //如果卡片突然移走,自动退出
}
TIMER_1=TH0;
TIMER_1=(TIMER_1<<8)+TL0;
TH0=0x00;
TL0=0x00;
temp2=1100;
if(TIMER_1>temp2) // >520us,确定数据为1
{
goto str1;
}
temp2=800;
if(TIMER_1<temp2) // <490us
{
goto str1;
}
do
{
TIMER_1=0;
TR0=1;
while(RF_DATA_IN==1 && TF0==0);
if(TF0==1)
{
flag_card=0;
goto str2; //如果卡片突然移走,自动退出
}
TH0=0x00;
TL0=0x00;
TF0=0;
while(RF_DATA_IN==0 && TF0==0);
TR0=0;
if(TF0==1)
{
flag_card=0;
goto str2; //如果卡片突然移走,自动退出
}
TIMER_1=TH0;
TIMER_1=(TIMER_1<<8)+TL0;
TH0=0x00;
TL0=0x00;
temp2=600;
if(TIMER_1>temp2)// >280us
{
header=0;
goto str1;
}
temp2=300;
if(TIMER_1<temp2)// <230us
{
header=0;
goto str1;
}
header++;
}while(header<8);
TR0=0;
TF0=0;
TH0=0xfd; //time:300us
TL0=0x9E;
TR0=1;
do
{
do
{
while(TF0==0);
TF0=0;
if(RF_DATA_IN==1) temp=1;
else temp=0;
while(RF_DATA_IN==temp) //检测电平跳变否?
{
if(TF0==1) //如果300us计时到还未跳变,视为非法电平!!!
{
TR0=0;
TF0=0;
goto str1;
}
}
temp=RF_DATA_IN;
TH0=0xfd; //time:300us
TL0=0x9e;
temp1=(temp1<<1)|temp;
BitCounter--;
}while(BitCounter); //一个字节完否
*(PData+ByteCounter)=temp1; //将一字节数据存入缓存数组
temp1=0;
BitCounter=5;
ByteCounter++;
}while(ByteCounter<10);
do
{
// WATCHDOG=~WATCHDOG;
while(TF0==0); //等待一个位周期
TF0=0;
if(RF_DATA_IN==1) temp=1;
else temp=0;
while(RF_DATA_IN==temp) //检测电平跳变否?
{
if(TF0==1) //如果300us计时到还未跳变,视为非法电平!!!
{
TR0=0;
TF0=0;
goto str1;
}
}
TH0=0xfd; //time:300us
TL0=0x9e;
temp=RF_DATA_IN;
temp1=(temp1<<1)|temp;
pc--;
}while(pc); //一个字节完否
Read_RF_Data[10]=temp1;
while(TF0==0);
TF0=0;
if(RF_DATA_IN==1) temp=1;
else temp=0;
while(RF_DATA_IN==temp) //检测电平跳变否?
{
if(TF0==1) //如果300us计时到还未跳变,视为非法电平!!!
{
TR0=0;
TF0=0;
goto str1;
}
}
temp=RF_DATA_IN;
if(temp==0) //如果停止位正确
{
Check_Data_bit=1; //置效验请求标志
}
else //如果停止位不正确
{
Clern_Number(); //清除
}
}
str2: _nop_();
}
/*********************************************/
/*效验数据*/
/*********************************************/
void Check_Data(void)
{
/////////////////////定义局部变量
uchar temp;
uchar temp1;
uchar ByteCounter; //数组计数器
uchar ByteCounter1;
uchar *PData;
uchar *PData1;
////////////////////初如化变量值
PData=Read_RF_Data;
PData1=ID_Data;
temp=0;
temp1=0;
ByteCounter=0;
ByteCounter1=0;
/////////////////////循环效验
// WATCHDOG=~WATCHDOG;
/////////////////////行校验
for(ByteCounter1=0;ByteCounter1<5;ByteCounter1++)//有5个字节数据
{
temp=(((*(PData+ByteCounter))&0x10)>>4)+(((*(PData+ByteCounter))&0x08)>>3)+(((*(PData+ByteCounter))&0x04)>>2)+(((*(PData+ByteCounter))&0x02)>>1);
if((temp&0x01)==((*(PData+ByteCounter))&0x01))//效验高4位
{
temp1=(*(PData+ByteCounter)&0xfe)<<3;
ByteCounter++;
temp=(((*(PData+ByteCounter))&0x10)>>4)+(((*(PData+ByteCounter))&0x08)>>3)+(((*(PData+ByteCounter))&0x04)>>2)+(((*(PData+ByteCounter))&0x02)>>1);
if((temp&0x01)==((*(PData+ByteCounter))&0x01))//效验高4位
{
*(PData1+ByteCounter1)=temp1|((*(PData+ByteCounter)&0xfe)>>1);//高低位生成一个字节存入数组
ByteCounter++;
READ_SUCESS=1;
}
else
{
READ_SUCESS=0;
ByteCounter1=5;//只要有一组不对则退出效验
Clern_Number();//并清所有数据
}
}
else
{
READ_SUCESS=0;
ByteCounter1=5;//只要有一组不对则退出效验
Clern_Number();//并清所有数据
}
// WATCHDOG=~WATCHDOG;
}
/////////////////////列校验
//......因没有必要所以先省略此处.........//
/////////////////////生成校验和,并发送出去
/* if(ByteCounter==10)
{
ID_Data[5]=ID_Data[0]+ID_Data[1]+ID_Data[2]+ID_Data[3]+ID_Data[4];//生成校验和
if(MSEL==0) //此脚如果为低电位,为异步通信方式发送数据
{
CP=0;
delay0_2ms(1);
Send_RS232net(ID_Data,6); //调用串口发送函数
delay0_2ms(1);
CP=1;
}
Clern_Number();
// dida(1);
delay0_2ms(1000);//*****(正确读取一张卡号后要等待约一秒后再重新扫描)*****
}*/
}
//************************************************************
/*清暂存器*/
//************************************************************
void Clern_Number(void)
{
// WATCHDOG=~WATCHDOG;
Read_RF_Data[0]=0;
Read_RF_Data[1]=0;
Read_RF_Data[2]=0;
Read_RF_Data[3]=0;
Read_RF_Data[4]=0;
Read_RF_Data[5]=0;
Read_RF_Data[6]=0;
Read_RF_Data[7]=0;
Read_RF_Data[8]=0;
Read_RF_Data[9]=0;
Read_RF_Data[10]=0;
ID_Data[0]=0;
ID_Data[1]=0;
ID_Data[2]=0;
ID_Data[3]=0;
ID_Data[4]=0;
ID_Data[5]=0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -