色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

13.56MHz讀寫卡模塊通信接口及選型指南

UtFs_Zlgmcu7890 ? 來源:互聯網 ? 作者:佚名 ? 2018-01-25 09:09 ? 次閱讀

周立功教授新書《面向AMetal框架與接口編程(上)》,對AMetal框架進行了詳細介紹,通過閱讀這本書,你可以學到高度復用的軟件設計原則和面向接口編程的開發思想,聚焦自己的“核心域”,改變自己的編程思維,實現企業和個人的共同進步。

第六章為重用外設驅動代碼,本文內容為6.4 讀寫卡模塊。

6.4 讀寫卡模塊

>>> 6.4.1 基本功能

ZLG600A 是ZLG 提供的符合14443 標準的13.56MHz 讀寫卡模塊,支持Plus CPU、Mifare DesfireCPU 卡、Mifare 1 S50/S70、Mifare 0 ultralight、Mifare Pro 卡,還支持ISO7816 協議讀寫接觸式IC 卡。可以搭載兩個天線滿足不同位置的多卡讀寫要求,連接從機數多達127 個,支持I2CUARTRS-232C、RS-485 多種接口。具備主動檢測卡進入功能,當檢測到卡時,則產生中斷且通過串口、I2C 輸出數據。

ZLG600A 系列讀寫卡模塊選型指南詳見表6.18,電源電壓為5V,平均電流為77mA,TypeA、TypeB 和PLUS CPU卡讀卡距離分別為7.5cm、4cm 和5cm。

表6.18 選型指南表

由于RS-232C 和RS-485 與UART通信方式完全相同,僅在硬件上增加了一些轉換電路,因此后面不再特別說明。在這里僅介紹I2C 和UART 兩種通信方式,其引腳含義詳見表6.19。

表6.19 通信接口定義

注:方形焊盤為第1 管腳,3.3V 模塊J1-5 接3.3V 電源,5V 模塊J1-5 接5V 電源。

當使用UART 通信時,只需要連接J1 中的電源引腳和TXD、RXD 引腳,其它引腳懸空,將LPC824 的USART0、USART1 或USART2 與ZLG600A 相連。當使用I2C 通信時,需要連接J1 中的電源引腳和SCL、SDA 引腳。由于I2C 從機不能主動向I2C 主機發送數據,因此需要使用INT 引腳,用于從機通知主機處理事務。其它未使用的引腳通過10K 的上拉電阻與高電平相連,將LPC824 的I2C0、I2C1、I2C2 或I2C3 與ZLG600A 相連。注:SCL 和SDA 模塊內部都有上拉電阻,使用I2C 通信時無需再外接上拉電阻。

>>> 6.4.2 初始化

AMetal 已經提供了ZLG600A 的驅動函數,在使用其它各功能函數前必須先完成初始化,其初始化函數詳見表6.20。

表6.20 ZLG600A 初始化接口函數

初始化ZLG600A 意在獲取ZLG600A 的實例句柄(handle),雖然初始化函數不同,但返回值均為ZLG600A 的實例句柄,該實例句柄將作為其它功能接口函數handle 的實參。因此,無論選擇I2C 或UART 通信方式,只要基于實例句柄編程,則應用程序與具體的通信方式無關。即便底層通信方式改變了,僅需在獲取實例句柄時換一個初始化函數,而應用程序“一行代碼”都不用修改。

1. UART 初始化

使用UART 時,其初始化函數原型為:

  • p_dev 為指向am_zlg600_uart_dev_t 類型實例的指針;

  • p_devinfo 為指向am_zlg600_uart_devinfo_t 類型實例信息的指針。

(1)實例

定義am_zlg600_uart_dev_t 類型(am_zlg600.h)實例如下:

其中,g_zlg600_uart_dev 為用戶自定義的實例,其地址作為p_dev 的實參傳遞。

(2)實例信息

實例信息主要描述了ZLG600A 使用UART 通信時的相關信息,包括UART 緩沖區信息、波特率等信息。其類型am_zlg600_uart_devinfo_t 定義(am_zlg600.h)如下:

實例信息主要包含幀格式、ZLG600A 模式、波特率和緩沖區信息。

  • 幀格式

frame_fmt 表示初始化時ZLG600A 使用的幀格式,為了兼容早期產品,ZLG600A 支持新幀格式和舊幀格式,其對應的宏詳見表6.21。在初始化完成后,可以通過相應的接口函數修改ZLG600A 使用的幀格式。但在初始化時,要知道ZLG600A 當前使用的幀格式,出廠默認使用的幀格式為舊幀格式,frame_fmt 的值設置為:AM_ZLG600_FRAME_FMT_OLD。

表6.21 幀格式對應的宏(am_zlg600.h)

注:若本次初始化完成后,通過后續相關功能接口函數更換使用的幀格式(如將舊幀格式更換為新幀格式),那么在系統下次啟動調用ZLG600A 初始化函數時,需要確保frame_fmt成員的值為更新后的幀格式(如新幀格式)。

  • ZLG600A 模式

