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

📄 u2270.c

📁 从网上找的读EM卡芯片U2270的源程序
💻 C
字号:
/*H4001只读卡读码程序*/
/******************头文件********************/

#include <sst89x5xxrd2.h>
#include <absacc.h>
#include <intrins.h>

#define uchar unsigned char
#define uint unsigned int

sbit RF_DATA_IN = P3^4; //接收来至U2270B的数据"Output"
sbit SO = P3^1; //单片机输出数据到用户接口
sbit SCK= P1^0; //同步时钟输出
sbit CP= P1^7; //卡存在信号输出
sbit MSEL= P1^2; //数据发送方式选择
sbit WATCHDOG = P2^1; //看门狗
sbit DD = P2^0; //蜂鸣器

/****************全局变量***********************/

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)
{
	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=0x1e3;
	if(TIMER_1>temp2) // >520us
	{
		goto str;
	}
	temp2=0x1c8;
	if(TIMER_1<temp2) // <490us
	{
		goto str;
	}
	do
	{
		WATCHDOG=~WATCHDOG;
		TIMER_1=0;
		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=0x106;
		if(TIMER_1>temp2)// >280us
		{
			header=0;
			goto str;
		}
		temp2=0xd8;
		if(TIMER_1<temp2)// <230us
		{
			header=0;
			goto str;
		}
		header++;
	}while(header<8);
	TR0=0;
	TF0=0;
	///////////////////如果9个"header"都对,开始接收卡内数据
	TH0=0xfe; //time:300us
	TL0=0xeb;
	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=0xfe; //time:300us
				TL0=0xeb;
				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=0xfe; //time:300us
			TL0=0xeb;
			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);
	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 + -