アプリケーションノート 4600

簡単なソフトウェアによる1-Wire®温度測定デバイスのハードウェアCRC検証およびシリアルビットストリームの誤り検出

筆者: Hrishikesh Shinde

要約: すべての1-Wire温度測定デバイスには、読取り専用メモリ(ROM)内に固有のIDコードが含まれています。このIDコードは、1-Wireバス上での一意なネットワークアドレスとして使用されます。さらに、一部の温度測定デバイスのスクラッチパッドメモリには、1-Wire通信を検証するためのCRC (巡回冗長検査)バイトも含まれています。このアプリケーションノートおよび付随するソフトウェアは、1-Wireデバイス間における通信の成功の検証またはシリアルデータストリーム中の誤り検出のための簡単な方法を提供します。手順としては、DOW (Dallas One Wire) CRCの値をソフトウェアで計算して、その値と各デバイスに実装されたCRCハードウェアによるCRC値との検証を行います。デバイスの例としてEcono 1-WireディジタルサーモメータDS1822を使用します。

CRCアルゴリズム

CRC (巡回冗長検査)は、シリアルデータストリームにおける誤り検出のための最も効果的な方式です。CRCによって、ユーザは温度測定デバイス間の通信の成功を検証することができます。また、CRCはハードウェア要件も最小限で済みます。DOW (Dallas One Wire) CRCは、DS1821DS1822DS18B20などのマキシムの1-Wire温度測定製品で使用されています。このDOW CRCを表す多項式は、次の通りです。
Polynomial = X8 + X5 + X4 + 1
CRCアルゴリズムの詳細については、アプリケーションノート27 「マキシムのiButton製品に用いる巡回冗長検査(CRC)の理解と用法」を参照してください。

CRCを理解するには、この機能を実際にハードウェアで構築した場合を考えるのが最も簡単であり、通常はフィードバックを備えたシフトレジスタの構成として表されます。DS1822のハードウェアの構成を図1に示します。

図1. CRCのハードウェアによる表現
図1. CRCのハードウェアによる表現

ROMコードのCRC

個々のDS1822に、固有の8バイトのIDコードがROMに格納されています。ROMコードの最下位バイトには、DS1822の1-Wireファミリコードである22hが含まれています。次の6バイトには、固有のシリアル番号が含まれています。最上位バイトが、ROMコードの最初の7バイトから計算されたCRCバイトです。

スクラッチパッドのCRC

DS1822のスクラッチパッドの最初の8バイトには、高温、低温のスレッショルドおよびコンフィグレーションレジスタの値が含まれています。また、これらのバイトにはDS1822が読み取った温度値および予備レジスタも含まれます。9バイト目が、最初の8バイトから計算されたCRC値です。

アプリケーションノート27で説明されているように、CRCバイトの計算に使用されるCRCアルゴリズムはスクラッチパッドとROMの両方で同一です。図1のシフトレジスタは、ビット値がすべて0の初期条件から開始します。LSBから順番に1ビットずつ、入力データ全体がシフトインされます。すべてのビットがシフトインされた後の結果が、その特定のデータについて計算されたCRC値を表しています。合計で、ROMコードの場合は56ビット(7バイト)、スクラッチパッドの場合は64ビット(8バイト)がシフトインされます。

ハードウェアCRCの検証

DS1822は、ROMコードまたはスクラッチパッドに対するCRC値を提供するCRCハードウェアを内蔵しています。この情報が、その後1-Wireバス上で転送されます。受信したデータは、通信インタフェースによって破壊されている可能性があります。ソフトウェアで計算したCRCを使用することによって、受信したデータのパケット(ROMコードの場合は8バイト、スクラッチパッドの場合は9バイト)の正しさを検証することができます。

DS1822についてこのCRC値を計算するために、Microsoft® Excelのスプレッドシート(Microsoft Excel 2003を使用)を設計しました。スナップショットを次の図2に示します。

図2. ExcelによるCRC計算機のスナップショット
図2. ExcelによるCRC計算機のスナップショット