now_mode 為初始化時使用的模式,ZLG600A 支持3 種模式:自動偵測模式、I2C 模式、UART 模式。其對應的宏詳見表6.22,出廠默認為自動偵測模式。

表6.22 模式對應的宏(am_zlg600.h)

注:由于在自動偵測模式下,為了使用UART 通信,需要Host 連續發送兩次0x20(兩次的時間間隔需要30us 以上),便于ZLG600A 檢測有效波特率,將會使得每次初始化ZLG600A 的耗費時間較長。因此在本次初始化完成后,通過后續接口函數將模式固定為UART 模式。更新模式后,系統在下次啟動調用ZLG600A 初始化函數時,需確保now_mode 成員的值為更新后的模式(如UART 模式)。

在自動偵測模式下,UART、I2C 接口均處于接收狀態。若ZLG600A 從UART 通信線上檢測到有效的波特率(需要Host 連續發送兩次0x20,且兩次的時間間隔在30us 以上,便于ZLG600 檢測到有效波特率),則模塊使用UART 通信方式;若模塊從I2C 總線上接收到匹配的從機地址,則模塊使用I2C 通信方式。只要其中一個接口先收到有效數據,模塊將以此方式與主機通信,且關閉另外一種接口。

在UART 通信模式下,通信接口固定為UART,關閉I2C 接口,無需Host再連續發送兩次0x20 檢測ZLG600A 波特率。在I2C 通信模式下,關閉UART接口。在完成初始化后,可以通過相應的接口函數修改ZLG600A 使用的模式。但在初始化時,要知道ZLG600A 當前使用的模式,出廠默認使用的模式為自動偵測模式,now_mode 的值設置為:

AM_ZLG600_MODE_AUTO_CHECK。

  • 波特率

baudrate 為UART 波特率,支持波特率的宏定義詳見表6.23。在自動偵測模式下,可以選擇表中任一有效的波特率,ZLG600A 會自動檢測使用的波特率。若處于UART 模式,波特率將為固定的值,該值為配置ZLG600A 是UART 模式時使用的波特率。

表6.23 支持的UART 波特率對應的宏(am_zlg600.h)

由于出廠默認模式為自動偵測模式,因此該值為任一有效的波特率,如定義波特率為115200,則該值為:AM_ZLG600_BAUDRATE_115200。

  • 緩沖區信息

當選擇UART 方式通信時,發送和接收都需要一個保存數據的緩沖區,以提高數據處理的效率和確保接收數據不會因為正在處理事務而丟失。緩沖區的大小由用戶根據實際情況指定,建議在64 字節以上,一般設置為128 字節。p_uart_rxbuf 和rxbuf_size 描述了接收緩沖區的首地址和大小,p_uart_txbuf 和txbuf_size 描述了發送緩沖區的首地址和大小。如果設置128 字節的緩沖區供發送和接收使用,其定義如下:

其中,g_zlg600_uart_txbuf[128]為用戶自定義的數組空間供發送使用,充當發送緩沖區,其地址(數組名g_zlg600_uart_txbuf 或首元素地址& g_zlg600_uart_txbuf[0])作為實例信息中p_uart_txbuf 成員的值,數組大小(這里為128)作為實例信息中txbuf_size 成員的值。同理,g_zlg600_uart_rxbuf[128]充當接收緩沖區,其地址作為實例信息中p_uart_rxbuf 成員的值,數組大小作為實例信息中rxbuf_size 成員的值。基于此,實例信息定義如下:

(3)UART 句柄uart_handle

若選擇LPC824 的USART1 與ZLG600A 通信,則可以通過LPC82x 的USART1 實例初始化函數am_lpc82x_usart1_inst_init()獲得UART 句柄。即:

獲得的UART 句柄即可直接作為uart_handle 的實參傳遞。

(4)實例句柄

ZLG600A 初始化函數am_zlg600_uart_init()的返回值即為ZLG600A 實例的句柄,該句柄將作為其它功能接口的第一個參數(handle)的實參。

其類型am_zlg600_handle_t(am_zlg600.h)定義如下:

若返回值為NULL,說明初始化失敗;若返回值不為NULL,說明返回一個有效的handle。

基于模塊化編程思想,將初始化相關的實例、實例信息等的定義存放到對應的配置文件中,通過頭文件引出實例初始化函數接口,源文件和頭文件的程序范例分別詳見程序清單6.98 和程序清單6.99。

程序清單6.98 ZLG600A(串口通信)實例初始化函數實現(am_hwconf_zlg600.c)

程序清單6.99 ZLG600A(串口通信)實例初始化函數聲明(am_hwconf_zlg600.h)

后續只需要使用無參數的實例初始化函數,即可獲取ZLG600A 的實例句柄。即:

2. I2C 初始化

使用I2C 通信方式時,其初始化函數原型為:

  • p_dev 為指向am_zlg600_i2c_dev_t 類型實例的指針;

  • p_devinfo 為指向am_zlg600_i2c_devinfo_t 類型實例信息的指針。

