Polling for Cards (卡片詢問) 步驟
根據您提供的 PDF 文件 (AN10834 - MIFARE ISO/IEC 14443 PICC Selection) 和圖片,我將專注於說明卡片啟動的第一個關鍵步驟:Polling for cards (卡片詢問)。這一流程主要涉及讀卡器 (PCD) 發送詢問命令,以及卡片 (PICC) 回覆一個狀態字節,以表示它的存在和類型。
第一部分:Polling for Cards (卡片詢問) 步驟說明
根據您提供的 PDF 文件中的 2.1 Polling for cards 內容,這個步驟用於確認射頻場 (RF field) 內是否存在符合 ISO/IEC 14443 Type A 或 Type B 標準的卡片。
流程概述:
| 步驟編號 | 動作主體 | 傳輸內容 (命令) | 傳輸內容 (響應) | 目的 |
| 1. | PCD (讀卡器) | RF Field ON | N/A | 啟動射頻場,並等待 5ms (T(min)_rf_on)。 |
| 2. | PCD (讀卡器) | REQA (REQuest type A) | N/A | PCD 發送 Type A 詢問命令 (7位元長度)。 |
| 3. | PICC (卡片) | N/A | ATQA (Answer To reQuest type A) | MIFARE 1K 卡片 回覆 ATQA (2 個位元組),表示它的存在和基本類型。 |
| 4. | PCD (讀卡器) | N/A | (接收 ATQA) | PCD 接收到 ATQA 後,確認 Type A 卡片在場,然後進入下一步:Activate Card (卡片啟動,即防衝突流程)。 |
MIFARE 1K 卡的關鍵數據:
REQA (Type A 詢問命令): 通常是 26 (十六進制)。
ATQA (Type A 響應): 對於 MIFARE Classic 1K,ATQA 的值通常是 00 04 或類似於
xx 04的結構(其中04表示其屬於 NXP MIFARE Classic 家族,並使用 7-byte UID)。
第二部分:Python Tkinter 模擬 Polling 流程
以下是使用 Python tkinter 建立一個簡單 GUI 來視覺化上述 Polling for Cards 步驟的程式碼架構。它將專注於 REQA 命令發送與 ATQA 響應接收的過程。
import tkinter as tk
from tkinter import ttk
class PollingSimulator:
def __init__(self, master):
self.master = master
master.title("MIFARE 卡片詢問 (Polling for Cards) 模擬")
# 模擬數據
self.REQA_COMMAND = "26 (Hex)"
self.MIFARE_1K_ATQA = "00 04 (Hex)"
# 狀態變數
self.step_text = tk.StringVar()
self.status_text = tk.StringVar()
self.current_step = 0
self.max_step = 4
# 初始化介面
self.create_widgets()
self.reset_flow()
def create_widgets(self):
# 標題
ttk.Label(self.master, text="ISO/IEC 14443-A Polling 流程", font=('Arial', 14, 'bold')).grid(row=0, column=0, columnspan=2, pady=10)
# 步驟顯示
ttk.Label(self.master, text="當前步驟:", font=('Arial', 10, 'bold')).grid(row=1, column=0, sticky='w', padx=10, pady=5)
self.step_label = ttk.Label(self.master, textvariable=self.step_text, font=('Arial', 10, 'italic'), foreground='blue')
self.step_label.grid(row=1, column=1, sticky='w', pady=5)
# 狀態與結果顯示
ttk.Label(self.master, text="流程狀態:", font=('Arial', 10, 'bold')).grid(row=2, column=0, sticky='w', padx=10, pady=5)
self.status_label = ttk.Label(self.master, textvariable=self.status_text, wraplength=400, justify=tk.LEFT, font=('Arial', 10))
self.status_label.grid(row=2, column=1, sticky='w', pady=5)
# 關鍵數據區
data_frame = ttk.LabelFrame(self.master, text="傳輸數據")
data_frame.grid(row=3, column=0, columnspan=2, padx=10, pady=10, sticky="ew")
ttk.Label(data_frame, text="REQA 命令:").grid(row=0, column=0, padx=5, pady=2, sticky='w')
ttk.Label(data_frame, text=self.REQA_COMMAND, foreground='darkred').grid(row=0, column=1, padx=5, pady=2, sticky='w')
ttk.Label(data_frame, text="MIFARE 1K ATQA:").grid(row=1, column=0, padx=5, pady=2, sticky='w')
ttk.Label(data_frame, text=self.MIFARE_1K_ATQA, foreground='darkgreen').grid(row=1, column=1, padx=5, pady=2, sticky='w')
# 操作按鈕
self.next_button = ttk.Button(self.master, text="執行下一動作", command=self.next_step)
self.next_button.grid(row=4, column=0, pady=10, padx=10, sticky='e')
self.reset_button = ttk.Button(self.master, text="重置流程", command=self.reset_flow)
self.reset_button.grid(row=4, column=1, pady=10, padx=10, sticky='w')
def reset_flow(self):
self.current_step = 0
self.step_text.set(f"0/{self.max_step}")
self.status_text.set("準備就緒。PCD 尚未啟動 RF 載波。")
self.next_button.config(state=tk.NORMAL)
def next_step(self):
self.current_step += 1
self.step_text.set(f"{self.current_step}/{self.max_step}")
if self.current_step == 1:
# 步驟 1: 啟動 RF
self.status_text.set(
f"[動作 1] PCD 動作:啟動 RF 載波 (RF Field ON)。\n"
f"PCD 等待 T(min)_rf_on (至少 5ms) 以確保 PICC 準備就緒。"
)
self.next_button.config(text="發送 REQA 命令")
elif self.current_step == 2:
# 步驟 2: PCD 發送 REQA
self.status_text.set(
f"[動作 2] PCD 動作:發送 Type A 詢問命令 (REQA)。\n"
f"PCD 廣播 REQA ({self.REQA_COMMAND}),詢問 Type A 卡片是否存在。"
)
self.next_button.config(text="等待 PICC 響應 ATQA")
elif self.current_step == 3:
# 步驟 3: PICC 回覆 ATQA
self.status_text.set(
f"[動作 3] PICC 動作:MIFARE 1K 卡片回覆 ATQA。\n"
f"卡片響應 ATQA ({self.MIFARE_1K_ATQA}),確認其存在和基本類型。"
)
self.next_button.config(text="PCD 確認卡片在場")
elif self.current_step == 4:
# 步驟 4: 流程結束並進入下一階段
self.status_text.set(
f"[動作 4] PCD 動作:接收並解析 ATQA,確認是 Type A 卡。\n"
f"Polling 步驟完成。PCD 準備進入 **卡片啟動/防衝突 (Activate Card/Anti-collision)** 流程。"
)
self.next_button.config(state=tk.DISABLED, text="Polling 流程結束")
else:
self.status_text.set("流程結束。請點擊 '重置流程' 重新開始。")
self.next_button.config(state=tk.DISABLED)
if __name__ == "__main__":
root = tk.Tk()
app = PollingSimulator(root)
root.geometry("500x350")
root.mainloop()
程式碼執行說明:
環境需求: 確保您的 Python 環境安裝了
tkinter庫。執行效果: 運行上述程式碼後,會彈出一個 GUI 視窗,模擬 Polling 流程。
操作流程:
點擊「執行下一動作」按鈕。
視窗將依序顯示 PCD 啟動 RF、發送 REQA 命令、MIFARE 1K 卡片回覆 ATQA,直到最終 PCD 確認卡片在場,準備進入防衝突階段。
這視覺化了從射頻啟動到確認卡片存在的整個 Polling 過程。







沒有留言:
張貼留言