曼彻斯特解码原则+KEM系列RFID卡解码源程序分析.docx
《曼彻斯特解码原则+KEM系列RFID卡解码源程序分析.docx》由会员分享,可在线阅读,更多相关《曼彻斯特解码原则+KEM系列RFID卡解码源程序分析.docx(32页珍藏版)》请在冰豆网上搜索。
曼彻斯特解码原则+KEM系列RFID卡解码源程序分析
曼彻斯特解码原则+K-EM系列RFID卡解码源程序分析
————————————————————————————————作者:
————————————————————————————————日期:
曼彻斯特解码原则+125KEM4100系列RFID卡解码源程序分析
曼彻斯特解码原则
1.曼彻斯特编码
曼彻斯特编码(Manchester Encoding),也叫做相位编码(PE),是一个同步时钟编码技术,被物理层使用来编码一个同步位流的时钟和数据。
曼彻斯特编码被用在以太网媒介系统中。
曼彻斯特编码提供一个简单的方式给编码简单的二进制序列而没有长的周期没有转换级别,因而防止时钟同步的丢失,或来自低频率位移在贫乏补偿的模拟链接位错误。
在这个技术下,实际上的二进制数据被传输通过这个电缆,不是作为一个序列的逻辑1或0来发送的(技术上叫做反向不归零制(NRZ))。
相反地,这些位被转换为一个稍微不同的格式,它通过使用直接的二进制编码有很多的优点。
曼彻斯特编码,常用于局域网传输。
在曼彻斯特编码中,每一位的中间有一跳变,位中间的跳变既作时钟信号,又作数据信号;从高到低跳变表示"1",从低到高跳变表示"0"。
还有一种是差分曼彻斯特编码,每位中间的跳变仅提供时钟定时,而用每位开始时有无跳变表示"0"或"1",有跳变为"0",无跳变为"1"。
对于以上电平跳变观点有歧义:
关于曼彻斯特编码电平跳变,在雷振甲编写的<<网络工程师教程>>中对曼彻斯特编码的解释为:
从低电平到高电平的转换表示1,从高电平到低电平的转换表示0,模拟卷中的答案也是如此,张友生写的考点分析中也是这样讲的,而《计算机网络(第4版)》中(P232页)则解释为高电平到低电平的转换为1,低电平到高电平的转换为0。
清华大学的《计算机通信与网络教程》《计算机网络(第4版)》采用如下方式:
曼彻斯特编码从高到低的跳变是0 从低到高的跳变是1。
两种曼彻斯特编码是将时钟和数据包含在数据流中,在传输代码信息的同时,也将时钟同步信号一起传输到对方,每位编码中有一跳变,不存在直流分量,因此具有自同步能力和良好的抗干扰性能。
但每一个码元都被调成两个电平,所以数据传输速率只有调制速率的1/2。
就是说主要用在数据同步传输的一种编码方式。
【在曼彻斯特编码中,用电压跳变的相位不同来区分1和0,即用正的电压跳变表示0,用负的电压跳变表示1。
因此,这种编码也称为相应编码。
由于跳变都发生在每一个码元的中间,接收端可以方便地利用它作为位同步时钟,因此,这种编码也称为自同步编码。
】
2. 曼彻斯特编码(Manchester Encoding),也叫做相位编码(PE);常用于局域网传输。
在曼彻斯特编码中,每一位的中间有一跳变,位中间的跳变既作时钟信号,又作数据信号。
但在不同的书籍中,曼彻斯特编码中,电平跳动表示的值不同,这里产生很多歧义:
ﻫ1、在网络工程师考试以及与其相关的资料中:
位中间电平从高到低跳变表示"0";ﻫ位中间电平从低到高跳变表示"1"。
ﻫ2、在一些《计算机网络》书籍中:
ﻫ位中间电平从高到低跳变表示"1";ﻫ位中间电平从低到高跳变表示"0"。
ﻫ在清华大学出版的《计算机通信与网络教程》《计算机网络(第4版)》也是这么说的,就以此为标准,我们就叫这为标准曼彻斯编码。
至于第一种,我们在这里就叫它曼彻斯特编码。
但是要记住,在不同的情况下懂得变通哦,否则会被老师扣分数的哦。
这两者恰好相反,千万别弄混淆了。
现在我们要讲的就是差分曼彻斯特编码:
ﻫ在信号位开始时不改变信号极性,表示辑"1"
在信号位开始时改变信号极性,表示逻辑"0" ;ﻫ【注意】:
如果在最初信号的时候,即第一个信号时:
ﻫ如果中间位电平从低到高,则表示0;
如果中间位电平从高到低,则表示1;
后面的(从第二个开始)就看每个信号位开始时有没有跳变来决定:
ﻫ下面我们来举个例子,来比较标准曼彻斯特编码、曼彻斯特编码、差分曼彻斯特编码:
ﻫ
EM4100系列用的是:
曼彻斯特编码!
125K;EM4100系列RFID卡解码源程序分析
1.ﻫ我们知道了曼彻斯特编码原则,那么反过来的过程就是解码了。
ﻫ
EM4100系列用的是:
曼彻斯特编码!
2.传统只读射频卡读卡器的设计一般采用U2270B或EM4095读写基站芯片加MCU模式,其成本高、功耗大。
本文介绍一种采用一片74HC4060+LM258/358加少量普通元件构成的读卡器电路和处理的程序设计方案,电路简单、功耗小、成本低。
74HC4060+LM258/358电路为市面上已非常成熟RFID-125KHZ-I卡且广泛采用的低功耗、低成本方案。
该方案在门禁、保安、考勤、展览会、公园、旅店、餐厅等公共场所的门票、优惠卡以及生产过程、邮政包裹、航空铁路运输、产品包装、交通等部门的物流、电子标签、防伪标志、一次性票证等众多领域上占据半壁江山。
3.推挽式放大电路输出後接LC串联谐振电路,当回路固有谐振频率与输入讯号频率相等时,电路发生串联谐振。
本文只要求对125kHz频率的讯号放大,所以根据串联谐振公式
计算电路中元件参数,可得L=737uH,C=2200pF。
4.包络检波电路
感应线圈产生谐振电压约有20V,所以载波讯号的电压也约为20V。
对输入电压高於500mV检波,称为「大讯号检波」,利用二极体单向导电特性及检波负载RC充放电过程实现。
RC参数的确定需要满足两个条件:
1.不产生隋性失真,一般工程上按
计算,f为载波频率。
2.不产生负峰切割失真,即
m为调幅系数,R1是交流阻值,R0是直流阻值。
联立上述两个条件,确定检波电路中R12、C36分别为470kΩ、4700pF。
5.波形整形电路
在单晶片处理之前,整形电路将检波後的讯号变成单片机可以识别的高低电平。
LM358 (LM258) 内部整合两个运放,经过两次整形後可以得到很好的方波讯号。
电路中R16、R17、R18、R19起到分压作用,确定输出翻转门限为2.5V;R15、R21将同向输入的电压叠加在反向输入端;C54、C55为耦合电容,能够隔离直流分量,传递交流讯号。
当U+大於U-+2.5V时,输出高电平;当U+小於U-+2.5V时,输出低电平。
6.读卡程序是根据EM4100、EM4001系列射频卡的特点量身定做的一段程序,射频卡以曼彻斯特编码,传输一个资料的时间t=64/125kHz=512μs。
实际使用中,一般传输时间为,230μs<0.5t<280μs。
280μs<定时器取样时间<512μs。
所以本文中取样波形时,定时器时间设定为400μs,保证为取样留有足够的时间。
原程序分析:
1.定时器时间设定为400μs
#defineTH0_H 0xfe// 定时器0取样定时值设定为400us
#defineTL0_L 0x8f//8f
2.定时器0中断优先级最高:
PT0=1;
3.//曼彻斯特码同步头检测,9个1采用逐个前移检测法
//逐个前移检测法,即每检测到一个数据,如果是"1",并向数据库写入1,
//如果是"0",就放弃当前检测的数据,并向当前数据流方向移动一位,
//这样一来,就保证了不管数据流是在何种状态下,都能正确无误地抓取9个1,
//同步头9个1的提取成功,曼彻斯特码译码器即和当前的数据流保持了同步,
//并把余下的55位数据全部译完。
ﻩ
4.uchar REM_Buffer[14];//曼彻斯特码解码后得到最终数据的缓存0~13
/*曼彻斯特码解码后的数据放在REM_Buffer[0~13];
REM_Buffer[0]=0xff数据格式:
11111111同步头,8个1
REM_Buffer[1]=0x8x数据格式:
1xxxxxxx同步头,1个1,x表示无意义
REM_Buffer[2]= 数据格式:
D00D01D02D03P0xxx 八个版本位或厂商信息的前四位,x表示无意义;P0为行效验位
REM_Buffer[3]= 数据格式:
D10D11D12D13P1xxx八个版本位或厂商信息的后四位,x表示无意义;P1为行效验位
REM_Buffer[4]=数据格式:
D20D21D22D23P2xxx三十二个数据,x表示无意义;P2为行效验位
REM_Buffer[5]= 数据格式:
D30D31D32D33 P3xxx三十二个数据,x表示无意义;P3为行效验位
REM_Buffer[6]= 数据格式:
D40D41D42D43P4xxx三十二个数据,x表示无意义;P4为行效验位
REM_Buffer[7]=数据格式:
D50D51D52D53P5xxx三十二个数据,x表示无意义;P5为行效验位
REM_Buffer[8]= 数据格式:
D60D61D62D63P6xxx三十二个数据,x表示无意义;P6为行效验位
REM_Buffer[9]= 数据格式:
D70D71D72D73P7xxx 三十二个数据,x表示无意义;P7为行效验位
REM_Buffer[10]= 数据格式:
D80D81D82D83 P8xxx三十二个数据,x表示无意义;P8为行效验位
REM_Buffer[11]= 数据格式:
D90D91D92D93P9xxx 三十二个数据,x表示无意义;P9为行效验位
REM_Buffer[12]= 数据格式:
PC0PC1PC2PC30xxx四个列效验位,x表示无意义;0为停止位
原程序:
//2008.10.15
//125K;EM4100系列RFID卡解码
//#include<reg52.h>//使用AT89S51/52等系列单片机头文件
#include<STC12C5410AD.h>//stc系列单片机专用头文件
#include<intrins.h>
#define uint unsigned int//定义
#defineucharunsigned char//定义
#define ulongunsignedlong//定义
sbit REM=P2^1;//曼彻斯特编码输入端
sbitCLK=P3^3;//产生125KHZ时钟信号端
sbit LED=P2^5;//红灯
sbit SPP=P1^0;//喇叭
bit REM_BIT;//曼彻斯特码高、低边沿跳变标志位,
bit Efficacy_BIT; //待效验标志位,
bitP_PC_BIT; //行,列效验标志位
bit YES_NO_BIT;//效验正确,或效验错误标志位,
//YES_NO_BIT=1表示效验正确;
//YES_NO_BIT=0表示效验错误。
#defineTH0_H0xfe//定时器0取样定时值设定为400us
#defineTL0_L 0x8f//8f
//350~420us
//375~450us
uchar U_D_Buffer[5];//User_Data//用户数据缓存,
ulong long_D;//方法1,卡号在 long_D 中,不足10位,则在高位前面加0
ucharchar_D;//方法2,前两位卡号在 char_D中,
uint int_D;//方法2,卡号后4位卡号在int_D中,
uchar volue;//volue为曼彻斯特码译码时的临时运算缓存
uchar REM_Buffer[14];//曼彻斯特码解码后得到最终数据的缓存0~13
/*曼彻斯特码解码后的数据放在REM_Buffer[0~13];
REM_Buffer[0]=0xff数据格式:
11111111 同步头,8个1
REM_Buffer[1]=0x8x数据格式:
1xxxxxxx同步头,1个1,x表示无意义
REM_Buffer[2]= 数据格式:
D00D01D02D03P0xxx八个版本位或厂商信息的前四位,x表示无意义;P0为行效验位
REM_Buffer[3]= 数据格式:
D10D11D12D13 P1xxx八个版本位或厂商信息的后四位,x表示无意义;P1为行效验位
REM_Buffer[4]= 数据格式:
D20D21D22D23P2xxx三十二个数据,x表示无意义;P2为行效验位
REM_Buffer[5]= 数据格式:
D30D31D32D33P3xxx三十二个数据,x表示无意义;P3为行效验位
REM_Buffer[6]= 数据格式:
D40D41D42D43P4xxx 三十二个数据,x表示无意义;P4为行效验位
REM_Buffer[7]= 数据格式:
D50D51D52D53P5xxx三十二个数据,x表示无意义;P5为行效验位
REM_Buffer[8]= 数据格式:
D60D61D62D63P6xxx三十二个数据,x表示无意义;P6为行效验位
REM_Buffer[9]= 数据格式:
D70D71D72D73P7xxx 三十二个数据,x表示无意义;P7为行效验位
REM_Buffer[10]= 数据格式:
D80D81D82D83 P8xxx三十二个数据,x表示无意义;P8为行效验位
REM_Buffer[11]= 数据格式:
D90D91D92D93 P9xxx 三十二个数据,x表示无意义;P9为行效验位
REM_Buffer[12]= 数据格式:
PC0PC1PC2PC30xxx四个列效验位,x表示无意义;0为停止位
*/
ucharcodeDispTab[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
ucharcodeData[]={"Data:
"};//数据
ucharcodeUserData[]={"User Data:
"};//用户数据
ucharcodeCard_1[]={"Methods1 DecimalCardNumber:
"};//方法1:
掐头留尾法提取10位十进制卡号:
ucharcodeCard_2[]={"Methods 2DecimalCardNumber:
"};////方法2:
前两位+后4位的微根格式,段间以小数点或豆号隔开
ucharcode DispTab_2[]={' ','H',','};
voidinit()//
{
ﻩTMOD=0x21;
TH1=0xfd;//11.0592MHz 波特率:
9600
TL1=0xfd;
PCON&=0x80;
SCON=0x40;
//AUXR=0x40;//波特率倍增 //11.0592MHz 115200
ﻩTH0=0x00;//
TL0=0x00;//
EA=1;
ET0=1;
ﻩTR0=0;
TR1=1;
ﻩES=0;
REN=1;
PT0=1;
//PT0H=1;//定时器0中断优先级最高:
第三
ﻩﻩ//PT0H是stc单片机特有的寄存器
REM=1;
CLK=1;
SPP=1;
ﻩLED=1;
REM_BIT=1;
}
voiddelay1(uintz)//delay(10);10次为1ms
{ﻩucharx;
ﻩfor(;z>0;z--)
ﻩ{
ﻩfor(x=0;x<160;x++)
{
}
ﻩ}
}
/*
void delay()//
{
_nop_();
_nop_();
_nop_();
}
*/
void Time_interrupt(void) interrupt1 //定时器0中断
{
TR0=0;//关闭定时器0,为曼彻斯特码提取数据定时器
}
void RS232_in(void) interrupt4//串口中断
{
ﻩEA=0;
ﻩif(RI==1)//接收
ﻩ{
RI=0;
ﻩ ﻩ//SBUF_RI_Buffer[0]=SBUF;//RS2323接收缓冲区
ﻩ}
//////////////////
ﻩelse //if(TI==1)//发送
ﻩTI=0;
ﻩEA=1;
}
void RS232()//通信转输数据,发给PC
{
ﻩuchari;
ulongmm;
ﻩ//ES=0;
ﻩif((REM_Buffer[0]==0xff)&&(REM_Buffer[1]==0x80))//同步头9个1的判断,同步头正确,进入数据发送,否则退出
ﻩ{
ﻩ
ﻩﻩfor(i=0;i<6;i++)
ﻩ{
ﻩﻩﻩSBUF=Data[i];//""
ﻩﻩwhile(TI==0);
ﻩﻩTI=0;
ﻩﻩ}
for(i=0;i<13;i++)
ﻩ{
SBUF=DispTab[(REM_Buffer[i]/16)];
ﻩﻩ//SBUF=REM_Buffer[i];//给 PC 发送REM_Buffer[0~13]个数据
ﻩﻩwhile(TI==0);//TI=1,表示数据发送完毕,
ﻩﻩﻩTI=0;//TI清零,并把余下的数据继续发送,直到13个数据全部发送完。
ﻩSBUF=DispTab[(REM_Buffer[i]%16)];
ﻩwhile(TI==0);
ﻩﻩﻩTI=0;
ﻩSBUF=DispTab_2[1];//'H'
ﻩwhile(TI==0);
ﻩﻩTI=0;
ﻩSBUF=DispTab_2[0];//''
ﻩwhile(TI==0);
ﻩﻩﻩTI=0;
ﻩﻩ}
ﻩfor(i=0;i<94;i++)
{
SBUF=DispTab_2[0];//" "
while(TI==0);
ﻩTI=0;
ﻩ}
ﻩ//U_D_Buffer[5];//User_Data//用户数据缓存,
ﻩﻩfor(i=0;i<11;i++)
{
SBUF=UserData[i];//""
while(TI==0);
ﻩﻩTI=0;
}
ﻩfor(i=0;i<5;i++)
ﻩ{
ﻩﻩSBUF=DispTab[(U_D_Buffer[i]/16)];
ﻩﻩﻩwhile(TI==0);
ﻩﻩTI=0;
ﻩﻩSBUF=DispTab[(U_D_Buffer[i]%16)];
ﻩwhile(TI==0);
ﻩTI=0;
ﻩSBUF=DispTab_2[1];//'H'
ﻩwhile(TI==0);
ﻩﻩﻩTI=0;
ﻩﻩSBUF=DispTab_2[0];//''
ﻩwhile(TI==0);
ﻩTI=0;
ﻩﻩ}
ﻩfor(i=0;i<120;i++)
{
ﻩﻩSBUF=DispTab_2[0];//""
ﻩﻩwhile(TI==0);
ﻩﻩTI=0;
ﻩ}
ﻩfor(i=0;i<31;i++)
ﻩ{
ﻩﻩSBUF=Card_1[i];//" "
ﻩﻩwhile(TI==0);
ﻩTI=0;
ﻩ}
//10位十进制卡号Card_1
ﻩﻩSBUF=DispTab[long_D/1000000000];//10
ﻩﻩwhile(TI==0);
ﻩTI=0;
ﻩmm=long_D%1000000000;
ﻩﻩSBUF=DispTab[mm/100000000];//9
ﻩwhile(TI==0);
TI=0;
ﻩﻩmm=long_D%100000000;
ﻩSBUF=DispTab[mm/10000000];//8
ﻩﻩwhile(TI==0);
TI=0;
ﻩmm=long_D%10000000;
ﻩﻩSBUF=DispTab[mm/1000000];//7
ﻩﻩwhile(TI==0);
TI=0;
ﻩmm=long_D%1000000;
ﻩSBUF=DispTab[mm/100000];//6
while(TI==0);
TI=0;
mm=mm%100000;
ﻩSBUF=DispTab[mm/10000];//5
ﻩﻩwhile(TI==0);
ﻩTI=0;
mm=long_D%10000;
ﻩﻩSBUF=DispTab[mm/1000];//4
while(TI==0);
ﻩTI=0;
ﻩmm=long_D%1000;
ﻩSBUF=DispTab[mm/100];//3
ﻩwhile(TI==0);
ﻩTI=0;
ﻩmm=long_D%100;
ﻩﻩSBUF=DispTab[mm/10];//2
ﻩﻩwhile(TI==0);
TI=0;
ﻩSBUF=DispTab[mm%10];//1
ﻩwhile(TI==0);
TI=0;
//////////////////////////////////Card_2
ﻩfor(i=0;i<106;i++)
{
ﻩﻩSBUF=DispTab_2[0];//""
ﻩﻩwhile(TI==0);
ﻩTI=0;
ﻩ}
ﻩfor(i=0;i<31;i++)
ﻩﻩ{
ﻩﻩSBUF=Card_2[i];//""
ﻩﻩwhile(TI==0);
ﻩﻩﻩTI=0;
ﻩﻩ}
ﻩﻩSBUF=DispTab[char_D/100];//
while(TI==0);
ﻩTI=0;
ﻩchar_D=char_D%100;
ﻩSBUF=DispTab[char_D/10];//
ﻩwhile(TI==0);
ﻩTI=0;
ﻩSBUF=DispTab[char_D%10];//
while(TI==0);
ﻩﻩTI=0;
ﻩSBUF=DispTab_2[2];//////////////////////
while(TI==0);
ﻩTI=0;
ﻩﻩSBUF=DispTab[int_D/10000];//
ﻩﻩwhile(TI==0);
ﻩTI=0;
int_D=int_D%10000;
ﻩﻩSBUF=DispTab[int_D/1000];//
while(TI==0);
ﻩﻩTI=0;
ﻩﻩint_D=int_D%1000;
ﻩSBUF=DispTab[int_D/100];//
ﻩwhile(TI==0);
ﻩTI=0;
ﻩint_D=int_D%100;
ﻩSBUF=DispTab[int_D/10];//
while(TI==0);
ﻩTI=0;
ﻩﻩSBUF=DispTab[int_D%10];//
ﻩwhile(TI==0);
ﻩTI=0;
ﻩfor(i=0;i<109;i++)
ﻩ{
ﻩﻩﻩSBUF=DispTab_2[0];//""
ﻩﻩwhile(TI==0);
ﻩﻩﻩTI=0;
ﻩﻩ}
ﻩ//}
}
ﻩ
ﻩ//ES=0;
}
void REM_init()//射频接口初始化
{
ﻩCLK=0;//为74HC4060提供+5