 NT3H2211 NFC 標簽|I2C 驅(qū)動 + NDEF 文本 / URI 記錄完整實踐)
前言最近做了基于 STM32L431VC NT3H2211 的 NFC 近場通信實驗踩了 I2C 時序、NDEF 數(shù)據(jù)格式、中文 UTF?8 編碼不少坑。NT3H2211 是一枚很有意思的 Type?2 類型 NFC 標簽芯片具備I2C、RF 射頻雙訪問接口單片機可以通過 I2C 讀寫標簽內(nèi)存手機可以通過 13.56MHz 射頻無線讀寫兩套接口訪問同一片存儲區(qū)域。本篇把完整調(diào)試過程、原理、代碼關(guān)鍵點、問題排查整理出來方便大家快速上手。硬件環(huán)境主控STM32L431VCNFC 芯片NT3H2211 擴展板通信接口硬件 I2C1PB6 (SCL)、PB7 (SDA)調(diào)試工具串口助手 SSCOM波特率 115200NFC 伴侶 APP一、NT3H2211 核心原理NT3H2211 內(nèi)存按照16 字節(jié)一頁進行管理主要分為制造數(shù)據(jù)區(qū)、用戶數(shù)據(jù)區(qū)、配置區(qū)。I2C 從機地址固定為0x55。雙界面機制STM32 通過 I2C 改寫標簽內(nèi)容手機靠近產(chǎn)生 13.56MHz 射頻場既可以給無源標簽供電也能讀寫數(shù)據(jù)。兩邊可以修改同一套存儲這也是本次實驗一個很有意思的現(xiàn)象手機 APP 寫入數(shù)據(jù)會覆蓋單片機 I2C 寫入的內(nèi)容。NDEF 格式NFC 數(shù)據(jù)交換標準格式。一條 NDEF 消息由多條記錄組成每條記錄包含消息標志位、類型、負載長度、負載數(shù)據(jù)。常見兩種記錄Text 文本記錄、URI 鏈接記錄。Text 文本記錄負載結(jié)構(gòu)狀態(tài)字節(jié) 語言碼 實際文本狀態(tài)字節(jié)標記編碼方式UTF?8/UTF?16以及語言碼的字節(jié)長度。中文必須使用 UTF?8 編碼一個漢字占 3 字節(jié)。二、硬件 I2C 引腳配置要點PB6、PB7 復(fù)用為 I2C1這里是很多人踩坑的地方。GPIO_InitStruct.Pin GPIO_PIN_6|GPIO_PIN_7; GPIO_InitStruct.Mode GPIO_MODE_AF_OD; // 復(fù)用開漏I2C必須開漏輸出 GPIO_InitStruct.Pull GPIO_PULLUP; // 上拉電阻保證總線電平 GPIO_InitStruct.Alternate GPIO_AF4_I2C1; HAL_GPIO_Init(GPIOB, GPIO_InitStruct);??重點I2C 要使用開漏模式不能推挽輸出。開漏搭配上拉電阻實現(xiàn) I2C 總線 “線與” 邏輯。本實驗時序配置0x10909CEC對應(yīng)標準 100kHz I2C 速率。三、軟件實現(xiàn)流程整體業(yè)務(wù)流程I2C初始化 → 讀取芯片制造數(shù)據(jù) → 配置CC容器初始化標簽 → 寫入NDEF文本記錄 → 寫入NDEF URI記錄 → I2C讀取用戶區(qū)數(shù)據(jù)串口打印 → 等待手機NFC讀取1、標簽初始化初始化 I2C 之后讀取制造頁修改 CCCapability Container容器參數(shù)標記這是一塊支持 NDEF 的 NFC 標簽寫完之后回讀校驗保證配置生效。void NFC_Init(void) { uint8_t buf[NFC_PAGE_SIZE] {0}; MX_I2C1_Init(); NT3HReaddManufactoringData(buf); buf[0] 0xAA; buf[12] 0xE1; // NDEF標簽標識 buf[13] 0x10; // 版本1.0 buf[14] 0x6D; // 內(nèi)存頁數(shù) buf[15] 0x00; NT3HWriteInitData(buf); NT3HReaddManufactoringData(buf); //回讀驗證 }2、寫入 NDEF 文本、URI 記錄封裝好storeText()寫入文本記錄storeUrihttp()寫入 URI 鏈接記錄。第一條文本記錄設(shè)置 MB1消息開始最后一條 URI 記錄設(shè)置 ME1消息結(jié)束ret storeText(NDEFFirstPos, (uint8_t *)Hello NFC); ret storeUrihttp(NDEFLastPos, (uint8_t *)123.com);文本記錄內(nèi)部會設(shè)置狀態(tài)字節(jié)0x02代表 UTF?8 編碼語言碼長度 2 字節(jié)語言碼en。3、讀取標簽數(shù)據(jù)串口輸出循環(huán)讀取多頁用戶區(qū)內(nèi)存拼接緩沖區(qū)后串口輸出。這里會出現(xiàn)一個現(xiàn)象串口打印出現(xiàn)大量亂碼。NT3HReadUserpages(15, data_buf); printf(\r\nreaddata:%s, data_buf);亂碼原因NDEF 原始是二進制數(shù)據(jù)包含消息頭、記錄頭這些非 ASCII 不可打印字節(jié)直接用%s字符串打印就會亂碼。數(shù)據(jù)本身沒有損壞改用十六進制打印%02X就可以看到完整原始字節(jié)流。4、手機端驗證兩種驗證手段直接手機 NFC 感應(yīng)標簽讀取 NDEF 文本使用 NFC 伴侶 APP通過射頻接口直接向標簽寫入中文姓名。實驗中發(fā)現(xiàn)手機 APP 寫入的中文 “尹強” 直接覆蓋掉 STM32 通過 I2C 寫入的 Hello NFC完美印證 NT3H2211 雙界面共享存儲的特性。解析數(shù)據(jù)包可以看到中文每個漢字占 3 字節(jié) UTF?8 編碼。四、踩坑問題記錄I2C 連續(xù)讀寫出錯NT3H2211 芯片對時序有要求連續(xù) I2C 讀寫之間必須加 1ms 延時。代碼讀寫函數(shù)加入HAL_Delay(1)解決連續(xù)訪問異常。手機 NFC 識別不到標簽NFC 有效距離很短一般 1?4cm手機 NFC 感應(yīng)區(qū)域要緊貼天線位置屏蔽罩附近感應(yīng)效果最好。中文顯示亂碼NDEF 文本記錄狀態(tài)字節(jié)必須指明 UTF?8 編碼如果設(shè)置錯誤中文就會解析亂碼。不要用推挽模式配置 I2C 引腳會造成總線沖突通信完全失敗。五、拓展腦洞基于這套硬件還可以做很多有意思項目NFC 電子名片寫入 vCard 格式手機一碰添加聯(lián)系人NFC 配網(wǎng)把 WiFi 賬號密碼寫入標簽手機一碰完成配網(wǎng)簡易 NFC 門禁將學(xué)號身份信息存入標簽傳感器數(shù)據(jù)實時寫入 NFC手機靠近讀取溫濕度等環(huán)境數(shù)據(jù)。小結(jié)這次實驗把 I2C 外設(shè)驅(qū)動、NDEF 協(xié)議棧、NFC 芯片雙界面特性完整跑通。NFC 底層不復(fù)雜但協(xié)議細節(jié)很多尤其 NDEF 各個字段、文本負載格式很容易忽略。遇到串口亂碼不要第一時間認為硬件讀寫失敗優(yōu)先打印十六進制原始數(shù)據(jù)排查。