(1)實例

定義am_zlg600_i2c_dev_t 類型(am_zlg600.h)實例如下:

其中,g_zlg600_i2c_dev 為用戶自定義的實例,其地址作為p_dev 的實參傳遞。

(2)實例信息

實例信息主要描述了ZLG600A 使用I2C 通信時的相關信息,包括I2C 緩沖區信息、波特率等信息。其類型am_zlg600_i2c_devinfo_t 的定義(am_zlg600.h)如下:

實例信息主要包含幀格式、ZLG600A 模式、7 位I2C 從機地址和中斷引腳信息。

frame_fmt 的含義與使用UART 通信方式時一致,對于出廠設置的模塊,frame_fmt 的值應設置為:AM_ZLG600_FRAME_FMT_OLD。

now_mode 的含義與使用UART 通信方式時一致,對于出廠設置的模塊,now_mode 的值應設置為:AM_ZLG600_MODE_AUTO_CHECK。在本次初始化完成后,若通過后續接口函數將模式固定為I2C 模式。則系統在下次啟動調用ZLG600A 初始化函數時,必須確保now_mode 成員的值為更新后的I2C 模式。

slv_addr 為ZLG600A 的7 位I2C 從機地址,出廠默認值為0x59,數據手冊中描述為0xB2,該值為8 位地址,右移一位,即移除表示讀寫方向的位后,值即為0x59。在本次初始化完成后,若通過后續接口函數修改I2C 地址。則系統在下次啟動調用ZLG600A 初始化函數時,必須確保slv_addr 成員的值為更新后的I2C 地址。

int_pin 為ZLG600A 的INT 引腳與實際微控制器(如LPC824)連接的引腳號。比如,選擇LPC824 的PIO0_13 與ZLG600A 的 INT 引腳相連,則該值應設置為PIO0_13。

基于此,實例信息定義如下:

(3)I2C 句柄i2c_handle

若選擇LPC824 的I2C1 與ZLG600A 通信,則通過LPC82x 的I2C1 實例初始化函數am_lpc82x_i2c1_inst_init()獲得I2C 句柄。即:

獲得的I2C 句柄即可直接作為i2c_handle 的實參傳遞。

(4)實例句柄

am_zlg600_i2c_init()與am_zlg600_uart_init()的返回值相同,該返回值為ZLG600A 實例的句柄,該句柄將作為其它功能接口的第一個參數(handle)的實參。若返回值為NULL,說明初始化失敗;若返回值不為NULL,說明返回一個有效的handle。

基于模塊化編程思想,將初始化相關的實例、實例信息等的定義存放到對應的配置文件中,通過頭文件引出實例初始化函數接口,源文件和頭文件的程序范例分別詳見程序清單6.100 和程序清單6.101。

程序清單6.100 新增ZLG600A 的I2C 通信方式的實例初始化函數(am_hwconf_zlg600.c)

程序清單6.101 am_hwconf_zlg600.h 文件內容更新

后續只需要使用無參數的實例初始化函數,即可獲取到ZLG600A 的實例句柄。即:

>>> 6.4.3 設備控制類接口函數

ZLG600A 支持多種IC 卡,比如,Mifare S50/S70、ISO7816-3、ISO14443(PICC)、PLUSCPU 卡等,每種卡都有對應的命令。命令與接口函數基本上是一一對應的關系,ZLG600A的命令較多,分為以下5 類:設備控制類命令、Mifare S50/S70 卡類命令、ISO7816-3 類命令、ISO14443(PICC)卡類命令和PLUS CPU 卡類命令。

設備控制類接口函數與具體卡片沒有直接關系,主要用于直接操作ZLG600A,比如,獲取ZLG600A 的設備信息和存儲IC 卡密鑰等,詳見表6.24。

表6.24 ZLG600A 設備控制類接口函數(am_zlg600.h)

1. 讀取設備信息

該函數意在獲取ZLG600A 的基本信息,包括產品信息和版本信息等,獲取的信息為字符串,比如,“ZLG600A V1.00”。其函數原型為:

其中,p_info 為獲取信息的指針,由于字符串長度為20 字節,因此需要提供一個長度為20 字節的內存空間,以便存放獲取到的信息。若返回值為AM_OK,說明獲取信息成功,反之失敗,范例程序詳見程序清單6.102。

程序清單6.102 讀取ZLG600A 設備信息范例程序

假定選擇UART 通信方式,即可使用am_zlg600_uart_inst_init()實例初始化函數獲取ZLG600A 的實例句柄。同時包含標準C 頭文件string.h,便于使用strcmp()函數判斷字符串是否為“ZLG600A V1.00”?

由于這次使用的是ZLG600A V1.00 模塊,因此獲取的信息一定為“ZLG600A V1.00”。如果你使用的是其它型號或版本的模塊,則要注意將比較信息的字符串修改,否則就算成功讀取信息,比較結果也是不相等的。

