《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 通信與網(wǎng)絡(luò) > 設(shè)計(jì)應(yīng)用 > 基于C#的射頻卡讀寫(xiě)原理及實(shí)現(xiàn)
基于C#的射頻卡讀寫(xiě)原理及實(shí)現(xiàn)
來(lái)源:微型機(jī)與應(yīng)用2010年第14期
張可可1, 熊慶宇2
(重慶大學(xué)自動(dòng)化學(xué)院,, 重慶400044)
摘要: 介紹了射頻卡的硬件結(jié)構(gòu)和工作原理,,給出了一套對(duì)射頻卡進(jìn)行數(shù)據(jù)采集和實(shí)時(shí)處理的軟件設(shè)計(jì)方案,并采用C#語(yǔ)言編寫(xiě)了關(guān)鍵的程序代碼,。
Abstract:
Key words :

摘  要: 介紹了射頻卡的硬件結(jié)構(gòu)和工作原理,,給出了一套對(duì)射頻卡進(jìn)行數(shù)據(jù)采集和實(shí)時(shí)處理的軟件設(shè)計(jì)方案,并采用C#語(yǔ)言編寫(xiě)了關(guān)鍵的程序代碼,。
關(guān)鍵詞: 射頻卡,; 讀卡器定時(shí)器; 動(dòng)態(tài)鏈接庫(kù)

    射頻卡又稱非接觸式IC卡,,它將RFID和IC技術(shù)完美結(jié)合,,使卡片能夠在不需要電源及與讀卡器不接觸的情況下正常工作。目前射頻卡已經(jīng)廣泛使用在社會(huì)生活的各個(gè)領(lǐng)域,如銀行卡,、企業(yè)一卡通系統(tǒng)等,。由于射頻卡具有使用人群的密集性以及使用時(shí)間不確定性的特點(diǎn),就要求讀卡器能夠?qū)ι漕l卡進(jìn)行實(shí)時(shí)準(zhǔn)確的數(shù)據(jù)采集并通過(guò)數(shù)據(jù)線把采集到的數(shù)據(jù)傳送給計(jì)算機(jī),通過(guò)特定的處理軟件進(jìn)行快速處理,并將處理結(jié)果反饋回射頻卡,從而實(shí)現(xiàn)計(jì)算機(jī)與射頻卡信息的雙向交互,滿足人們特定的要求。本文通過(guò)定時(shí)器技術(shù)實(shí)現(xiàn)對(duì)射頻卡信息的實(shí)時(shí)采集和交互處理,利用定時(shí)器的定時(shí)觸發(fā)功能實(shí)現(xiàn)對(duì)射頻卡讀寫(xiě)函數(shù)的全天候循環(huán)調(diào)用,減輕系統(tǒng)的負(fù)載,、優(yōu)化系統(tǒng)的進(jìn)程,、提高系統(tǒng)的穩(wěn)定性,從而保持計(jì)算機(jī)和射頻卡協(xié)同高效地工作。
