本發(fā)明涉及讀卡器領(lǐng)域,尤其涉及一種非接觸式ic卡讀卡器設(shè)計(jì)。
背景技術(shù):
智能卡的名稱來(lái)源于英文名詞“smartcard”,又稱集成電路卡,即ic卡。它將一個(gè)集成電路芯片鑲嵌于塑料基片中,封裝成卡的形式,其外形與覆蓋磁條的磁卡相似。
ic卡的概念是70年代初提出來(lái)的,法國(guó)布爾(bull)公司于1976年首先創(chuàng)造出ic卡產(chǎn)品,并將這項(xiàng)技術(shù)應(yīng)用到金融、交通、醫(yī)療、身份證明等多個(gè)行業(yè),它將微電子技術(shù)和計(jì)算機(jī)技術(shù)結(jié)合在一起,提高了人們生活和工作的現(xiàn)代化程度。在此后的十幾年間,除法國(guó)的布爾公司之外,世界上先后有motorola、ti、thomson、hitachi、oki、toshiba、sharp、atmel、gemplus、schlumberger、philips等十幾家公司相繼投入了智能卡芯片和卡片成品的開發(fā)與生產(chǎn),形成了一個(gè)世界性的新興技術(shù)產(chǎn)業(yè)。
當(dāng)前,用于信息處理的卡片種類繁多,而且基本上都采用了較新的技術(shù),ic卡脫穎而出的原因在于它對(duì)于磁卡、pet卡、光卡和凸字卡等其它種類的卡具有存儲(chǔ)容量大、體積小、重量輕,抗干擾能力強(qiáng),便于攜帶、安全性高、對(duì)網(wǎng)絡(luò)的要求不高等突出的特點(diǎn),正是由于這些特點(diǎn),使得ic卡從誕生至今雖然只有短短數(shù)年,但其市場(chǎng)卻遍布世界各地。在全球智能卡蓬勃發(fā)展之際,中國(guó)于1993年提出了“金卡工程”。金卡工程是以電子貨幣應(yīng)用為重點(diǎn)的各類卡基應(yīng)用系統(tǒng)工程,是為了實(shí)現(xiàn)電子貨幣大范圍流通的跨部門、跨地區(qū)和跨世紀(jì)的系統(tǒng)工程。在“金卡工程”提出至今10年來(lái),我國(guó)ic卡應(yīng)用發(fā)展迅猛,累計(jì)發(fā)卡約10億張,據(jù)不完全統(tǒng)計(jì),僅2015年一年,我國(guó)發(fā)行使用各類ic卡約3.5億張左右。ic卡目前已在商貿(mào)、交通、電信、醫(yī)療、衛(wèi)生保健、社會(huì)保險(xiǎn)、金融、稅務(wù)、工商、公安、組織機(jī)構(gòu)代碼和城市公共事業(yè)管理等許多領(lǐng)域得到廣泛應(yīng)用,并取得了初步的社會(huì)和經(jīng)濟(jì)效益。它對(duì)提高現(xiàn)代化管理水平和人民的生活質(zhì)量,推動(dòng)整個(gè)社會(huì)信息化進(jìn)程具有重要作用。本發(fā)明正是在這種環(huán)境下提出的。
技術(shù)實(shí)現(xiàn)要素:
本發(fā)明涉及一種非接觸式ic卡讀卡器設(shè)計(jì),本發(fā)明開發(fā)了一種讀寫距離為25mm的非接觸式ic卡讀卡器,本發(fā)明詳細(xì)地闡述了非接觸式ic卡讀卡器的硬件和軟件設(shè)計(jì),給出了每一部分的實(shí)際電路圖和應(yīng)用程序。讀卡器的硬件設(shè)計(jì)包括電源供應(yīng)電路、蜂鳴器驅(qū)動(dòng)電路、rs232通信電路、mcu的連接、mfrc500接口電路和讀卡器天線這幾部分的設(shè)計(jì)。軟件設(shè)計(jì)分為對(duì)mfrc500的應(yīng)用程序的設(shè)計(jì)、對(duì)讀卡器其他電路的應(yīng)用程序設(shè)計(jì)和主程序設(shè)計(jì)三個(gè)部分,每一部分都給出了具體程序并對(duì)程序進(jìn)行了詳細(xì)的說明。本發(fā)明具有典型讀寫距離為20~25mm、配有rs232通訊接口,便于同上位機(jī)通訊、專為門禁系統(tǒng)設(shè)計(jì)、小巧,價(jià)格便宜等特點(diǎn)。
附圖說明
圖1:非接觸式ic卡讀卡器結(jié)構(gòu)框圖。
圖2:max232的電路連接圖。
圖3:電源供應(yīng)電路圖。
圖4:讀卡器對(duì)mifare卡片的操作流程圖。
圖5:讀卡器主程序框圖。
具體實(shí)施方式
為了使本發(fā)明的目的、技術(shù)方案及優(yōu)點(diǎn)更加清楚明白,以下結(jié)合附圖及實(shí)施例,對(duì)本發(fā)明進(jìn)行進(jìn)一步詳細(xì)說明。應(yīng)當(dāng)理解,此處所描述的具體實(shí)施例僅僅用以解釋本發(fā)明,并不用于限定本發(fā)明。
本發(fā)明涉及一種非接觸式ic卡讀卡器設(shè)計(jì),本發(fā)明開發(fā)了一種讀寫距離為25mm的非接觸式ic卡讀卡器,本發(fā)明詳細(xì)地闡述了非接觸式ic卡讀卡器的硬件和軟件設(shè)計(jì),給出了每一部分的實(shí)際電路圖和應(yīng)用程序。讀卡器的硬件設(shè)計(jì)包括電源供應(yīng)電路、蜂鳴器驅(qū)動(dòng)電路、rs232通信電路、mcu的連接、mfrc500接口電路和讀卡器天線這幾部分的設(shè)計(jì)。軟件設(shè)計(jì)分為對(duì)mfrc500的應(yīng)用程序的設(shè)計(jì)、對(duì)讀卡器其他電路的應(yīng)用程序設(shè)計(jì)和主程序設(shè)計(jì)三個(gè)部分,每一部分都給出了具體程序并對(duì)程序進(jìn)行了詳細(xì)的說明。本發(fā)明具有典型讀寫距離為20~25mm、配有rs232通訊接口,便于同上位機(jī)通訊、專為門禁系統(tǒng)設(shè)計(jì)、小巧,價(jià)格便宜等特點(diǎn)。
圖1為本發(fā)明的非接觸式ic卡讀卡器結(jié)構(gòu)框圖。非接觸式ic卡讀卡器硬件電路包括以下幾個(gè)部分:微控制器、mifare讀寫芯片、天線匹配電路、天線、rs232通信電路、復(fù)位電路、電源電路、led狀態(tài)顯示和蜂鳴器驅(qū)動(dòng)電路等,分布于兩塊電路板上,即控制電路板和天線電路板。
本發(fā)明cpu采用8位微處理器中選取了atmel公司生產(chǎn)的at89c51(其指令與mcs51系列兼容)。所使用的仿真器為南京wave公司生產(chǎn)的g6w型,該仿真器支持匯編語(yǔ)言、c51高級(jí)語(yǔ)言、pl/m語(yǔ)言。編程器為top2000型編程器。
本發(fā)明讀卡器采用串行接口芯片max232通過標(biāo)準(zhǔn)的db9直接與pc機(jī)相連。max232是xim公司生產(chǎn)的專用串行接口芯片,包括2路接收器和驅(qū)動(dòng)器,本發(fā)明只用其中一路發(fā)器。芯片內(nèi)部有一個(gè)電源電壓變換器可把輸入的+5v電源電壓變換為rs232輸出電所需的±10v電壓。所以使用此接口芯片的串行通信系統(tǒng)只需單一的+5v電在本發(fā)明中硬件上采用3線制(rxd、txd、gnd)軟握手的零modem方式,即pc機(jī)和單片機(jī)的發(fā)送數(shù)據(jù)線(txd)與接收數(shù)據(jù)(rxd)交叉連接,二者的地線(gnd)接相連,而其它信號(hào)線如握手信號(hào)線均不用,而采用軟件握手。max232的電路連接如圖2所示。
本發(fā)明讀卡器內(nèi)所有芯片的工作電壓均為5v,讀卡器采用外接電源供電,220v市電經(jīng)變壓器降壓,再經(jīng)穩(wěn)壓電路穩(wěn)壓成5v后供應(yīng)讀卡器內(nèi)芯片。本讀卡器選用7805芯片進(jìn)行穩(wěn)壓,電路圖如圖3所示。
本發(fā)明電感藕合式射頻識(shí)別系統(tǒng)的讀寫器天線用于產(chǎn)生磁通量,而磁通量用于向非接觸式ic卡提供電源并在讀卡器與非接觸式ic卡之間傳輸信息。因此,對(duì)讀卡器天線的構(gòu)造就有三個(gè)基本要求:首先是使天線線圈的電流最大,用于產(chǎn)生最大的磁通量:其次是功率要匹配,以最大程度地利用產(chǎn)生磁通量的可用能量;最后是要有足夠的帶寬,以無(wú)失真地傳送用數(shù)據(jù)調(diào)制的載波信號(hào)。
本發(fā)明軟件設(shè)計(jì)分為三部分,即對(duì)mfrc500的應(yīng)用程序的設(shè)計(jì)、對(duì)讀卡器其他電路的應(yīng)用程序設(shè)計(jì)和主程序設(shè)計(jì)。對(duì)mfrc500的應(yīng)用程序的設(shè)計(jì)既是對(duì)mfcm200操作指令的程序設(shè)計(jì);對(duì)讀卡器的其他電路的應(yīng)用程序的設(shè)計(jì)包括led狀態(tài)顯示程序設(shè)計(jì)、蜂鳴器程序設(shè)計(jì)和rs232通信程序設(shè)計(jì)。
本發(fā)明讀卡器對(duì)mifare卡片的操作流程如圖4所示,復(fù)位應(yīng)答操作將通知mfrc500在天線的有效工作范圍(距離)內(nèi)尋找mifare卡片。如果有mifare卡片存在,這一操作將分別與每一張mifare卡片進(jìn)行通信,讀取mifare卡片上的卡片類型號(hào)tagtype(兩個(gè)字節(jié)),由mfrc500傳遞給mcu,進(jìn)行識(shí)別處理。如果有多余一張的mifare卡片在讀卡器天線的有效工作范圍(距離)內(nèi),必須執(zhí)行防重疊操作,返回一張卡片的序列號(hào),作為本次操作的對(duì)象。而其它卡片處于等待狀態(tài)。在成功執(zhí)行防重疊操作之后,或在任何時(shí)候當(dāng)程序員想實(shí)際地與己知序列號(hào)的卡片進(jìn)行通信時(shí),必須執(zhí)行選擇卡片操作,以建立與所選卡片的通信,同時(shí)返回該卡片的size(容量)字節(jié)。為了保證對(duì)卡片操作的合法性,在對(duì)卡片進(jìn)行操作之前必須在卡片和讀卡器之間進(jìn)行認(rèn)證操作。讀卡器對(duì)任何一張mifare卡片進(jìn)行任何操作都要經(jīng)過上述幾個(gè)步驟,之后就可以具體地對(duì)卡片進(jìn)行相應(yīng)的讀、寫等操作。
本發(fā)明讀卡器主程序框圖如圖5所示。
要讓蜂鳴器發(fā)出聲音,必須要讓晶體管不斷on/off交互變化,即p2.3不斷的輸出“1”電位和“0”電位,如果p2.3輸出一直是“1”電位或一直是“0電位,則蜂鳴器將無(wú)法發(fā)出聲音。程序設(shè)計(jì)除了要讓蜂鳴器能夠發(fā)出聲音之外還要讓蜂鳴器能夠連續(xù)發(fā)出不同音長(zhǎng)及音調(diào)的聲音,使蜂鳴器能夠基于不同功能發(fā)出不同的報(bào)警信號(hào)。蜂鳴器驅(qū)動(dòng)子程序如下:
初始化寄存器程序:
registerwrite(regclockqcontrol,0x0);//設(shè)置時(shí)鐘控制初始值
register_write(regclockqcontrol,ox40);
registerwrite(regtxcontrol,0x58);//設(shè)置發(fā)送控制初始值
register_write(regrxcontroll,0x73);
registerwrite(regdeeodercontrol,ox08);//設(shè)置譯碼控制初始值
register_write(regbitphase,0xad);//初始化位相
register_write(regrxtl'treshold,0xff);//初始化最小閥值
registerwrite@egrxcontrol2,oxod;//根據(jù)運(yùn)行環(huán)境的處理速率可調(diào)整該值
register_write(reifolevel,oxos);//初始化fifo緩存
register_write(regtimerclock,ox07);//定時(shí)器初始值裝載
register_write(regtimerreload,0xoa);
詢問程序:
unsignedcharmf500picccommonrequest(intreq_code,int+atq)
{
regwrite(reginterrupten.0xtv);//禁止所有中斷
regwritefreginterruptrq.0x7f);//使能request中斷
regwrite(regcommand.pcd_idle);//中止可能正在運(yùn)行的其它程序
regwrite(regcontrol,regread(regcontr01)iox01);//清空fifo
regwrite(regfifodata,req_eode);//寫入request命令代碼
regwrite(regcommand.pcd"iransceive);//命令開始執(zhí)行
regwrite(reginterrupten,0x7f);//禁止所有中斷
regwrite(reginterruptrq.0x7f);//使能request中斷
mrc500_cnt---ox00;
while((!(regread(regprimarystatus)&0x08))&&(mrc500_cnt<50))
{mrc500_cm+=l;}//等待命令執(zhí)行完或超時(shí)退出
if(mrc500_ent>40)//mrc500timeout(about18ms)
{
regwrite(regcommand,oxoo);//中止程序
status=mi_accesstimeout
returnstatus;
}
status=regread(regerrorflag)&0x07;//讀取錯(cuò)誤標(biāo)志
if(status)
{
if(status&0x01)
status=mi._collerr;//判斷為沖突檢測(cè)錯(cuò)誤
if(status&0x02)
status=miparityerr;//判斷為校驗(yàn)錯(cuò)誤
if(status&ox04)
status=mlfram玳gerr;//判斷為幀錯(cuò)誤
}
else
{
if(tegread(regfifolength)==0x02)//判斷接收到的數(shù)據(jù)長(zhǎng)度
{
stams=mi_ok:
atq[o]=regread(regfifodata);//讀取atq
atq[11=regread(regfifodata);
}
else
status=mi_bitcounterr;
{
regwritefregcommand,pcd_idle);//程序終止
returnstatus;
}
unsignedcharm500picccascanticoll(unsigncdcharbent,unsignedchar+snr)
{
unsignedcharcomplete=0:
unsignedcharstatus=mlok;
complete=0:
while((complete==0)&&(status==mi_ok))
{
nbytesreceived=0;
/*p禁止rxcrc和txcrc,校驗(yàn)使能*/
regwrite(regchannelredundancy,ox03);
nbits=bent%8;//位個(gè)數(shù)
if(nbits)
{
regwrite(regbitframing,nbits<《4inbits);
nbytes=bent/8+1;//字節(jié)個(gè)數(shù)
}
elsenbytes=bent:
for(i=0;i<nbytes;i++)
snrin[i]=coll_data[i];
nvb=0x20+((bent/8)<<4|nbits;//要發(fā)送的字節(jié)數(shù)
regwrite(reginterrupten,0x70;//禁止所有中斷
regwrite(reginterruptrq,ox7f);//復(fù)位request中斷
regwrite(regcommand,pcd_idle);//中止可能正在運(yùn)行的程序
regwrite(regcontrol,regread(regcontr01)10x01);//清空fifo
regwrite(regfifodata,0x93);//寫入”sel”命令代碼
regwrite(regfifodata,nvb);//寫入”nvb”命令代碼
for(i=0;i<nbytes;i++)//發(fā)送snr
regwrite(regflfodata,snr_in[i]);
regwrite(reginterrupten.0x84);//timerirq和idlelrq使能
regwrite(regcommand,pcd_transceive);//命令開始執(zhí)行
mrc500_cnt=ox00;
while((t(regread(regpfimarystatus)&0x08))&&(mrc500_cnt<200))
{mrc500_cnt+=l;)//超時(shí)或命令結(jié)束判斷
if(mrc500cnt>15)//超時(shí)判斷
{
regwrite(regcommand,pcdidie);//中止程序
status=mi_accfstimeout;
returnstatus;
}
status=regread(regerrorflag)&ox07;//讀取錯(cuò)誤標(biāo)志
nbytesreceived=regread(regfifolength);//讀取數(shù)據(jù)長(zhǎng)度
for(i=0;i<nbytesreceived;i++)
if(rcgread(regfifolength)>=ox04);//判斷接收的數(shù)據(jù)長(zhǎng)度是否正確
{
for(status--o;status<4;status++)
siii'_]’n[status]=regread(regfifodata);
status=mlok;
}
……}
if(status==mi—ok)
{
memcpy(snr,snr_in,4);//保存slit
}
else
memcpy(snr,0000,4);
/*沖突禁止后置0*/
regwrite(regdecodercontrol,regread(regdecodercontr01)&(0x20));
regwrite(regcommand,pcd_idie);//中止程序
return
status;
}
選擇卡片程序:
unsignedcharmf500picccaseseleet(intsnri])
{
regwrite(reginterrupten,0x7f);//禁止所有中斷
regwrite(reginterruptrq,0x7f);//復(fù)位request中斷
regwrite(regcommand,pcdrole);//中止可能正在運(yùn)行的其它程序
regwrite(regcontrol,regread(regcontr01)10x01);//清空fifo
regwrite(regfifodata,ox93);//寫入”sel”命令代碼
regwrite(regfifodata,oxto);//寫入”nvb”命令代碼
for(status=o;status<4;status++)
regwrite(regfifodata,snr[status]);//寫sill"到fifo
status=snr[0]“snr[1]“snr[2]“snr[3];//計(jì)算bcc
regwrite(regfifodata,status);//將bcc寫入fifo
regwrite(reginterrupten,0xa4);//使能timerlrq和idlelrq
regwrite(regcommand,pcd_transceive);//命令開始執(zhí)行
mrc500_cnt=0x00;
while((!(regread(regpfimarystatus)&ox08))&&(mrc500_cnt<110))
{mrc500_cnt+=1;}//超時(shí)或命令結(jié)束判斷
if(mrc500_cnt>100)//超時(shí)判斷
{
regwrite(regcommand,pcd_idle);//中止程序
status=miaccesstimeout.//置超時(shí)標(biāo)志
returnstatus;
}
status=regread(regerrorflag)&ox07;//讀取錯(cuò)誤標(biāo)志
if(status)
{
if(status&ox01)
status=mi_collerr;//1判斷為沖突檢測(cè)錯(cuò)誤
elseif(status&0x02)
status=mi_parityerr;//判斷為校驗(yàn)錯(cuò)誤
elseif(status&ox04)
status=mi_framingerr;//判斷為幀錯(cuò)誤
}
else
{
if(regread(regfifolength)==0x01)//判斷接收數(shù)據(jù)長(zhǎng)度是否正確
{
if(regread(regfifodata)&ox04)
status=mi_sakerr;//判斷為sak錯(cuò)誤
elsestatus=mi-ok;
}
else
status=mi_bitcounterr;//數(shù)據(jù)長(zhǎng)度不符合則為計(jì)數(shù)錯(cuò)誤
}
regwrite(regcommand,pcd_idle);//程序終止
returns
tatus;
}
認(rèn)證程序:
unsignedcharm500piceloadkey(unsignedcharkey[])
{
regwrite(reginterrupten.0x7f);//禁止所有中斷
regwrite(reginterruptrq,0x7f);//復(fù)位request中斷
regwrite(regcommand.pcd_idle);//中止可能正在運(yùn)行的其它
regwrite(regcontrol,regread(regcontr01)lox01);//清空fifo
for(status=0;status<12;status++)
regwrite(regfifodata.key[status]);//寫入key到fifo
regwrite(reginterrupten,0x84);//使能idlelrq中斷
regwrite(regcommand.pcd_ldadkey);//寫入loadkey命令
do
{
status=(regread(regerrorflag)&ox40);
}
while((!(regread(regpfimarystatus)&0x08)));//等待命令執(zhí)行完畢
if(status)
status=ml_wrong_load_mode;//判斷錯(cuò)誤類型
else
status=mi_ok;
regwrite(regcommand,pcd_idle);//程序終止
returns
tatus;
piccread()函數(shù)主要代碼:
unsignedcharpiccread(unsignedcharblock_add,unsignedcharvalue[])
{
regwrite(reginterrupten,01710;//禁止所有中斷
regwrite(reginterruptrq,0x7v3;//復(fù)位request中斷
regwrite(regcommand,pcd_idle);//中止可能『f在運(yùn)行的其它程序
regwrite(regcontrol,regread(regcontrol|0x01);//清空fifo
regwrite(regfifodata,picc_read);//寫入read命令
regwrite(regfifodata,block_add);//寫入block_add參數(shù)
regwritecreginterrupten,0x84);//使能idlelrq中斷
regwrite(regcommand,pcd_transceive);//寫入命令代碼
mrc500_cnt=0;
while((!(regread(regprimarystatus)&0x08))&&(mrc500_cnt<300))
{mrc500_cnt+=l;}//超時(shí)或命令結(jié)束判斷
if(mrc500cnt>200)
{
regwrite(regcommand,pcd_idle);//超時(shí)判斷
status=miaccesstimeout;
retum
status;
}
status=regread(regerrorflag)&010e;//讀取錯(cuò)誤標(biāo)志
if(status)
{
if(status&0x02)
status=miparityerr;elseif(status&0x04),//判斷為校驗(yàn)錯(cuò)誤
statusz
mi_framingerr;//判斷為幀錯(cuò)誤
elseif(status&0,08)
status=mi_crcerr;//判斷為crc錯(cuò)誤
}
else
{
if(rcgread(regfifolength)==16)//判斷所接收到的數(shù)據(jù)長(zhǎng)度是否正確
{
for(status=0;status<16;status++)
value[status]=regread(regfifodata);//讀取一個(gè)block中的16個(gè)字節(jié)
status=ml-ok;
)
else
status=mi_bitcounterr;//數(shù)據(jù)長(zhǎng)度不符合則為計(jì)數(shù)錯(cuò)誤
}
regwrite(regcommand,pcd_idle);//程序終止
returnstatus;
}
蜂鳴器驅(qū)動(dòng)子程序:
參數(shù)說明:
count:發(fā)出聲音的個(gè)數(shù)
sounglong:音長(zhǎng),聲音的長(zhǎng)短
tone:音調(diào),聲音的高低,以khz為單位
voidbeep(unsignedcharcount,unsignedcharsoundlong,unsignedchartone)
{
ucharidatai,j,k,spfreg;
spfreg=(1000/tone)/2;//方波的半周期轉(zhuǎn)換方式,以khz為單位
for(i=0;i<count;i++)//發(fā)出聲音個(gè)數(shù)循環(huán)
{
for(j=0;j<soundlong;j++)//音長(zhǎng)循環(huán)
{
for(k=0;k<spfreg;k++)
p2_2=0;
for(k=0;k<spfreg;k++)
p2_2=1;
}
delay_50us(2000);//每發(fā)出一個(gè)聲音延遲100ms
}
}
以上所述僅為本發(fā)明的較佳實(shí)施例而已,并不用以限制本發(fā)明,凡在本發(fā)明的精神和原則之內(nèi)所作的任何修改、等同替換和改進(jìn)等,均應(yīng)包含在本發(fā)明的保護(hù)范圍之內(nèi)。