2. 裝載IC 卡密鑰

卡片內存儲的數據均是加密的,必須驗證成功后才能讀寫數據。驗證就是將用戶提供的密鑰與卡片內部存儲的密鑰對比,只有相同才認為驗證成功。ZLG600A 提供了用于存儲卡片驗證的密鑰的E2PROM,裝載IC 卡密鑰的作用就是將密鑰存放到指定的E2PROM 存儲區,其函數原型為:

其中,key_type 為密鑰類型,密鑰一般分為2 類,其分別為TypeA 和TypeB。其對應的宏詳見表6.25。ZLG600A 能保存A 類型密鑰16組,B 類型密鑰16 組。

表6.25 密鑰類型(am_zlg600.h)

注:之所以存在兩類密鑰,是由于實際卡片中往往存在兩類密鑰,兩類密鑰可以更加方便地進行權限管理,比如,TypeA 驗證成功后只能讀,而TypeB 只有驗證成功后才能寫入,但權限可以自定義設置。

key_sec 為保存的區號,由于ZLG600A 能保存A 類密鑰16 組和B 類密鑰16 組,因此每種類型保存的區域有16 個,其對應區號為0 ~ 15。

p_key 指向了實際待保存密鑰的緩沖區,key_length 為密鑰的長度,密鑰最大長度為16 字節。保存一組6 字節長度的A 類型密鑰至區號0 的范例程序詳見程序清單6.103。

程序清單6.103 裝載密鑰范例程序

當后續需要驗證卡片時,只需要指定密鑰存放的E2PROM 區號0,無需再將密鑰發送給ZLG600A。

>>> 6.4.4 操作接口函數

Mifare 卡是一種符合ISO14443 標準的A 型卡,其接口函數詳見表6.26。

表6.26 Mifare S50/S70 接口函數(am_zlg600.h)

經常使用的公交卡、房卡、水卡和飯卡等均是Mifare 卡。比如,S50 和S70,它們的區別在于容量的不同。S50 為1Kbyte,共16 個扇區,每個扇區4 塊,每塊16 字節。S70 為4Kbyte,共40 個扇區,前32 個扇區每個扇區4 塊,每塊16 字節,后8 個扇區每個扇區16 塊,每塊16 字節。

1. 自動檢測

  • 設置自動檢測回調函數

當有卡片靠近ZLG600A 時,將會自動調用用戶設定的回調函數,讀取卡片的相關信息,因此需要先設置一個回調函數。其函數原型為:

其中,pfn_callback 為指向回調函數的指針,p_arg 為回調函數的參數。若返回AM_OK,表示設置成功,反之失敗,范例程序詳見程序清單6.104。

程序清單6.104 設置自動檢測回調函數范例程序

程序中定義了一個detect_flag 變量,表示是否檢測到卡片。如果初始值為0,說明未檢測到卡片。在設置自動檢測回調函數時,將其地址作為回調函數的p_arg 參數。因此在回調函數中,p_arg 實質上是指向detect_flag 的指針,通過該指針將detect_flag 設置為1,表明當前檢測到卡片。

  • 啟動自動檢測

當設置好回調函數后,即可啟動自動檢測。其函數原型為:

其中,p_info 為指向自動檢測相關信息的指針,其類型am_zlg600_auto_detect_info_t 定義如下:

該信息結構體包含檢測模式、天線模式、請求模式和密鑰驗證相關的信息。

  • 檢測模式

ad_mode 表示檢測模式,用于配置檢測相關動作。當檢測到卡片時,是否掛起該卡片,若選擇掛起,設置ad_mode 的值為AM_ZLG600_MIFARE_CARD_AD_HALT(am_zlg600.h),則在檢測到一次該卡片后,就將該卡片掛起,后續檢測將忽略該卡片。若需再次檢測該卡片,必須將卡片遠離ZLG600A 后重新靠近才有效。若設置ad_mode 的值為0,則不會掛起卡片,每次自動檢測均可以檢測到靠近的卡片。

舉個簡單的例子可能更容易理解,在平常刷公交卡時,當卡片靠近刷卡器時,會扣費一次,刷卡成功。若公交卡不離開刷卡器,則不會再次扣費,此時卡片已經被刷卡器掛起了,不會再被識別到。若將公交卡離開刷卡器后再次靠近,將可能再次扣費。

當ad_mode 的值均設置為AM_ZLG600_MIFARE_CARD_AD_HALT 時,則可以避免重復檢測到同一張卡片。

  • 天線模式

tx_mode 設置天線的工作模式,ZLG600A 有2 個天線TX1 和TX2,4 種工作模式:僅使用TX1、僅使用TX2、TX1 和TX2 交替使用、TX1 和TX2 同時使用,各種模式對應的tx_mode 的值宏定義詳見表6.27。

表6.27 天線工作模式(am_zlg600.h)

  • 請求模式

req_mode 表示請求模式,即檢測所有的卡還是只檢測空閑卡,對應的值宏定義詳見表6.28,一般來講只檢測空閑卡。

