/********************************************
EM开发板v2.0 读卡演示程序
IC卡技术网 http://www.iccardtech.com
IC卡技术论坛 http://www.cardbbs.net
*************************************************/
#include <REGX52.H>
#include <string.h>
#include <stdio.h>
#include <absacc.h>
#include <intrins.h>
#define SPK P1_6 //蜂鸣器
#define LED P1_7 //指示灯
#define INPORT P1_1 //解码输入
//用来区分脉冲宽度的参数
/* 11.0592MHz
#define TIME00 50
#define TIME05 260
#define TIME10 550
*/
#define TIME00 83
#define TIME05 433
#define TIME10 927
bit bitin; //上一次的状态位
unsigned char Buff[30]; //解码缓冲区
void delay_ms(unsigned int ms)
{
unsigned char i;
while(ms--)
{
i=112;
while(i--);
}
}
void printchar(unsigned char ch)
{
if(ch>=0&&ch<=9) ch=ch+'0';
else if(ch>=10&&ch<=15) ch=ch+'A'-10;
putchar(ch);
}
void printhex(unsigned char hex)//以十六进制格式输出1个字节
{
unsigned char c;
c=hex;
c=c>>4;
printchar(c);
c=hex;
c=c&0x0F;
printchar(c);
}
//检测数据位
unsigned char readbit()
{
unsigned int mk=TIME10; //装入超时值
TL0=TH0=0; //初始化计时器
TR0=1; //开始计时
while(--mk) //超时机制,防止死等
if(bitin!=INPORT) //有跳变
break;
TR0=0; //停止计时
if(mk==0) //超时退出
return 0;
bitin=INPORT; //保存状态
mk=TH0*256+TL0; //计算这样跳变的脉宽
if((mk>TIME05)&&(mk<=TIME10)) //一个周期
return 1;
if((mk>=TIME00)&&(mk<=TIME05)) //半个周期
return 2;
return 0; //出错
}
//读一个完整的数据位
unsigned char readdata()
{
switch(readbit())
{
case 1: //一个周期
return !bitin;
case 2: //半个周期
if(readbit()!=2) return 2; //再读一次半个周期
return !bitin;
default:
return 2;
}
}
//接收并解码
bit CheckData()
{
unsigned char i,j;
bitin=INPORT; //保存位状态
for(i=0;i<9;i++) //检测9个数据位1
{
if(readdata()!=1)
return 0;
}
//读取数据
for(i=0;i<11;i++)
{
Buff[i]=0x00;
for(j=0;j<5;j++)
{
Buff[i]<<=1;
switch(readdata())
{
case 0: //0
break;
case 1: //1
Buff[i]|=0x08;
break;
case 2: //err
return 0;
}
}
}
//结束位
if(Buff[10]&0x08!=0x00)
return 0;
//行奇校验位
for(i=0;i<10;i++)
if((((Buff[i]>>4) ^
(Buff[i]>>3) ^
(Buff[i]>>2) ^
(Buff[i]>>1) ^
Buff[i])&0x08)!=0)
return 0;
//列奇校验位
j=0;
for(i=0;i<11;i++)
j=j ^ (Buff[i]&0x80);
if(j!=0)
return 0;
for(i=0;i<11;i++)
j=j ^ (Buff[i]&0x40);
if(j!=0)
return 0;
for(i=0;i<11;i++)
j=j ^ (Buff[i]&0x20);
if(j!=0)
return 0;
for(i=0;i<11;i++)
j=j ^ (Buff[i]&0x10);
if(j!=0)
return 0;
//完成
return 1;
}
bit ReadCardNo()
{
if(CheckData()) //检测卡
{
unsigned char i;
//编码输出
Buff[0]=(Buff[2] & 0xF0) | (Buff[3]>>4 & 0x0F);
Buff[1]=(Buff[4] & 0xF0) | (Buff[5]>>4 & 0x0F);
Buff[2]=(Buff[6] & 0xF0) | (Buff[7]>>4 & 0x0F);
Buff[3]=(Buff[8] & 0xF0) | (Buff[9]>>4 & 0x0F);
SPK=0;
LED=0;
// printf("SN is 0x");
for(i=0;i<4;i++)
printhex(Buff[i]);
// putchar('\n');
delay_ms(300);
SPK=1;
LED=1;
delay_ms(700);
return 1;
}
return 0;
}
void init(void)
{
LED=0;
SPK=0;
TMOD=0x21;
TH1=0xFb;
SCON=0x50;
PCON=0x00;
TR1=1;
TI=1;
//EA=1;
INPORT=1;
printf("Start\n");
delay_ms(300);
LED=1;
SPK=1;
}
main()
{
//初始化
init();
for(;;)
{
ReadCardNo();
//在这里可以做其它事.
}
}