1 射頻卡硬件結(jié)構(gòu)與工作原理
 本課題中射頻卡采用業(yè)界廣泛使用的由荷蘭飛利浦公司生產(chǎn)的M1卡,M1卡主要有射頻天線和ASIC兩部分組成,,如圖1[1],。射頻天線是由特制的磁感線圈繞制而成,用來(lái)接收讀卡器發(fā)出的固定頻率的電磁波,。ASIC主要由高速射頻RF接口,、數(shù)據(jù)讀寫(xiě)控制單元、存儲(chǔ)工具EEPROM構(gòu)成,。當(dāng)讀卡器對(duì)射頻卡進(jìn)行讀寫(xiě)操作時(shí),,讀卡器會(huì)持續(xù)發(fā)出一組頻率固定的電磁波,電磁波的頻率與M1卡內(nèi)置的LC諧振模塊的諧振頻率相同,,從而造成LC諧振模塊發(fā)生共振,,使諧振電路的電容內(nèi)產(chǎn)生電荷,這個(gè)電容通過(guò)特殊的傳輸裝置單向傳輸?shù)搅硗庖粋€(gè)電容聚集起來(lái),。當(dāng)積累的電荷電壓達(dá)到2 V時(shí),,此電荷實(shí)際上可以作為一個(gè)電源向卡內(nèi)的各種電路裝置供電,從而實(shí)現(xiàn)讀卡器對(duì)射頻卡的讀寫(xiě)操作,。

 高速射頻RF接口的主要功能是用來(lái)接收通過(guò)LC諧振電路產(chǎn)生的電源電壓以及諧振電路本身的復(fù)位信號(hào)和時(shí)鐘信號(hào),。數(shù)據(jù)讀寫(xiě)控制單元的主要功能是對(duì)射頻接口傳遞的數(shù)據(jù)進(jìn)行調(diào)制和解密并對(duì)數(shù)據(jù)按照特定的步驟與讀卡器進(jìn)行數(shù)據(jù)的交互處理。讀卡器與計(jì)算機(jī)連接的串口初始化成功后,,就開(kāi)始在讀卡器射頻感應(yīng)的工作范圍內(nèi)尋找射頻卡[2],。如果同時(shí)感應(yīng)到多張射頻卡,讀卡器會(huì)啟動(dòng)反沖突機(jī)制控制模塊選定其中的一張,。選定要處理的卡之后,,讀寫(xiě)器就確定要訪問(wèn)的扇區(qū)號(hào),并對(duì)該扇區(qū)密碼進(jìn)行密碼校驗(yàn),,在3次相互認(rèn)證之后就可以通過(guò)加密流進(jìn)行通訊,,對(duì)讀卡器進(jìn)行讀寫(xiě)操作,操作成功后啟動(dòng)報(bào)警控制模塊,,提示操作成功,,同時(shí)掛起該張卡,。EEPROM是射頻卡的存儲(chǔ)單元,用來(lái)保存讀卡器寫(xiě)入的信息,。M1射頻卡存儲(chǔ)空間是8 KB,。存儲(chǔ)空間分為16個(gè)扇區(qū),每個(gè)扇區(qū)又分為4個(gè)塊,,每個(gè)塊內(nèi)存大小為16 B,。64個(gè)塊按物理排序命名,序號(hào)從0塊一直到63塊,。其中0塊保存的是射頻卡的序列號(hào),,出廠時(shí)由廠家直接寫(xiě)入,不能更改,。另外,,每個(gè)扇區(qū)的第4塊是該扇區(qū)的密碼存儲(chǔ)塊,其中包括兩套密碼以及密碼讀取控制字節(jié),。其余3塊是數(shù)據(jù)塊,,可以存儲(chǔ)數(shù)據(jù)并進(jìn)行相應(yīng)數(shù)據(jù)操作[3],如圖2所示,。