表6.28 請求模式(am_zlg600.h)

  • 密鑰驗證

由于絕大部分卡片在檢測到卡片時,都要先讀取一塊數據,因此可以將讀取數據作為自動檢測的一個附加功能。即在檢測到卡片時,自動讀取1 塊(16 字節)數據。由于讀取數據前均需要驗證,這就需要在啟動自動檢測時,指定密鑰驗證相關的信息。

所謂密鑰驗證就是將用戶提供的密鑰與卡片內部存儲的密鑰對比,只有相等方能驗證成功。auth_mode 指定了3 種驗證模式,其對應的宏表6.29。

表6.29 驗證模式(am_zlg600.h)

如果在自動檢測到卡片時,不需要讀取數據,則應該將auth_mode 的值設置為AM_ZLG600_MIFARE_CARD_AUTH_NO。由于不會用到信息結構體中key_type、key[16]、key_len、nblock 四個成員的值,因此無需設置。

如果需要讀取數據,則必須將auth_mode 置為AM_ZLG600_MIFARE_CARD_AUTH_E2或AM_ZLG600_MIFARE_CARD_AUTH_DIRECT,其主要區別是驗證密鑰存放位置不同。

如果使用“直接驗證”(AM_ZLG600_MIFARE_CARD_AUTH_DIRECT)的方式,則信息結構體的key[16]包含了實際的密鑰,key_len 表示了密鑰的長度。

如果使用“E2 驗證”(AM_ZLG600_MIFARE_CARD_AUTH_E2)方式,則驗證密鑰存放在ZLG600A 的E2PROM 中。此時,信息結構體的key[16] 僅使用了首元素key[0],其值為密鑰在E2PROM 中的區號(0 ~ 15)。自動檢測時,將使用ZLG600A 中E2PROM 對應區號中的密鑰進行驗證。key_len 表示密鑰的長度。顯然,若使用“E2 驗證”,則需要確保已經使用am_zlg600_ic_key_load()將密鑰存放到了ZLG600A 中E2PROM 相應的區域。

信息結構體中的nblock 指定了要驗證的塊,即讀取數據的塊,只有該塊被驗證成功后,才能讀取數據。Mifare S50 和Mifare S70 卡片包含的塊數目詳見表6.30。

表6.30 常見卡片的塊數目(am_zlg600.h)

假定無需讀取數據,可以定義自動檢測信息如下:

定義好相關信息后,可以使用啟動函數啟動自動檢測,即:

  • 讀取卡片信息

當啟動自動檢測后,若前面注冊的回調函數被調用,表明檢測到卡片,此時可以使用該接口讀取卡片的信息。其函數原型為:

其中,p_card_info 為指向卡片信息的指針,用于獲取卡片信息。卡片信息的類型am_zlg600_mifare_card_info_t(am_zlg600.h)定義如下:

該信息結構體包含了天線驅動模式、卡片唯一序列號和讀取的數據等相關的信息。

  • 天線驅動模式

tx_mode 表示天線的驅動模式,在啟動自動檢測時,天線的模式有4 種:僅使用TX1、僅使用TX2、TX1 和TX2 交替使用、TX1 和TX2 同時使用。若啟動自動檢測時使用的模式為TX1 和TX2 交替使用,那么該值將會被設置為實際檢測到卡片的天線。tx_mode 可能被設置的值詳見表6.31。

表6.31 讀取到的天線驅動模式(am_zlg600.h)

當TX1 和TX2 同時使用時,將無法區分具體檢測到卡片的天線。

  • 片唯一序列號

每張卡片都具有一個唯一序列號,即UID。所有卡片的UID 都是不相同的。卡的序列號長度有三種:4 字節、7 字節和10 字節。uid_len 表明了讀取到的UID 的長度,uid[10]中存放了讀取到的UID(字節數)。

  • 讀取的數據

在啟動自動檢測時,指定了讀取卡片數據相關的驗證信息,若auth_mode 不為AM_ZLG600_MIFARE_CARD_AUTH_NO,且對應的密鑰正確,驗證成功,將讀取啟動自動檢測時信息結構體的nblock 成員指定的塊(由信息結構體的nblock 指定)的數據。讀取的數據存放在card_data[16]數組中,讀取卡片信息的范例程序詳見程序清單6.105。

程序清單6.105 讀取卡片信息范例程序

讀取卡片信息成功后,將通過調試串口打印出讀取到的UID 信息。并翻轉LED1 燈的狀態,指示讀取一次卡片信息成功。

2. 卡片驗證

由于卡片內存儲的數據是加密的,因此必須驗證成功后才能讀寫數據。驗證方式有“E2驗證”和“直接驗證”,它們的區別是用于驗證的密鑰存放的位置不同。

  • E2 驗證

用于驗證的密鑰是存放在ZLG600A 的E2PROM 中,其函數原型為:

其中,key_type 的類型是密鑰類型,它的值為AM_ZLG600_IC_KEY_TYPE_A 或AM_ZLG600_IC_KEY_TYPE_B,分別代表A 類型密鑰和B 類型密鑰。

