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