前言:
曼彻斯特编码
由0到1,表示0;有1到0,表示1;即跳变表示数据;
125KHz的ID卡。ID卡内固化了64位数据,由5个区组成:9个引导位、10个行偶校验位“PO~P9′’、4个列偶校验位“PC0~PC3”、40个数据位“D00~D93”和1个停止位S0。9个引导位是出厂时就已掩膜在芯片内的,其值为“111111111”,当它输出数据时,首先输出9个引导位,然后是10组由4个数据位和1个行偶校验位组成的数据串,其次是4个列偶校验位,最后是停止位“0”。“D00~D13”是一个8位的晶体版本号或ID识别码。“D20~D93”是8组32位的芯片信息,即卡号。注意校验位都是偶校验,网上有些资料写的是奇校验,很明显是错的,如果是奇校验的话,在一个字节是FF的情况下,很容易就出现9个1,这样引导位就不是唯一的了,也就无法判断64位数据的起始位了。
数据格式是:
单片机喂狗程序:会自动复位,需要把它弄清楚才好。原程序只在中断的时候才喂狗,这样狗会叫,所以不行。
要在while(1)循环里面,把喂狗程序加进去,要不然狗要叫的。
曼彻斯特解码:
根据两个下降沿的长度,测量,来判断数据到底是1还是0;
这里要设置一个状态位,以下降沿检测为例;
1,检测到两个下降沿之间的时间为1T
若tag=1,即还有半位没读完,则下一位的值跟当前位的值相同,tag继续为1;
若以下降沿为1,上升沿为0,则当前数据为0,下一位的数据为0;
2检测到两个下降沿之间的数据为1.5T
若当前tag为1,表示还有半位没有读完,当前值我为1,下一位·0
3,2T
若当前Tag=1,当前位为1,下两位数据为01;
源码程序如下:
采用中断方式读时间间隔,经过检测。可以读任何的芒果卡
/**************************************************************** * Project Name: ID Reader Module * COMPANY: SCISHINE * VERSION: V1.0 * DATE: 2010/2/1,2012/11/22 * AUTHOR: Lfyun/wd * IC: STC89C52 ****************************************************************/ //#include <reg52.h> #include <stc12c2052AD.H> //#include "STCIDmodule.h" //#include <intrins.h> //#include <stdio.h> unsigned int Decode_data_temp[5]={0,0,0,0,0}; //????????? //unsigned char Tran_data_temp[11]={0x30,0x35,0x36,0x38,0x32,0x37,0x31,0x33,0x39,0x34,0x0d}; //?????ASCII?? unsigned char Tran_data_temp[11]={0,0,0,0,0,0,0,0,0,0,0}; //?????ASCII?? //10,100,1000,10000, unsigned long int Divsor_temp[9]={0x3b9aca00,0x05f5e100,0x00989680,0x000f4240,0x000186a0,0x00002710,0x000003e8,0x00000064,0x0000000a};//?? unsigned long int Dividen_temp=0; unsigned char Data_buf=0; //??????,?????? unsigned char INT0_Inter_Flag=0; //????????? ?? unsigned char wk=0; //????????9?1,???,??????????9 ?1 unsigned char All_byte_finish_flag=0; //??????????,?????????? unsigned char One_byte_finish_flag=0; //???????? unsigned char Row_check=0; //5???1???,????? ???,??5??1 ??? unsigned char Row_bit_num=0; //??????, ?????? unsigned char Tag=0; //???????? ??? //unsigned char p[2]={0,0}; //unsigned char q=0; void delay(int j); unsigned char Column01_bit_count=0; unsigned char Column02_bit_count=0; unsigned char Column03_bit_count=0; unsigned char Column04_bit_count=0; //???1???,????? ,????1 ??? unsigned char Low_Flag=0; //???????????,??????, unsigned char Data_buf1=0; //??????,?????,????buf unsigned char Byte_num; //0~4????,???????? unsigned char Data_ready=0; //??????,?????? unsigned int Time_Temp_Buf1=0; unsigned int Time_Temp_Buf=0; //??????,1T,1.5T,2T unsigned char First_time_flag=1; ///??????? unsigned char led_buzzer_key=0; ///???? ////sbit Row_check_flag=Row_check^0; //??????? ////sbit Column_check01 = Column01_bit_count^0; /////sbit Column_check02 = Column02_bit_count^0; /////sbit Column_check03 = Column03_bit_count^0; ////sbit Column_check04 = Column04_bit_count^0; ///?????? sbit Buzzer = P1^3; sbit Led = P1^4; //////////#define Band_load 0xcc ///???9600???? #define Band_load 221 //////???1200???? void Sys_Init(); void Decode_Manchester(); void Row_Count(); void Test_5Bit(); void Send_AByte(); void Data_to_AscII(); void Delay_50ms(); void Send_data(); void Led_buzzer(); void delay(int j); /******************************************** ????: Delay_50ms() ????: 50ms?? ????: ? ????: ? ********************************************/ void Delay_50ms() { unsigned char n; unsigned char m; for(m=0;m<=0x0f;m++) {for(n=0;n<=0xfe;n++) ; } return; } /******************************************** ????: Sys_Init() ????: ????? ????: ? ????: ? ********************************************/ void Sys_Init() { WDT_CONTR=0x3c; // P3M0=0x05; // P3M1=0x00; // P1M0=0x00; // P1M1=0x00; //???? Buzzer=0; //???? Led=0; //?? // P1=0x00; Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); TMOD=0x21; //Timer1???????,??8???,???0??16?????,???? // PX0H=1; PX0=1; First_time_flag=1; /////////???UART??????//////// SCON=0x40; AUXR =0x80; //???0???1T,???0?????????,???,???1???1T/12,12?? //////// AUXR&&=#10111111B; //???1???12T TH1=Band_load; TL1=TH1; TCON=0x51; //??Timer0??????,???????,??Timer1??.,?????0????0,?????? IT0=1;//???????,?????,?????????????? ?????? EX0=1; EA=1; IE|=0x91; //??????,UART????,???? ES=0; // P1=0x18; Buzzer =1; //???? return; } /******************************************** ????: Row_Count() ????: ??1?? ????: ? ????: ? ********************************************/ void Row_Count() { switch(Row_bit_num) { case 1:Column01_bit_count++; //????1??? break; case 2:Column02_bit_count++; //????1??? break; case 3:Column03_bit_count++; break; case 4:Column04_bit_count++; break; default: break; } return; } /******************************************** ????: Test_5Bit() ????: ?,???? ????: ? ????: ? ********************************************/ void Test_5Bit() { if(Row_bit_num<=4) return; else { if(Byte_num<=4) { if(Low_Flag==0) { Low_Flag=1; Row_check=Row_check<<7; ///// Checkout(); // if(Row_check&0x01==0x00) // if(Row_check|0xfe==0xfe) if(Row_check==0x00) { //// Checkout_Flag=0; Data_buf=Data_buf>>1; Data_buf1=Data_buf<<4; // Dividen_temp=Dividen_temp>>1; Data_buf=0; Row_check=0; Row_bit_num=0; // Data_ready=1; return; } else { Row_check=0; Row_bit_num=0; Column01_bit_count=0; Column02_bit_count=0; Column03_bit_count=0; Column04_bit_count=0; wk=0; Byte_num=0; Data_buf=0; Data_buf1=0; Dividen_temp=0; return;} } else { Low_Flag=0; Row_check=Row_check<<7; //// Checkout(); // if(Row_check&0x01==0x00) // if(Row_check|0xfe==0xfe) if(Row_check==0x00) {///// Checkout_flag=0; Data_buf=Data_buf>>1; Data_buf1 += Data_buf; // Dividen_temp=Dividen_temp>>1; // Dividen_temp=Dividen_temp|0x01; Data_buf=0; Row_check=0; Row_bit_num=0; // Byte_num++; One_byte_finish_flag=1; return; } else { Row_check=0; Row_bit_num=0; Column01_bit_count=0; Column02_bit_count=0; Column03_bit_count=0; Column04_bit_count=0; wk=0; Byte_num=0; Data_buf=0; Data_buf1=0; Dividen_temp=0; return;} } } else { Column01_bit_count=Column01_bit_count<<7; Column02_bit_count=Column02_bit_count<<7; Column03_bit_count=Column03_bit_count<<7; Column04_bit_count=Column04_bit_count<<7; // if((Column01_bit_count&0x01==0x00)&&(Column02_bit_count&0x01==0x00)&&(Column03_bit_count&0x01==0x00)&&(Column04_bit_count&0x01==0x00)) // if((Column01_bit_count|0xfe==0xfe)&&(Column02_bit_count|0xfe==0xfe)&&(Column03_bit_count|0xfe==0xfe)&&(Column04_bit_count|0xfe==0xfe)) if(Column01_bit_count==0x00&&Column02_bit_count==0x00&&Column03_bit_count==0x00&&Column04_bit_count==0x00) { All_byte_finish_flag=1; //Data_ready=1; Row_check=0; Row_bit_num=0; Column01_bit_count=0; Column02_bit_count=0; Column03_bit_count=0; Column04_bit_count=0; wk=0; Byte_num=0; Data_buf=0; Data_buf1=0; // Dividen_temp=0; return;} else { Row_check=0; Row_bit_num=0; Column01_bit_count=0; Column02_bit_count=0; Column03_bit_count=0; Column04_bit_count=0; wk=0; Byte_num=0; Data_buf=0; All_byte_finish_flag=0; Data_buf1=0; Dividen_temp=0; return;} } } } /******************************************** ????: Send_AByte() ????: ?????????? ????: ? ????: ? ********************************************/ void Send_AByte() { if(One_byte_finish_flag==1) { One_byte_finish_flag=0; switch(Byte_num) { case 0:Decode_data_temp[0]=Data_buf1; Byte_num++; break; case 1:Decode_data_temp[1]=Data_buf1; Dividen_temp+=Data_buf1; Byte_num++; break; case 2:Decode_data_temp[2]=Data_buf1; Dividen_temp=Dividen_temp<<8; Dividen_temp+=Data_buf1; Byte_num++; break; case 3:Decode_data_temp[3]=Data_buf1; Dividen_temp=Dividen_temp<<8; Dividen_temp+=Data_buf1; Byte_num++; break; case 4:Decode_data_temp[4]=Data_buf1; Dividen_temp=Dividen_temp<<8; Dividen_temp+=Data_buf1; Byte_num++; break; default: break; } } } /******************************************** ????: Decode_Manchester() ????: ??? ????: ? ????: ? ********************************************/ //tag=1,???????????????????????????? //tag=0,???????????,?????????? void Decode_Manchester() { // while(INT0_Inter_Flag==0); // INT0_Inter_Flag=0; //1T if((Time_Temp_Buf<=0x2310)&&(Time_Temp_Buf>=0x1900)) // if(Time_Temp_Buf<=0x2100) { if(wk<=0x08) { wk++; Tag=1; // return; } //Data_buf?8?unsinged char ?? else { if(Tag==1) { Tag=1; Data_buf=Data_buf<<1; Data_buf=Data_buf|0x01; // Dividen_temp=Dividen_temp<<1; // Dividen_temp=Dividen_temp|0x01; Row_check++; //?????? Row_bit_num++; Row_Count(); Test_5Bit(); Send_AByte(); // return; } else { Tag=0; Data_buf=Data_buf<<1; // Dividen_temp=Dividen_temp<<1; Row_bit_num++; Test_5Bit(); Send_AByte(); // return; } } // Time_Temp_Buf=0; } //1.5T else if((Time_Temp_Buf<=0x35b0)&&(Time_Temp_Buf>0x2901)) // else if(Time_Temp_Buf<=0x3500) { if(wk<=0x07) { // Row_check=0; Row_bit_num=0; Column01_bit_count=0; Column02_bit_count=0; Column03_bit_count=0; Column04_bit_count=0; wk=0; Byte_num=0; Data_buf=0; Dividen_temp=0; // return; } else if(wk==0x08) { if(Tag==1) { Tag=0;//???0 wk++; Data_buf=Data_buf<<1; // Dividen_temp=Dividen_temp<<1; Row_bit_num++; // Test_5Bit(); // return; } else//???? { Row_check=0; Row_bit_num=0; Column01_bit_count=0; Column02_bit_count=0; Column03_bit_count=0; Column04_bit_count=0; wk=0; Byte_num=0; Data_buf=0; Dividen_temp=0; // return; } } else if(wk>0x08) { if(Tag==1) { Tag=0;//???0 Data_buf=Data_buf<<1; Data_buf=Data_buf|0x01; // Dividen_temp=Dividen_temp<<1; // Dividen_temp=Dividen_temp|0x01; Row_check++; Row_bit_num++; Row_Count(); Test_5Bit(); Send_AByte(); if(All_byte_finish_flag==0) { Data_buf=Data_buf<<1; // Dividen_temp=Dividen_temp<<1; Row_bit_num++; Test_5Bit(); Send_AByte(); } // return; } else { Tag=1; Data_buf=Data_buf<<1; // Dividen_temp=Dividen_temp<<1; Row_bit_num++; Test_5Bit(); Send_AByte(); // return; } } // Time_Temp_Buf=0; } //2T else if((Time_Temp_Buf<=0x4550)&&(Time_Temp_Buf>0x3901)) // else if(Time_Temp_Buf<=5500) { if(wk<=0x07) { Row_check=0; Row_bit_num=0; Column01_bit_count=0; Column02_bit_count=0; Column03_bit_count=0; Column04_bit_count=0; wk=0; Byte_num=0; Data_buf=0; Dividen_temp=0; // return; } else if(wk==0x08) { if(Tag==1) { Tag=1; wk++; Data_buf=Data_buf<<1; // Dividen_temp=Dividen_temp<<1; Row_bit_num++; // Test_5Bit(); // return; } else { Row_check=0; Row_bit_num=0; Column01_bit_count=0; Column02_bit_count=0; Column03_bit_count=0; Column04_bit_count=0; wk=0; Byte_num=0; Data_buf=0; Dividen_temp=0; Tag=0; // return; } } else { if(Tag==1) {Tag=1; Data_buf=Data_buf<<1; Data_buf=Data_buf|0x01; // Dividen_temp=Dividen_temp<<1; // Dividen_temp=Dividen_temp|0x01; Row_check++; Row_bit_num++; Row_Count(); Test_5Bit(); Send_AByte(); if(All_byte_finish_flag==0) { Data_buf=Data_buf<<1; // Dividen_temp=Dividen_temp<<1; Row_bit_num++; Test_5Bit(); Send_AByte(); } // return; } else { Row_check=0; Row_bit_num=0; Column01_bit_count=0; Column02_bit_count=0; Column03_bit_count=0; Column04_bit_count=0; wk=0; Byte_num=0; Data_buf=0; Dividen_temp=0; Tag=0; // return; } } // Time_Temp_Buf=0; } Time_Temp_Buf=0; // All_byte_finish_flag=1; } /* void Decode_Manchester() { unsigned char bb=0; // while(INT0_Inter_Flag==0); // INT0_Inter_Flag=0; if(wk<=0x07) { bb=(Time_Temp_Buf<=0x2510)&&(Time_Temp_Buf>=0x1000); switch(bb) // if(Time_Temp_Buf<=720) { case 1: wk++; Tag=1; break; // return; case 0: wk=0; break; default: break; // All_byte_finish_flag=0; // return; } } else {if(Time_Temp_Buf<=0x2510&&Time_Temp_Buf>=0x1000) // else if(Time_Temp_Buf<=720) { ////// led_buzzer_key=1; //////// Led_buzzer(); if(Tag) { Tag=1; if(wk==0x08) { wk++; Tag=1; // All_byte_finish_flag=0; // return; } else { Data_buf=Data_buf<<1; Data_buf=Data_buf|0x0001; Row_check++; Row_bit_num++; Row_Count(); Test_5Bit(); Send_AByte(); // return; } } else { Tag=0; Data_buf=Data_buf<<1; Row_bit_num++; Test_5Bit(); Send_AByte(); /// return; } } else if(Time_Temp_Buf<=0x36b0&&Time_Temp_Buf>0x2711) /// else if(Time_Temp_Buf<=1065) { if(Tag) { Tag=0; if(wk<=8) { wk++; Tag=0; Data_buf=Data_buf<<1; /// return; } else { Data_buf=Data_buf<<1; Data_buf |= 0x0001; Row_bit_num++; Row_check++; Row_Count(); Test_5Bit(); Send_AByte(); if(All_byte_finish_flag==0) { Data_buf=Data_buf<<1; Row_bit_num++; Test_5Bit(); Send_AByte(); } /// return; } } else { Tag=1; Data_buf=Data_buf<<1; Row_bit_num++; Test_5Bit(); Send_AByte(); //// return; } } else if(Time_Temp_Buf<=0x4650&&Time_Temp_Buf>0x36b1) /// else if(Time_Temp_Buf<=1405) { if(Tag==0) { Row_check=0; Row_bit_num=0; Column01_bit_count=0; Column02_bit_count=0; Column03_bit_count=0; Column04_bit_count=0; wk=0; Byte_num=0; Data_buf=0; /// Data_buf1=0; /// return; } else if(wk<=0x08) { Data_buf=Data_buf<<1; Tag=1; Row_bit_num++; Test_5Bit(); Send_AByte(); /// return; } else { Tag=1; Data_buf=Data_buf<<1; Data_buf |= 0x0001; Row_bit_num++; Row_check++; Row_Count(); Test_5Bit(); Send_AByte(); if(All_byte_finish_flag==0) { Data_buf=Data_buf<<1; Row_bit_num++; Test_5Bit(); Send_AByte(); } /// return; } } } // } return; } /******************************************** ????: Data_to_AscII() ????: ?????????ASCII? ????: ? ????: ? ********************************************/ void Data_to_AscII() { unsigned char j=0; unsigned char i=0; unsigned char k=0; if(All_byte_finish_flag==1) { All_byte_finish_flag=0; led_buzzer_key=1; Tran_data_temp[0]=Dividen_temp/Divsor_temp[0]; Tran_data_temp[1]=(Dividen_temp%Divsor_temp[0])/Divsor_temp[1]; Tran_data_temp[2]=(Dividen_temp%Divsor_temp[1])/Divsor_temp[2]; Tran_data_temp[3]=(Dividen_temp%Divsor_temp[2])/Divsor_temp[3]; Tran_data_temp[4]=(Dividen_temp%Divsor_temp[3])/Divsor_temp[4]; Tran_data_temp[5]=(Dividen_temp%Divsor_temp[4])/Divsor_temp[5]; Tran_data_temp[6]=(Dividen_temp%Divsor_temp[5])/Divsor_temp[6]; Tran_data_temp[7]=(Dividen_temp%Divsor_temp[6])/Divsor_temp[7]; Tran_data_temp[8]=(Dividen_temp%Divsor_temp[7])/Divsor_temp[8]; Tran_data_temp[9]=(Dividen_temp%Divsor_temp[8]); //?????ASCII? for(j=0;j<=0x0a;j++) { if(j<=9) Tran_data_temp[j]+=0x30; else Tran_data_temp[j]='\n'; switch(Tran_data_temp[j]) { case 0x30: k++; break; default: break; } } if(k==0x0a) led_buzzer_key=0; } return; } /* switch(Tran_data_temp[j]) { case 0x30: Tran_data_temp[j]=0x27; break; case 0x31: Tran_data_temp[j]=0x1e; break; case 0x32: Tran_data_temp[j]=0x1f; break; case 0x33: Tran_data_temp[j]=0x20; break; case 0x34: Tran_data_temp[j]=0x21; break; case 0x35: Tran_data_temp[j]=0x22; break; case 0x36: Tran_data_temp[j]=0x23; break; case 0x37: Tran_data_temp[j]=0x24; break; case 0x38: Tran_data_temp[j]=0x25; break; case 0x39: Tran_data_temp[j]=0x26; break; default: break; } */ /******************************************** ????: Led_buzzer() ????: ???????,??,???? ????: ? ????: ? ********************************************/ void Led_buzzer() { if(led_buzzer_key) { Led=1; Buzzer=0; Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Buzzer=1; Led=0; Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Delay_50ms(); Data_ready=1; led_buzzer_key=0; } return; } /******************************************** ????: INT0_int() ????: ?????? ????: ? ????: ? ********************************************/ void Int0_int(void) interrupt 0 { TR0=0; //?????0 // p[0]=TH0; // p[1]=TL0; Time_Temp_Buf|=TH0; Time_Temp_Buf=Time_Temp_Buf<<8; Time_Temp_Buf=Time_Temp_Buf|TL0; // Time_Temp_Buf=(p/16)*16*16*16+(p%16)*16*16+(q/16)*16+q%16; // q=0; if(First_time_flag==1) { First_time_flag=0; Time_Temp_Buf=0; } else INT0_Inter_Flag=1;//????????????? // All_byte_finish_flag=1; TL0=0; TH0=0; TR0=1;//?????0 } /******************************************** ????: Send_data() ????: ??????????? ????: ? ????: ? ********************************************/ void Send_data() { unsigned char k=0; RI=0; // EX0=0; if(1==Data_ready) { for(k=0;k<=0x0a;k++) { // SBUF=Row_check; SBUF=Tran_data_temp[k]; // SBUF=wk; // SBUF='a'; while(0==TI); TI=0; Tran_data_temp[k]=0; // Row_check=0; } Dividen_temp=0; First_time_flag=1; } Data_ready=0; // EX0=1; return; } void main() { Sys_Init(); // Pwm_125K_Out(); while(1) { // if(INT0_Inter_Flag==1) // { while(INT0_Inter_Flag) { INT0_Inter_Flag=0; Decode_Manchester(); Data_to_AscII(); Led_buzzer(); Send_data(); WDT_CONTR=0x3c; // Buzzer = 0; //???? // Led = 0; //?? // P1=0x00; // Buzzer =1; //???? // Led = 1; //?? // P1=0x18; // delay(3); } } } void delay(int j) { for(;j>0;j--); }