p_uid 為指向UID 高4 字節緩沖區的指針,若UID 為4 字節,其值為獲取的UID 的首元素地址,即&card_info.uid[0];若UID 為7 字節,其值為獲取的UID 的第3 號元素的地址,即&card_info.uid[3];若UID 為10 字節,其值為獲取的UID 的第6 號元素的地址,即&card_info.uid[6]。key_sec 為密鑰存放在ZLG600A 的E2PROM 中的區號,該值應該與使用am_zlg600_ic_key_load()函數存儲對應密鑰時使用的區號一致。

nblock 指定本次驗證的塊號,返回值為AM_OK 時表明驗證成功,反之失敗,使用區號0 中的A 類密鑰驗證塊1 的范例程序詳見程序清單6.106。

程序清單6.106 E2 驗證范例程序

自動檢測獲取卡片信息card_info 詳見程序清單6.101,調用am_zlg600_ic_key_load()將密鑰存放在在0 區的E2PROM 中的程序詳見程序清單6.103。

實際上絕大部分卡都是4 字節的,而7 或10 字節的UID 卡極少。如果確定使用的卡片UID 為4 字節,則p_uid 的值為&card_info.uid[0]。

  • 直接驗證

用于驗證的密鑰是由接口函數提供,其函數原型為:

其中,key_type、p_uid、nblock 的含義與“E2 驗證”相同,由于需要直接提供密鑰,因此使用p_key 指向密鑰存放的緩沖區,key_len 表示密鑰的長度。返回值為AM_OK,表明驗證成功,反之失敗,直接使用6 字節密鑰進行驗證的范例程序詳見程序清單6.107。

程序清單6.107 直接驗證范例程序

程序使用6 字節全0xFF 作為密鑰驗證塊1,之所以這樣,是因為Mifare S50/S70 卡片的密鑰出廠默認為全0xFF,且密鑰長度為6 字節。對于出廠默認設置,使用A 類密鑰和B類密鑰驗證均可。對于一些有權限控制的卡片,如驗證A 類密鑰后僅只讀,驗證B 類密鑰后可寫,則需要根據實際情況進行驗證,密鑰和權限控制的修改后面會進一步介紹。

3. 讀寫數據

若驗證成功,則開始讀寫已驗證的塊。讀寫數據都是以塊為單位的,其大小為16 字節。

  • 讀取數據

讀取數據就是讀取某一塊的數據,其函數原型為:

其中,nblock 指定讀取的塊號,p_buf 為指向存放數據的緩沖區,緩沖區大小為16 字節。返回值為AM_OK 時,表明讀取數據成功,反之失敗。如程序清單6.108 所示為讀取塊1 數據的范例程序。

程序清單6.108 讀取數據范例程序

  • 寫入一塊數據

寫入數據就是將數據寫入到某一塊,其函數原型為:

其中,nblock 指定寫入的塊號,p_buf 為指向寫入數據的緩沖區,緩沖區大小為16 字節。返回值為AM_OK 時,說明寫入數據成功,反之失敗。如程序清單6.109 所示為寫入16 字節數據至塊1 的范例程序。

程序清單6.109 寫入數據范例程序

如程序清單6.110 所示是展示卡片自動檢測、驗證和讀寫數據的綜合測試范例程序。

程序清單6.110 ZLG600 綜合測試范例程序

程序每檢測到一次卡片(detect_flag 的值為1),將讀取一次信息,然后使用調試串口打印UID 的值,接著進行讀寫檢測。若讀寫檢測失敗,表明驗證失敗,很可能密鑰不是初始密鑰,已經被修改過了。

由于讀取UID 并不需要驗證,因此,當測試程序運行時,將常見的公交卡、門禁卡、飯卡等卡靠近ZLG600A,均可以讀取卡片的UID。由于這些卡片的密鑰并不知曉,因此讀寫數據測試很可能會失敗。

>>> 6.4.5 密鑰和權限控制

Mifare S50/S70 卡的初始密鑰全為0xFF,顯然,對于實際產品來講,希望能夠更改其密鑰為其它值。由于存在密鑰A和密鑰B,可以對每個密鑰設定不一樣的權限,如驗證密鑰A后僅只讀,驗證密鑰B 后可寫。下面以Mifare S50 為例,介紹密鑰和權限控制的修改方法。

密鑰和權限控制是針對扇區而言的,即一個扇區的密鑰是相同的,不同扇區的密鑰可以不同。S50 共計16 個扇區,每個扇區4 塊,每塊16 字節,前3塊為普通的數據塊,最后一塊(尾塊)為密鑰和權限控制塊。對最后一塊存儲的數據進行修改,即可完成密鑰和權限控制的修改。操作最后一塊的存儲數據時要格外小心,數據稍有錯誤,就可能導致扇區被鎖死。尾塊的前6 字節為A 密鑰,后6字節為B 密鑰,中間4 字節用于權限控制,詳見圖6.11。

圖6.11 尾塊格式

如需修改密鑰和控制權限,重點在理解字節6、7 和8(字節9 是一個普通的數據)的含義。3 個字節共計24 位,每6 位(分別為C1、C2、C3、

由于存在此關系,因此實際控制位的含義僅通過C1、C2、C3 三個位即可確定。控制尾塊和數據塊的控制位含義是不同的。對于尾塊,其控制了密鑰A、密鑰B 以及控制區域的訪問權限。控制位的含義詳見表6.32。

表6.32 尾塊控制位含義

表中,“×”表示任何情況下都無權限,“KeyA”表示通過密鑰A 驗證后可以取得權限,KeyB 表示通過密鑰B 驗證后可以取得權限,“KeyA | B”表示通過密鑰A 或者密鑰B 驗證后均可取得權限。由此可見,密鑰A 的安全性很高,任何情況下都無法讀出。特殊情況下,當C1C2C3 的值為000、010 或001 時,驗證密鑰A 后即可讀取密鑰B 區域的數據。

無論什么情況,驗證密鑰A 后,均可獲得控制區域的讀權限。通過讀取控制區域,可以知道當前C1、C2、C3 的值,以判斷需要驗證哪個密鑰后可以獲得密鑰區域或控制區域的寫權限,進而修改密鑰和控制區域的值。比如,當前的C1、C2、C3 的值為0、1、1,為了修改密鑰A,則需要先驗證密鑰B,驗證密鑰B 后,即可對尾塊進行寫入,寫入時其它數據保持不變,僅修改前6 字節(KeyA 區域)的值即可完全對密鑰A 的修改。

對于數據塊,C1、C2、C3 控制了對塊中存儲數據的操作權限,詳見表6.33。

表6.33 數據塊控制位含義

同樣,表中“×”表示任何情況下都無權限,“KeyA”表示通過密鑰A 驗證后可以取得權限,KeyB 表示通過密鑰B 驗證后可以取得權限,“KeyA | B”表示通過密鑰A 或者密鑰B 驗證后均可取得權限。

加值操作(相當于充值)和減值操作(相當于消費)是對塊中存放的值進行增加和減少操作,加值和減值均有對應的命令可以直接使用。例如,當前塊1 的C1、C2、C3 控制位的值為0、0、0(默認值),只要密鑰A 或密鑰B 驗證通過后,均可取得數據塊的讀、寫、加值、減值的權限。可以根據實際需要,修改尾塊中相應控制位的值(修改時,需確保具有寫入控制區域的權限),以對數據進行保護。

需要注意的是,凡是表中標識驗證密鑰B 后可以取得權限的,在特殊情況下驗證密鑰B后可能并不能取得權限。在介紹尾塊控制位含義時,當C1、C2、C3 的值為000、010 或001時,KeyB 區域將可能被讀取,詳見表6.32。這些情況下,由于密鑰B 可能被讀取,為了確保安全,此時密鑰B 驗證將無效,即使密鑰B 驗證通過,同樣無法取得相應的權限。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • RS485
    +關注

    關注

    39

    文章

    1163

    瀏覽量

    82471
  • 周立功
    +關注

    關注

    38

    文章

    130

    瀏覽量

    37698
  • 致遠電子
    +關注

    關注

    13

    文章

    408

    瀏覽量

    31359

原文標題:周立功:重用外設驅動代碼——讀寫卡模塊

文章出處:【微信號:Zlgmcu7890,微信公眾號:周立功單片機】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    13.56MHz讀卡天線學習筆記

    現如今,13.56MHz無線智能應用十分廣泛,如:二代身份證、手機支付、校園一卡通、工等都是使用13.56MHz無線智能技術。高頻RF
    發表于 05-23 07:13

    刷卡芯片13.56MHZ哪個好用

    其他的品牌像是復旦微、國民技術、瑞萌等等,但是今天我要為大家介紹的這款是南京中科微研發的這款SI522。Si522 是一個高度集成的, 工作在 13.56MHz 的非接觸式讀寫器芯片, 閱讀器支持
    發表于 06-12 14:32

    CI523一款支持讀寫A/B 13.56MHZ資料

    Ci523 是一個高度集成的,工作在 13.56MHz 的非接觸式讀寫器芯片,閱讀器支持 ISO/IEC14443 A/B/MIFARE。無需外圍其他電路,Ci523的內部發送器可驅動讀寫器天線
    發表于 09-17 17:53

    13.56MHZ讀卡芯片<CI522/CI523>

    13.56MHz 非接觸式通信中的高集成度讀寫芯片,它集成了在13.56MHz下所有類型的被動非接觸式
    發表于 10-15 16:56

    分享一款不錯的非接觸式讀寫13.56MHz通信方案

    分享一款不錯的非接觸式讀寫13.56MHz通信方案
    發表于 05-27 06:54

    CI522與CI523的13.56MHZ區別開發資料

    CI523 是一款應用于13.56MHz 非接觸式通信中的高集成度讀寫芯片,它集成了在13.56MHz下所有類型的被動非接觸式
    發表于 08-20 15:42

    SI522是應用于13.56MHz 非接觸式通信中高集成度讀寫系列芯片中的一員

    SI522(超低功耗13.56M芯片)替代RC522 完全兼容 PIN對PINSI522是應用于13.56MHz 非接觸式通信中高集成度讀寫
    發表于 12-30 15:02

    Si523超低功耗帶自動尋13.56MHz非接觸式讀寫

    1. 產品介紹Si523 是一個高度集成的,工作在 13.56MHz 的非接觸式讀寫器芯片,可替代MFRC523, ISO/IEC14443 A/B/MIFARE,支持自動載波偵測功能(ACD
    發表于 10-18 17:41

    CI521 RFID 13.56MHz非接觸式讀寫芯片

    1、產品介紹Ci521 是一個高度集成的,工作在13.56MHz 的非接觸式讀寫器芯片,QFN32封裝模式,閱讀器支持ISO/IEC 14443 A/B/MIFARE。無需外圍其他電路,Ci521
    發表于 11-08 10:42

    國產13.56MHz低功耗自動檢智能鎖讀卡芯片

    成功中斷喚醒或定時喚醒MCU 實現低電流消耗的同時又保證了低功耗尋模式的穩定性。Si522A是高度集成的,工作在 13.56MHz 的非接觸式讀寫器芯片,閱讀器支持 ISO/IEC 14443 A
    發表于 02-02 14:46

    載頻為13.56MHz非接觸式IC接收模塊設計

    載頻為13.56MHz非接觸式IC接收模塊設計 非接觸式IC又稱射頻,是世界上最近幾年發展起來的一項新技術。它利用無線
    發表于 01-21 09:42 ?2617次閱讀
    載頻為<b class='flag-5'>13.56MHz</b>非接觸式IC<b class='flag-5'>卡</b>接收<b class='flag-5'>模塊</b>設計

    基于MFRC523的非接觸式讀寫13.56MHz通信設計方案

    基于MFRC523的非接觸式讀寫13.56MHz通信設計方案 MFRC523是NXP公司的一個的高集成讀/寫器,用于13.56MHz頻率的非接觸式
    發表于 04-13 10:01 ?1874次閱讀
    基于MFRC523的非接觸式<b class='flag-5'>讀寫</b><b class='flag-5'>13.56MHz</b><b class='flag-5'>通信</b>設計方案

    13.56MHz RFID讀寫設備規范的詳細資料說明

    本標準規定了13.56MHz RFID讀寫設備(包括臺式設備和手持設備)的技術要求、試驗方法和檢驗規則,以及標志、包裝、貯存和運輸的要求。
    發表于 03-03 16:43 ?19次下載
    <b class='flag-5'>13.56MHz</b> RFID<b class='flag-5'>讀寫</b>設備規范的詳細資料說明

    13.56MHz 的非接觸式讀寫器Si522A-內部集成低功耗自動尋與定時喚醒功能

    13.56MHz 的非接觸式讀寫器Si522A-內部集成低功耗自動尋與定時喚醒功能
    的頭像 發表于 12-13 18:25 ?1107次閱讀

    13.56MHz 非接觸式讀寫芯片LS5120產品介紹

    電子發燒友網站提供《13.56MHz 非接觸式讀寫芯片LS5120產品介紹.zip》資料免費下載
    發表于 03-22 11:14 ?8次下載
    主站蜘蛛池模板: 国产精品嫩草影院| 色琪琪久久热在线| 0855午夜福利伦理电影| 伦理片在线3348| 被黑人做的白浆直流| 吻嘴胸全身好爽床大全| 护士美女照片| 2012中文字幕手机在线| 日本中文字幕巨大的乳专区| 国产偷国产偷亚洲高清app| 一抽一出BGM免费50分动漫| 嗯啊…跟校草在教室里做h| 囯产精品久久久久久久久蜜桃| 亚洲精品天堂无码中文字幕影院| 蜜柚视频在线观看全集免费观看| 国产成人久久精品激情| 在线亚洲精品国产一区麻豆 | 5278欧美一区二区三区| 男人插曲视频大全免费网站| 俄罗斯少女人体| 亚洲精品久久7777777| 精品国产午夜肉伦伦影院| av在线观看地址| 亚洲VA天堂VA欧美VA在线| 嗯啊…嗯np男男双性总受| 国产人妻XXXX精品HD电影| 99久久精品国产国产毛片 | 国产69精品久久久久人妻刘玥| 亚洲中文字幕永久在线全国| 热久久伊大人香蕉网老师| 久久99re66热这里只有精品| 动漫美女性侵| 2020年国产理论| 亚洲 日韩 国产 中文视频| 暖暖高清视频免费| 激情欧美日韩一区二区| 古风H啪肉NP文| 99热.com| 中文无码热在线视频| 午夜福利免费视频921000电影| 男人插曲女人下生免费大全|