📄 c读卡程序.c
字号:
/*-- 曼码调制的非接触ID卡通用读卡程序编制
C语言代码程序如下:/*
/*H4001只读卡读码程序*/
/******************头文件********************/
#include <regx55.h>
#include <absacc.h>
#include <intrins.h>
/******************宏定义*********************/
sbit P17 = P1^7; sbit P37 = P3^7;
sbit P16 = P1^6; sbit P36 = P3^6;
sbit P15 = P1^5; sbit P35 = P3^5;
sbit P14 = P1^4; sbit P34 = P3^4;
sbit P13 = P1^3; sbit P33 = P3^3;
sbit P12 = P1^2; sbit P32 = P3^2;
sbit P11 = P1^1; sbit P31 = P3^1;
sbit P10 = P1^0; sbit P30 = P3^0;
sbit P27 = P2^7; sbit P07 = P0^7;
sbit P26 = P2^6; sbit P06 = P0^6;
sbit P25 = P2^5; sbit P05 = P0^5;
sbit P24 = P2^4; sbit P04 = P0^4;
sbit P23 = P2^3; sbit P03 = P0^3;
sbit P22 = P2^2; sbit P02 = P0^2;
sbit P21 = P2^1; sbit P01 = P0^1;
sbit P20 = P2^0; sbit P00 = P0^0;
#define uchar unsigned char
#define uint unsigned int
#define RF_DATA_IN P17 //接收来至U2270B的数据"Output"
#define SO P31 //单片机输出数据到用户接口
#define SCK P16 //同步时钟输出
#define CP P15 //卡存在信号输出
#define MSEL P13 //数据发送方式选择
#define WATCHDOG P21 //看门狗
#define RED_LED P10 //led灯
#define GREEN_LED P11 //led灯
#define DD P12 //蜂鸣器
/****************全局变量***********************/
uchar data Read_RF_Data[11]; //暂存从U2270B上接收的数据
uchar data ID_Data[6]; //暂存经效验后的正确数据
uint data TIMER_1=0;
bit Check_Data_bit; //效验请求标志位
/****************函数列表***********************/
void Recive_RF_Data(void);
void Check_Data(void);
void Clern_Number(void);
void Send_RS232net(uchar Data[],uchar Num);
void delay0_2ms(uint count);
void delay1ms(uint count);
void dida(uchar j);
void Data_start(void)
{DD=0x00;
RED_LED=0x00;
TMOD=0x21; //T0方式1,T1工作于方式2
TH1=0x00; //初始化T1计时器
TL1=0x00;
TR1=0;
SCON=0x50; //串行口初始化
PCON=0x80; //SMOD位设置
TH0=0x00; //初始化T0计时器
TL0=0x04;
TR0=0;
ES=1; //开放串行口中断
EA=1; //开放总中断
}
/**********************************************/
/*主函数*/
/**********************************************/
void main(void)
{
delay1ms(100);
Data_start();
while(1)
{
WATCHDOG=~WATCHDOG;
Recive_RF_Data(); //调用接收RF数据函数
if(Check_Data_bit==1) //如果此位为1,有一组数据申请效验
{
Check_Data(); //调用数据效验函数
Check_Data_bit=0;
}
}
}
/*********************************************/
/*接收RF数据*/
/*********************************************/
void Recive_RF_Data(void)
{
/////////////////////定义局部变量
uchar header,pc;
uchar temp;
uchar temp1;
uint temp2;
uchar ByteCounter; //字节计数器
uchar *PData;
uchar BitCounter; //位计数器
////////////////////初始化变量值
header=0;pc=4;
PData=Read_RF_Data;
temp=0;
temp1=0;
ByteCounter=0;
BitCounter=5;
/////////////////////检测一个稳定的低电平
str:
WATCHDOG=~WATCHDOG;
if(RF_DATA_IN==0)
if(RF_DATA_IN==0)
if(RF_DATA_IN==0)
if(RF_DATA_IN==0)
if(RF_DATA_IN==0)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
////////////////////检测一个起始位电平
while(RF_DATA_IN==0); //当电平由低向高跳变时启动计时器
TR0=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
////////////////////检测9个"header"
while(RF_DATA_IN==1);
TR0=0;
TF0=0;
TIMER_1=TH0;
TIMER_1=(TIMER_1<<8)+TL0;
TH0=0x00;
TL0=0x04;
temp2=0x108;
if(TIMER_1>temp2) // >520us
{
goto str;
}
temp2=0xf9;
if(TIMER_1<temp2) // <490us
{
goto str;
}
do
{
TIMER_1=0;
WATCHDOG=~WATCHDOG;
while(RF_DATA_IN==0);
TR0=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
while(RF_DATA_IN==1);
TR0=0;
TF0=0;
TIMER_1=TH0;
TIMER_1=(TIMER_1<<8)+TL0;
TH0=0x00;
TL0=0x04;
temp2=0x90;
if(TIMER_1>temp2)// >280us
{
header=0;
goto str;
}
temp2=0x77;
if(TIMER_1<temp2)// <230us
{
header=0;
goto str;
}
header++;
}while(header<8);
TR0=0;
TF0=0;
///////////////////如果9个"header"都对,开始接收卡内数据
TH0=0xff; //time:300us
TL0=0x6a;
TR0=1;
if(header==8)
{
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 str;
}
}
TH0=0xff; //time:300us
TL0=0x6a;
temp=~RF_DATA_IN;
temp1=(temp1<<1)|temp;
BitCounter--;
}while(BitCounter); //一个字节完否
*(PData+ByteCounter)=temp1; //将一字节数据存入缓存数组
temp1=0;
BitCounter=5;
ByteCounter++;
WATCHDOG=~WATCHDOG;
}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 str;
}
}
TH0=0xff; //time:300us
TL0=0x6a;
temp=~RF_DATA_IN;
temp1=(temp1<<1)|temp;
pc--;
}while(pc); //一个字节完否
Read_RF_Data[10]=temp1; //将一字节数据存入缓存数组
///////////////////检测最后一个停止位
while(TF0==0);
TR0=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 str;
}
}
temp=~RF_DATA_IN;
if(temp==0) //如果停止位正确
{
Check_Data_bit=1; //置效验请求标志
}
else //如果停止位不正确
{
Clern_Number(); //清除
}
}
}
}
/*********************************************/
/*效验数据*/
/*********************************************/
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++;
}
else
{
ByteCounter1=5;//只要有一组不对则退出效验
Clern_Number();//并清所有数据
}
}
else
{
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);
GREEN_LED=0x00;
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;
}
//**********************************************************
/*串行口发送,接收程序*/
//**********************************************************
void Send_RS232net(uchar Data[],uchar Num) //串行口数据发送
{
uchar i=0;
uchar *PData;
PData=Data;
WATCHDOG=~WATCHDOG;
TH1=0xf3; //串行口波特率2400b/s
TL1=0xf3;
TR1=1;
for(i=0;i<Num;i++)//有Num组号码要发送
{
SBUF=*(PData+i);
while(TI==0);TI=0;//等待数据发送出去
delay0_2ms(1);//等待后再发送
}
TR1=0;
}
//*****************************************************
/*延时0.2ms*count*/
//*****************************************************
void delay0_2ms(uint count)
{
uint k;
while(count--!=0)
{
for(k=0;k<50;k++)
{
WATCHDOG=~WATCHDOG;
}
}
}
void delay1ms(uint count)
{
uint k;
while(count--!=0)
{
for(k=0;k<250;k++)
{
WATCHDOG=~WATCHDOG;
}
}
}
//*****************************************************
/*鸣叫声*/
//*****************************************************
void dida(uchar j)
{
uchar i;
for(i=0;i<j;i++)
{
DD=~DD;
delay1ms(30);
DD=~DD;
delay1ms(30);
}
}
///////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -