RFID基礎(chǔ)——ISO15693標(biāo)簽存儲(chǔ)結(jié)構(gòu)及訪問控制命令說明
ISO15693協(xié)議標(biāo)準(zhǔn)的高頻RFID無源IC卡,具有高度防沖突與長距離運(yùn)作等優(yōu)點(diǎn),主要應(yīng)用與資產(chǎn)管理、圖書館管理、供應(yīng)鏈管理、醫(yī)療領(lǐng)域。開發(fā)基于 ISO15693 的應(yīng)用首先需要了解標(biāo)簽的存儲(chǔ)結(jié)構(gòu)以及如何讀寫操作。
ISO15693-3詳細(xì)描述了 VICC 的內(nèi)存結(jié)構(gòu)、 VICC 和 VCD 之間通信所使用的數(shù)據(jù)幀格式以及訪問控制 VICC 的命令。本文將結(jié)合ICODE SLIX詳細(xì)介紹這些內(nèi)容。
VICC 的內(nèi)存結(jié)構(gòu)
ISO15693-3中規(guī)定的命令假定物理內(nèi)存以固定大小的塊(或頁)出現(xiàn)。
- 最多可尋址256個(gè)塊。
- 塊大小最多可達(dá)256位。
- 這導(dǎo)致最大內(nèi)存容量高達(dá)8 kBytes (64 kBits)。
內(nèi)存中包含配置區(qū)域和用戶存儲(chǔ)兩部分。配置區(qū)域存儲(chǔ)了唯一標(biāo)識(shí)符(UID)、應(yīng)用族標(biāo)識(shí)符(AFI)、數(shù)據(jù)存儲(chǔ)格式標(biāo)識(shí)符(DSFID)。以 ICODE SLIX 為例:
ICODE SLIX存儲(chǔ)器分為32個(gè)塊、每個(gè)塊由4字節(jié)(32位)組成,共128字節(jié),如下圖,上部4個(gè)塊(-4、-3、-2、-1塊)分別用于UID(64位唯一ID序列號(hào))、特殊功能(EAS、AFI、DSFID)和寫入控制位,其他28個(gè)塊為用戶數(shù)據(jù)塊。

Block -4 & Block -3
Block -4 & Block -3共八個(gè)字節(jié),用于記錄標(biāo)簽的UID,每個(gè)字節(jié)含義如下圖所示:

UID7(64~57):固定值“E0”
UID6(56~49):廠商代碼,“04”代表NXP,“07”代表TI,"23"代表上海貝嶺
UID5(48~41):產(chǎn)品分類代碼,“01”代表“ICODE SLIX”,“80”代表Tag-it HF-I Plus Chip,“00”代表Tag-it HF-I Plus Inlay
UID4UID0(401):標(biāo)簽芯片生產(chǎn)序列代碼
Block -2
Block -2是特殊功能區(qū),第一個(gè)字節(jié)未使用,剩下三個(gè)字節(jié)分別用于記錄EAS、AFI和DSFID。
EAS(Electronic Article Surveillance,電子防盜系統(tǒng))主要用來防止物品被盜,標(biāo)簽管理者可以設(shè)置(EAS=1)和清除(EAS=0)EAS標(biāo)識(shí),當(dāng)設(shè)置有EAS標(biāo)識(shí)的標(biāo)簽通過讀寫器的作用范圍時(shí),讀寫器會(huì)識(shí)別EAS標(biāo)識(shí),發(fā)出警報(bào)。EAS的數(shù)據(jù)結(jié)構(gòu)如下圖,EAS的LSB的第一位(e位)寫1代表EAS標(biāo)示有效,寫0代表清除EAS標(biāo)示,其他位無效。

特殊功能AFI(Application Family Idenfifier,應(yīng)用族標(biāo)識(shí)符),可事先規(guī)定應(yīng)用族代碼并寫入AFI字節(jié),在處理多個(gè)標(biāo)簽的時(shí)候進(jìn)行分類處理。
例如在物流中心處理大量貨物時(shí),可根據(jù)標(biāo)簽上的AFI應(yīng)用族標(biāo)識(shí)符來區(qū)分是出口貨物還是內(nèi)銷貨物。
AFI被編碼在一個(gè)字節(jié)里,由兩個(gè)半字節(jié)組成。
AFI的高位半字節(jié)用于編碼一個(gè)特定的或所有應(yīng)用族,下圖是AFI的族編碼定義。
AFI的低位半字節(jié)用于編碼一個(gè)特定的或所有應(yīng)用子族。子族不同于0的編碼有其自己的所有權(quán)。

數(shù)據(jù)存儲(chǔ)格式標(biāo)識(shí)符DSFID(data storage format identifier)。數(shù)據(jù)存儲(chǔ)格式標(biāo)識(shí)符指出了數(shù)據(jù)在 VICC 內(nèi)存中是怎樣構(gòu)成的。DSFID 被相應(yīng)的命令編程和鎖定。DSFID 被編碼在一個(gè)字節(jié)里。DSFID 允許即時(shí)知道數(shù)據(jù)的邏輯組織。假如VICC不支持DSFID 的編程,VICC將以值“0”作為應(yīng)答。
Block -1
BLock -1是寫入控制位,具體控制分配見下圖,它可以控制每個(gè)數(shù)據(jù)塊的寫入和塊-2(特殊功能塊)每個(gè)字節(jié)的寫入。寫入位1代表寫入保護(hù),且不可再修改控制位。其中Byte0用于控制 Block -2特殊功能區(qū)每個(gè)字節(jié)的寫入保護(hù)。

傳輸協(xié)議
傳輸協(xié)議(或協(xié)議)定義了 VCD 和 VICC 之間指令和數(shù)據(jù)雙向交換的機(jī)制。它基于“VCD 首先說”的概念。這意味著除非收到并正確地解碼一個(gè) VCD 發(fā)送來的指令,任何 VICC 將不會(huì)開始傳輸。
- 每一次完整的數(shù)據(jù)傳輸都是 VCD 向 VICC 發(fā)送一次請求,然后從 VICC(s)到 VCD 的一次響應(yīng)。
- 每一次請求和每一次響應(yīng)包含在一幀內(nèi)。幀分隔符(SOF, EOF)在 ISO/IEC 15693-2 中有規(guī)定。
- 每次請求包括以下的域:標(biāo)志、命令編碼、強(qiáng)制和可選的參數(shù)域(取決于命令)、應(yīng)用數(shù)據(jù)域、CRC。
- 每次響應(yīng)包括以下的域:標(biāo)志、強(qiáng)制和可選的參數(shù)域(取決于命令)、應(yīng)用數(shù)據(jù)域、CRC。
- 協(xié)議是雙向的。一幀中傳輸?shù)奈坏膫€(gè)數(shù)是 8 的倍數(shù),即整數(shù)個(gè)字節(jié)。
- 一個(gè)單字節(jié)域在通訊中首先傳輸最低有效位(LSBit)。
- 一個(gè)多字節(jié)域在通訊中首先傳輸最低有效字節(jié)(LSByte),每字節(jié)首先傳輸最低有效位(LSBit)。
- 標(biāo)志的設(shè)置表明可選域的存在。當(dāng)標(biāo)志設(shè)置為 1,這個(gè)域存在。當(dāng)標(biāo)志設(shè)置為 0,這個(gè)域不存在。
- RFU 標(biāo)志應(yīng)設(shè)置為 0。
請求格式
請求數(shù)據(jù)的格式包含:標(biāo)志、命令編碼、參數(shù)和數(shù)據(jù)、CRC
| SOF | 標(biāo)志 | 命令編碼 | 參數(shù) | 數(shù)據(jù) | CRC | EOF |
|---|---|---|---|---|---|---|
| 8 bits | 8 bits | 可選 | 可選 | 16 bits |
請求標(biāo)志
在請求中,字段“flags”指定VICC要執(zhí)行的操作,以及相應(yīng)的字段是否存在。它包含 8 位(bits)。為了方便描述,以b1,b2,……,b7,b8表示,每一位(bit)含義如下圖所示:

其中高半字節(jié)b5~b8的含義取決于低半字節(jié)中b3的值。b3值為0時(shí),b5~b8的含義參照圖中表4的描述,b3值為1時(shí),b5~b8的含義參照圖中表5的描述。
b3表示目錄標(biāo)志,這個(gè)名稱的原文是Inventory_flag,翻譯為目錄標(biāo)志感覺過于生硬。其實(shí)是用于標(biāo)志請求命令是否為列出射頻場中符合條件的 VICCs,簡單的說就是尋卡。
標(biāo)志的典型選值及說明如下:
| 值(16進(jìn)制) | 值(2進(jìn)制) | 說明 |
|---|---|---|
| 0x06 | 0000 0110 | 操作多張卡,不需要AFI參數(shù),高速率 |
| 0x26 | 0010 0110 | 操作單張卡(射頻場中有多張卡時(shí)都不會(huì)響應(yīng)),不需要AFI參數(shù),高速率 |
| 0x16 | 0001 0110 | 操作多張卡,需要AFI參數(shù),高速率 |
| 0x36 | 0011 0110 | 操作單張卡,需要AFI參數(shù),高速率 |
| 0x22 | 0010 0010 | 請求尋址需要UID,高速率 |
命名編碼
ISO15693中把請求命令分為四種類型:
- 強(qiáng)制的:命令碼范圍從 '01' 到 '1F' 。所有 VICCs 都支持強(qiáng)制命令碼。
- 可選的:命令碼范圍從 '20' 到 '9F' 。VICCs 可以有選擇地支持可選的命令碼。
- 定制的:命令碼范圍從 'A0' 到 'DF' 。VICCs 支持定制命令,在它們的可選范圍內(nèi),執(zhí)行由制造商規(guī)定的功能。標(biāo)志的功能(包括保留位)將不會(huì)被修改,除非是選擇標(biāo)志。可以被定制的域僅限于參數(shù)和數(shù)據(jù)域。
- 私有的:命令碼范圍從 'E0' 到 'FF' 。這個(gè)命令方便 IC 和 VICC 制造商用于各種目的的應(yīng)用,如測試、系統(tǒng)信息編程等等。它們在這個(gè)標(biāo)準(zhǔn)中沒有作規(guī)定。

響應(yīng)格式
響應(yīng)數(shù)據(jù)的格式包含:標(biāo)志、參數(shù)、數(shù)據(jù)、CRC

響應(yīng)標(biāo)志
在一次響應(yīng)中,字段“flags”指出 VICC 是怎樣完成動(dòng)作的,并且相應(yīng)字段是否出現(xiàn)。響應(yīng)標(biāo)志由 8 bits 組成。

響應(yīng)錯(cuò)誤碼
當(dāng)錯(cuò)誤標(biāo)志被 VICC 置位,將包含錯(cuò)誤碼域,并提供出現(xiàn)的錯(cuò)誤信息。錯(cuò)誤碼在表 7 中定義。假如 VICC 不支持表 7 中列出的規(guī)定錯(cuò)誤碼,VICC 將以錯(cuò)誤碼 '0F' 應(yīng)答("不給出錯(cuò)誤信息")。