ユーザは、ROMコードの最後の7バイトまたはスクラッチパッドの最初の8バイトの値を入力します。「Calculate CRC」ボタンをクリックすることによって、対応するCRC値が計算されます。これらの値とハードウェアで計算された値とを照合して検証を行うことができます。

このExcelスプレッドシートの開発に使用したVBAのコードは次の通りです。


Private Sub ROMCRC_Click()
    
    Dim InHex, OutBinStr As String
    Dim OutBinArr(1 To 56) As Integer
    Dim OutDec, i, CRC(1 To 8), CRCTemp As Integer
    
    InHex = Range("ROMByte1").Value & Range("ROMByte2").Value &
      	Range("ROMByte3").Value & Range("ROMByte4").Value &
      	Range("ROMByte5").Value & Range("ROMByte6").Value &
      	Range("ROMByte7").Value
    OutBinStr = HexToBin(InHex)
    
    ' Convert string to array, LSB = OutBinArr(1)
    For i = 1 To 56
        OutBinArr(57 - i) = Mid$(OutBinStr, i, 1) ' Split(OutBinStr)
    Next i
    
    'Initialize CRC
    For i = 1 To 8
        CRC(i) = 0
    Next i
    
    'Calculate CRC
    For i = 1 To 56
        CRCTemp = CRC(1) Xor OutBinArr(i)
        CRC(1) = CRC(2)
        CRC(2) = CRC(3)
        CRC(3) = CRC(4) Xor CRCTemp
        CRC(4) = CRC(5) Xor CRCTemp
        CRC(5) = CRC(6)
        CRC(6) = CRC(7)
        CRC(7) = CRC(8)
        CRC(8) = CRCTemp
    Next i
    
    DecCRC = BinToDec(CRC)
    
    Range("ROMCRCValue").Value = DecCRC

End Sub


Private Sub ScratchCRC_Click() Dim InHex, OutBinStr As String Dim OutBinArr(1 To 64) As Integer Dim OutDec, i, CRC(1 To 8), CRCTemp As Integer InHex = Range("HexByte1").Value & Range("HexByte2").Value & Range("HexByte3").Value & Range("HexByte4").Value & Range("HexByte5").Value & Range("HexByte6").Value & Range("HexByte7").Value & Range("HexByte8").Value OutBinStr = HexToBin(InHex) ' Convert string to array, LSB = OutBinArr(1) For i = 1 To 64 OutBinArr(65 - i) = Mid$(OutBinStr, i, 1) ' Split(OutBinStr) Next i 'Initialize CRC For i = 1 To 8 CRC(i) = 0 Next i 'Calculate CRC For i = 1 To 64 CRCTemp = CRC(1) Xor OutBinArr(i) CRC(1) = CRC(2) CRC(2) = CRC(3) CRC(3) = CRC(4) Xor CRCTemp CRC(4) = CRC(5) Xor CRCTemp CRC(5) = CRC(6) CRC(6) = CRC(7) CRC(7) = CRC(8) CRC(8) = CRCTemp Next i DecCRC = BinToDec(CRC) Range("DecCRCValue").Value = DecCRC End Sub
Private Function HexToBin(hstr) 'convert hex string to binary string cnvarr = Array("0000", "0001", "0010", "0011", _ "0100", "0101", "0110", "0111", "1000", _ "1001", "1010", "1011", "1100", "1101", _ "1110", "1111") bstr = "" For i = 1 To Len(hstr) hdgt = Mid(hstr, i, 1) cix = CInt("&H" & hdgt) bstr = bstr & cnvarr(cix) Next HexToBin = bstr End Function
Function BinToDec(bstr) 'convert 8 bit Binary number to Decimal Dim j, Out As Integer Out = 0 For j = 1 To 8 Out = Out + bstr(j) * 2 ^ (j - 1) Next j BinToDec = Out End Function

結論

CRC値は、1-Wireデバイス間の通信の成功の確認を容易にします。ソフトウェアベースのCRCを1-WireデバイスのハードウェアCRCと組み合わせて使用することによって、1-Wire通信の検証を行うことができます。