2 軟件設(shè)計(jì)流程與程序?qū)崿F(xiàn)
 基于射頻卡使用環(huán)境及對(duì)數(shù)據(jù)處理實(shí)時(shí)性的特殊要求,,必然要求讀卡器處于一種不間斷的監(jiān)測(cè)狀態(tài),能夠?qū)M(jìn)入讀卡器感應(yīng)區(qū)域的射頻卡進(jìn)行快速穩(wěn)定的數(shù)據(jù)采集,,并把這種處理結(jié)果實(shí)時(shí)傳輸給相連的計(jì)算機(jī),,通過(guò)專門(mén)的軟件進(jìn)行信息的交互處理[4]??紤]到這些要求,,在軟件的設(shè)計(jì)過(guò)程中使用C#中的timer控件來(lái)滿足這種要求,利用Timer控件的定時(shí)激發(fā)功能,,使讀卡器能夠不間斷地檢測(cè)是否有卡進(jìn)入感應(yīng)區(qū)域,。首先初始化串口,保證讀卡器和計(jì)算機(jī)的正常連接,,如果讀卡器沒(méi)有檢測(cè)到有射頻卡處于工作區(qū),,就一直保持檢測(cè)狀態(tài)。如果讀卡器檢測(cè)到工作范圍內(nèi)有卡,,就按照正常讀寫(xiě)操作流程(如圖3)對(duì)射頻卡進(jìn)行操作,,一張卡操作完成后,讀卡器會(huì)自動(dòng)報(bào)警提示操作成功并掛起這張卡,。在這種情況下,除非把這張卡移除工作區(qū),,否則讀卡器將無(wú)法繼續(xù)正常工作,。

 在分析了射頻卡的工作原理和軟件流程后,,本文用C#語(yǔ)言來(lái)編寫(xiě)具體的程序代碼,C#是微軟公司發(fā)布的一種面向?qū)ο蟮?、運(yùn)行于.NET Framework之上的高級(jí)程序設(shè)計(jì)語(yǔ)言[5],。為了便于產(chǎn)品的開(kāi)發(fā),廠家已經(jīng)附帶給出了開(kāi)發(fā)射頻卡程序所需要的動(dòng)態(tài)連接庫(kù),。C#語(yǔ)言可以直接調(diào)用給動(dòng)態(tài)連接庫(kù),,只需要在程序中加以引用說(shuō)明即可。本課題采用的讀卡器為雙面D8讀卡器,,附帶的動(dòng)態(tài)鏈接庫(kù)文件為dcrf32.dll,。此文件中包含了常用的射頻卡讀寫(xiě)操作等系列函數(shù)。實(shí)現(xiàn)對(duì)射頻卡寫(xiě)數(shù)據(jù)操作的部分關(guān)鍵代碼如下:
   …
   [DllImport("dcrf32.dll")]
   public static extern int dc_init(short port, int baud);  
   [DllImport("dcrf32.dll")]
   public static extern short dc_request(int icdev, char _Mode, ref uint TagType);
   [DllImport("dcrf32.dll")]
   public static extern short dc_select(int icdev, uint _SecNr, byte[] _Size);
   [DllImport("dcrf32.dll")]
   public static extern short dc_authentication(int icdev, int _Mode, int _SecNr); 
   [DllImport("dcrf32.dll")]
   public static extern int dc_beep(int icdev, short _Msec); 

   [DllImport("dcrf32.dll")]
   public static extern int dc_pro_halt(int icdev);
   [DllImport("dcrf32.dll")]
   public static extern short dc_exit(int icdev);
   private void  Card_Read();
   {
         _icdev=dc_init(Form3.Com, Form3.botelv);
                                        //串口初始化
        if (_icdev <= 0)
        {MessageBox.Show(“串口初始化失敗!");
                 return;
        }
                 byte[] name = System.Text.Encoding.Default.GetBytes
                 (txtN.Text);
                 byte[] sex = System.Text.Encoding.Default.GetBytes
                 (txtS.Text);
        if (name.Length > 16)
        {
                   MessageBox.Show("超過(guò)規(guī)定的數(shù)據(jù)長(zhǎng)度,寫(xiě)入失敗");
                   txtN.Text = null;
                   return;
        }
        if (sex.Length > 16)  //數(shù)據(jù)長(zhǎng)度檢測(cè)
        {
                   MessageBox.Show("超過(guò)規(guī)定的數(shù)據(jù)長(zhǎng)度,寫(xiě)入失敗");
                   txtS.Text = null;
                   return;
            }
            int st;
            ulong icCardNo = 0;
            char tt = (char)0;
            st = dc_card(IcDev, tt, ref icCardNo); //尋卡操作
            if (st != 0)
            {   txtCardId.Text = "";
                    txtN.Text = "";
                    txtS.Text = "";
                    MessageBox.Show("尋卡失??!");
                    return;
             }
           int sector = 0;
             st = dc_authentication(IcDev, 0, sector); //密碼驗(yàn)證
                if (st != 0)
                {
                    MessageBox.Show("驗(yàn)證密碼失敗,!");
                    return;
                }
            try
            {
                    string dt = txtS.Text;
                    st = dc_write(IcDev, 2, dt);    //射頻卡寫(xiě)操作
                    dc_beep(IcDev, 10);                     //蜂鳴操作
                    st=dc_halt(IcDev) ;                       //掛起操作
                    MessageBox.Show("修改成功");
    }
            catch
             {
        MessageBox.Show("更改卡中信息失敗");
             }
             dc_exit(IcDev); //關(guān)閉串口
    }
    private void timer1_Tick(object sender, EventArgs e)
                                        //定時(shí)器操作
          {
           timer1.Interval = 1000;     
           timer1.Start();
           Card_Read();
    }
    實(shí)際應(yīng)用結(jié)果表明,,采用C#語(yǔ)言結(jié)合定時(shí)器的特有功能編寫(xiě)的射頻卡讀寫(xiě)控制程序運(yùn)行穩(wěn)定,能夠很好地滿足工作現(xiàn)場(chǎng)的需要,。在讀卡器對(duì)射頻卡進(jìn)行讀寫(xiě)操作的同時(shí),,并不影響軟件系統(tǒng)其他模塊的操作,具有較強(qiáng)的實(shí)用意義,。
參考文獻(xiàn)
[1]  楊瑞,彩虹.射頻卡多線程讀寫(xiě)原理及其實(shí)現(xiàn)[J].計(jì)算機(jī)與信息技術(shù),,2006(2):1-3.
[2]  蘇明強(qiáng),劉偉.高性價(jià)比的MIFARE卡讀寫(xiě)模塊的設(shè)計(jì). [J].微計(jì)算機(jī)信息,,2006,22(5-2):1-2.

此內(nèi)容為AET網(wǎng)站原創(chuàng),,未經(jīng)授權(quán)禁止轉(zhuǎn)載。