命令詳解
強(qiáng)制的命令
尋卡命令(INVENTORY=0x01)
| 請求(VCD TO VICC) | 標(biāo)志(1B)+命令編碼(1B)+[AFI(1B)+MASK長度(1B)+mask值(1B)]+CRC16(2B) |
| 06 01 1E 4A | |
| 響應(yīng)(VICC TO VCD) | 標(biāo)志(1B)+DSFID(1B)+UID(8B)+CRC16(2B) |
| 00 00 99 07 30 1A 53 01 04 E0 A8 8D |
保持靜默(STAY QUIET=0x02)
| 請求(VCD TO VICC) | 標(biāo)志(1B)+命令編碼(1B)+UID(8B) +CRC16(2B)(2B) |
| 22 02 99 07 30 1A 53 01 04 E0 A9 E2 | |
| 響應(yīng)(VICC TO VCD) | 標(biāo)志(1B) |
| 00 |
可選的命令
讀單個(gè)數(shù)據(jù)塊(READ SINGLE BLOCK=0x20)
| 請求(VCD TO VICC) | 標(biāo)志(1B)+命令編碼(1B)+UID(8B)+數(shù)據(jù)(塊數(shù)量1B)+CRC16(2B) |
| 22 20 99 07 30 1A 53 01 04 E0 01 23 2D | |
| 響應(yīng)(VICC TO VCD) | 標(biāo)志(1B)+數(shù)據(jù)(4B)+CRC16(2B) |
| 00 61 62 63 64 C2 90 |
寫單個(gè)數(shù)據(jù)塊(WRITE SINGLE BLOCK=0x21)
| 請求(VCD TO VICC) | 標(biāo)志(1B)+命令編碼(1B)+UID(8B)+塊序號(hào)(1B)+數(shù)據(jù)(塊長度4B)+CRC16(2B) |
| 22 21 99 07 30 1A 53 01 04 E0 01 61 62 63 64 5B 8B | |
| 響應(yīng)(VICC TO VCD) | 標(biāo)志(1B)+CRC16(2B) |
| 00 78 F0 |
鎖定數(shù)據(jù)塊(LOCK BLOCK=0x22)
| 請求(VCD TO VICC) | 標(biāo)志(1B)+命令編碼(1B)+UID(8B)+塊序號(hào)(1B)+CRC16(2B) |
| 22 22 99 07 30 1A 53 01 04 E0 1B B6 CA | |
| 響應(yīng)(VICC TO VCD) | 標(biāo)志(1B)+CRC16(2B) |
| 00 78 F0 |
讀多個(gè)數(shù)據(jù)塊(READ MULTIPLE BLOCKS=0x23)
| 請求(VCD TO VICC) | 標(biāo)志(1B)+命令編碼(1B)+UID(8B)+數(shù)據(jù)(首塊序號(hào)+塊數(shù)量)(2B)+CRC16(2B) |
| 22 23 99 07 30 1A 53 01 04 E0 00 03 3C 36 | |
| 響應(yīng)(VICC TO VCD) | 標(biāo)志(1B)+數(shù)據(jù)(4B)*(塊數(shù)量+1)+CRC16(2B) |
| 00 2C 00 00 00 61 62 63 64 00 00 00 00 00 00 00 00 8B 21 |
讀取多個(gè)數(shù)據(jù)塊時(shí),塊序號(hào)范圍是 0x00~0xFF,塊數(shù)量的值比VICC返回的塊數(shù)要少1。也就是請求數(shù)據(jù)中塊數(shù)量的值為0,表示請求讀單個(gè)塊,值為 0x03 表示請求4個(gè)塊。
寫多個(gè)數(shù)據(jù)塊(WRITE MULTIPLE BLOCKS=0x24)
| 請求(VCD TO VICC) | 標(biāo)志(1B)+命令編碼(1B)+UID(8B)+首塊序號(hào)(1B)+塊數(shù)量(1B)+數(shù)據(jù)(塊長度NB)+CRC16(2B) |
| 22 24 99 07 30 1A 53 01 04 E0 00 03 01 01 01 01 02 02 02 02 03 03 03 03 96 D3 | |
| 響應(yīng)(VICC TO VCD) | 標(biāo)志(1B)+CRC16(2B) |
| 00 78 F0(寫入成功) 01 0F 68 EE(寫入失敗 |
由于是可選命令,并不是所有的標(biāo)簽都支持,例如最流行的NXP的ICODE SLIX、ICODE SLIX2系列都沒有支持該命令 [1]。ST的ST25DV04K、ST25DV16K、ST25DV64K支持該命令。[2]
選擇(SELECT=0x25)
| 請求(VCD TO VICC) | 標(biāo)志(1B)+命令編碼(1B)+UID(8B)+CRC16(2B) |
| 22 25 99 07 30 1A 53 01 04 E0 72 FC | |
| 響應(yīng)(VICC TO VCD) | 標(biāo)志(1B)+CRC16(2B) |
| 00 78 F0 |
復(fù)位(RESET TO READY=0x26)
| 請求(VCD TO VICC) | 標(biāo)志(1B)+命令編碼(1B)+UID(8B)+CRC16(2B) |
| 22 26 99 07 30 1A 53 01 04 E0 75 2A | |
| 響應(yīng)(VICC TO VCD) | 標(biāo)志(1B)+CRC16(2B) |
| 00 78 F0 |
寫AFI(WRITE AFI=0x27)
| 請求(VCD TO VICC) | 標(biāo)志(1B)+命令編碼(1B)+UID(8B)+AFI值(1B)+CRC16(2B) |
| 22 27 99 07 30 1A 53 01 04 E0 00 5F F8 | |
| 響應(yīng)(VICC TO VCD) | 標(biāo)志(1B)+CRC16(2B) |
| 00 78 F0 |
鎖定AFI(LOCK AFI=0x28)
| 請求(VCD TO VICC) | 標(biāo)志(1B)+命令編碼(1B)+UID(8B)+CRC16(2B) |
| 22 28 99 07 30 1A 53 01 04 E0 A0 F1 | |
| 響應(yīng)(VICC TO VCD) | 標(biāo)志(1B)+CRC16(2B) |
| 00 78 F0 |
寫DSFID(WRITE DSFID=0x29)
| 請求(VCD TO VICC) | 標(biāo)志(1B)+命令編碼(1B)+UID(8B)+DSFID值(1B)+CRC16(2B) |
| 22 29 99 07 30 1A 53 01 04 E0 06 92 1C | |
| 響應(yīng)(VICC TO VCD) | 標(biāo)志(1B)+CRC16(2B) |
| 00 78 F0 |
鎖定DSFID(LOCK DSFID=0x2A)
| 請求(VCD TO VICC) | 標(biāo)志(1B)+命令編碼(1B)+UID(8B)+CRC16(2B) |
| 22 2A 99 07 30 1A 53 01 04 E0 5A 6A | |
| 響應(yīng)(VICC TO VCD) | 標(biāo)志(1B)+CRC16(2B) |
| 00 78 F0 |
獲取系統(tǒng)信息(GET SYSTEM INFORMATION=0x2B)
| 請求(VCD TO VICC) | 標(biāo)志(1B)+命令編碼(1B)+UID(8B)+CRC16(2B) |
| 22 2B 99 07 30 1A 53 01 04 E0 A7 27 | |
| 響應(yīng)(VICC TO VCD) | 標(biāo)志(1B)+信息標(biāo)志(1B)+UID(8B)+DSFID(1B)+AFI(1B)+信息域([VICC內(nèi)存信息(2B)]+[IC參考(1B)])+CRC16(2B) |
| 00 0F 99 07 30 1A 53 01 04 E0 01 01 1B 03 01 BB C6 |
響應(yīng)數(shù)據(jù)中的信息標(biāo)志占8bits,具體含義如下表所示

VICC 內(nèi)存容量信息占兩個(gè)字節(jié),記錄了塊容量(以字節(jié)為單位),塊數(shù)量。

塊容量以 5 bits 的字節(jié)數(shù)量表達(dá)出來,允許定制到 32 字節(jié),即 256 bits。它比實(shí)際的字節(jié)數(shù)目要少1。例如:值 1F 表示 32 字節(jié),值 00 表示 1 字節(jié)。
塊數(shù)目是基于 8 bits,允許定制到 256 個(gè)塊。它比實(shí)際的字節(jié)數(shù)目要少 1。例如:值 FF 表示 256 個(gè)塊,值 00 表示 1 個(gè)塊。
最高位的 3 個(gè) bits 保留做未來備用,可以設(shè)置為 0。
IC 參考基于 8 個(gè) bits,它的意義由 IC 制造商定義。
上述示例中,響應(yīng)的信息標(biāo)志為 0x0F,表示 DSFID 、 AFI、VICC內(nèi)存容量、IC參考都會(huì)在結(jié)果中顯示。其中信息域中VICC內(nèi)存容量的值為1B 03,由于傳輸協(xié)議中定義了一個(gè)多字節(jié)域在通訊中首先傳輸最低有效字節(jié)(LSByte),每字節(jié)首先傳輸最低有效位(LSBit),因此 1B 是表示有27個(gè)數(shù)據(jù)塊,03 表示每塊4個(gè)字節(jié)。
獲取多個(gè)塊安全狀態(tài)(GET MULTIPLE BLOCK SECURITY STATUS=0x2C)
| 請求(VCD TO VICC) | 標(biāo)志(1B)+命令編碼(1B)+UID(8B)+首塊序號(hào)(1B)+塊數(shù)量(1B)+CRC16(2B) |
| 22 2C 99 07 30 1A 53 01 04 E0 09 06 C5 AA | |
| 響應(yīng)(VICC TO VCD) | 標(biāo)志(1B)+塊安全狀態(tài)(nB)+CRC16(2B) |
| 00 00 00 00 00 00 00 00 73 83 |
與讀取多個(gè)塊的數(shù)據(jù)一樣,塊的編碼從 '00' 到 'FF' (0 到 255)。請求中塊的數(shù)量比塊安全狀態(tài)的數(shù)量少 1,VICC 將在其響應(yīng)中返回塊安全狀態(tài)。例如:在“塊數(shù)量”域中,值 '06' 要求返回 7 個(gè)塊安全狀態(tài)。在“塊數(shù)量”域中,值 '00' 要求返回單個(gè)塊安全狀態(tài)。
定制的命令
NXP、TI、ST等廠商對于定制命令的支持各不相同。
上述是幾個(gè)有代表性的標(biāo)簽系列,還有一些國產(chǎn)標(biāo)簽也會(huì)兼容上述標(biāo)簽,比如復(fù)旦微電子的FM13HF01兼容ICODE SLIX,[4] 因此也會(huì)兼容其定制的命令。EAS(Electronic Article Surveillance,電子防盜系統(tǒng))是 RFID 的常見應(yīng)用,上述標(biāo)簽系列只有ICODE SLIX支持 EAS。以下是 EAS 相關(guān)的命令。
開啟EAS(SET EAS=0xA2)
命令用來在 EAS 未鎖定的情況下開啟EAS模式。如果啟用了 EAS 密碼保護(hù),首先需要通過 SET PASSWORD 命令把 EAS 密碼傳輸?shù)?VICC上。
| 請求(VCD TO VICC) | 標(biāo)志(1B)+命令編碼(1B)+ IC Mfg code(1B)+UID(8B)+CRC16(2B) |
| 22 A2 04 99 07 30 1A 53 01 04 E0 44 C1 | |
| 響應(yīng)(VICC TO VCD) | 標(biāo)志(1B)+CRC16(2B) |
| 00 78 F0 |
重置EAS(RESET EAS=0xA3)
命令用來在 EAS 未鎖定的情況下關(guān)閉EAS模式。如果啟用了 EAS 密碼保護(hù),首先需要通過 SET PASSWORD 命令把 EAS 密碼傳輸?shù)?VICC上。
| 請求(VCD TO VICC) | 標(biāo)志(1B)+命令編碼(1B)+ IC Mfg code(1B)+UID(8B)+CRC16(2B) |
| 22 A3 04 99 07 30 1A 53 01 04 E0 63 ED | |
| 響應(yīng)(VICC TO VCD) | 標(biāo)志(1B)+CRC16(2B) |
| 00 78 F0 |
鎖EAS(RESET EAS=0xA4)
命令用來鎖定EAS模式的當(dāng)前狀態(tài)和EAS ID,一旦鎖定就無法解鎖。如果啟用了 EAS 密碼保護(hù),首先需要通過 SET PASSWORD 命令把 EAS 密碼傳輸?shù)?VICC上。
| 請求(VCD TO VICC) | 標(biāo)志(1B)+命令編碼(1B)+ IC Mfg code(1B)+UID(8B)+CRC16(2B) |
| 22 A4 04 99 07 30 1A 53 01 04 E0 96 29 | |
| 響應(yīng)(VICC TO VCD) | 標(biāo)志(1B)+CRC16(2B) |
| 00 78 F0 |
EAS警報(bào)(EAS ALARM=0xA5)
如果開啟了 EAS 模式,執(zhí)行該命令后 VICC 會(huì)返回 EAS 序列,如果關(guān)閉了 EAS 模式,VICC 不做響應(yīng)。
| 請求(VCD TO VICC) | 標(biāo)志(1B)+命令編碼(1B)+廠商代碼(1B)+UID(8B)+CRC16(2B) |
| 22 A5 04 99 07 30 1A 53 01 04 E0 B1 05 | |
| 響應(yīng)(VICC TO VCD) | 標(biāo)志(1B)+ EAS 序列(32)+ CRC16(2B) |
| 00 2F B3 62 70 D5 A7 90 7F E8 B1 80 38 D2 81 49 76 82 DA 9A 86 6F AF 8B B0 F1 9C D1 12 A5 72 37 EF 50 85 |
CRC計(jì)算方法
ISO15693協(xié)議中的 CRC 校驗(yàn)沒有從常用的21個(gè)標(biāo)準(zhǔn)CRC參數(shù)模型[5]中選擇,而是使用下面的參數(shù)模型
| CRC 類型 | 長度 | 多項(xiàng)式 | 方向 | 預(yù)置 | 余數(shù) |
|---|---|---|---|---|---|
| ISO/IEC 13239 | 16 bits | X16 + X12 + X5 + 1 = 8408 | 向后 | FFFF | F0B8 |
代碼實(shí)現(xiàn)如下:
/// <summary>
/// Provide a calculation of CRC for ISO15693
/// The PN5180 module seems to have implemented crc and does not need to calculate when coding
/// </summary>
/// <param name="buffer">The buffer to process</param>
/// <param name="crc">The CRC, Must be a 2 bytes buffer</param>
public void CalculateCrcIso15693(ReadOnlySpan<byte> buffer, Span<byte> crc)
{
if (crc.Length != 2)
{
throw new ArgumentException($"The length of crc must be 2 bytes.", nameof(crc));
}
ushort polynomial = 0x8408;
ushort currentCrc = 0xFFFF;
// ISO15693-3.pdf
for (int i = 0; i < buffer.Length; i++)
{
currentCrc = (ushort)(currentCrc ^ buffer[i]);
for (int j = 0; j < 8; j++)
{
if ((currentCrc & 0x0001) != 0)
{
currentCrc = (ushort)((currentCrc >> 1) ^ polynomial);
}
else
{
currentCrc = (ushort)(currentCrc >> 1);
}
}
}
currentCrc = (ushort)~currentCrc;
crc[0] = (byte)(currentCrc & 0xFF);
crc[1] = (byte)((currentCrc >> 8) & 0xFF);
}




浙公網(wǎng)安備 33010602011771號(hào)