MAX14915為高性能、8通道、工業高邊開關,具有豐富、先進的功能集。SPI接口允許微控制器監視和控制MAX14915的大部分方面。為了增強魯棒性,MAX14915中的硬件循環冗余校驗(CRC)電路可以選擇保護其與微控制器之間的所有數據通信,防止誤碼。然而,在MAX14915中啟用CRC功能是不夠的。微控制器還必須在軟件中實現相同的CRC算法,既要為發送到MAX14915的數據附加校驗位,又要驗證從MAX14915接收的數據。實現此目的的一種方法是檢查數據手冊并使用它來創建自定義固件以實現必要的CRC功能。為了提供更快且經過驗證的解決方案,本應用筆記中提供了一系列功能。它們是用C語言編寫的,應該很容易移植到任何常見的微控制器上。
串行接口上的CRC錯誤檢測
MAX14915串行數據的CRC錯誤檢測可以啟用,以盡量減少由于SDI和SDO信號的數據損壞而導致的錯誤操作或錯誤信息。如果使能錯誤檢測,通過設置CRCEN引腳= 1,MAX14915執行以下操作:
對從微控制器接收的SDI數據執行錯誤檢測,以及
計算發送到微控制器的SDO數據的CRC,并將校驗字節附加到發送到微控制器的SDO診斷/狀態數據
這可確保從微控制器接收的數據(設置/配置)和發送到微控制器的數據(診斷/狀態)出現未檢測到錯誤的可能性較低。
CRC 錯誤檢測支持SPI尋址和菊花鏈操作模式,以及標準和突發讀/寫周期。
SDI(讀取周期)上的輸入數據
將 CRCEN 輸入設置為高電平可啟用 CRC 錯誤檢測。CRC 幀校驗序列 (FCS) 隨每個串行事務一起發送。5 位 FCS 基于生成器多項式 X5+ X4+ X2+ 1,CRC 起始值 = 11111。當CRC使能時,MAX14915期望在接收的SDI程序/配置數據后附加一個校驗字節。圖 1 顯示了校驗字節格式。
圖1.微控制器的SDI檢查字節。
5位FCS位CRC[4:0]是根據一個SPI命令中發送的所有數據計算的,包括校驗字節MSB中的三個“0”。因此,在突發命令的情況下,CRC 的計算范圍為 8+3 位到 24+3 位。CRC0是FCS的LSB。
MAX14915驗證接收到的FCS位,如果未檢測到錯誤,MAX14915設置OUT_輸出開關和/或根據SDI數據更改器件配置。如果檢測到CRC錯誤,MAX14915不會改變OUT_輸出和/或器件配置。相反,MAX14915將COMERR邏輯輸出設置為低電平,即COMERR輸出晶體管漏極開路導通。
如果掩模寄存器設置為使能全局故障寄存器中的CRCfault位,MAX14915還將FAULT引腳設置為低電平,為微控制器提供中斷,以進一步指示SPI接口上的通信錯誤。
SDO(寫入周期)上的輸出數據
當DAISY引腳為低電平時,MAX14915附加到SDO數據的檢查字節的格式如圖2所示:
圖2.MAX14915在尋址SPI模式下發送SDO檢查字節。
A1 和 A0 是 A1 和 A0 引腳的電平,而 THERR 位是在發生芯片熱關斷事件時設置的。CRC[4:0]是MAX14915根據SDO數據計算的1個CRC位,包括A0、A14915和THERR值。這允許微控制器檢查從MAX<>接收的SDO數據是否存在錯誤。
源代碼
本應用筆記提供了實現CRC生成器和CRC檢查器的C源代碼。MAX14915使用單字節或雙字節包與微控制器通信。源代碼為每種情況提供了一個編碼器和解碼器:
CRC5encode_2byte(用于傳輸 2 個字節)
CRC5encode_1byte(用于傳輸 1 字節)
CRC5check_2byte(用于檢查MAX2的14915字節響應)
CRC5check_1byte(用于檢查MAX1的14915字節響應)
除了選擇單字節或雙字節數據包與MAX14915通信外,請注意,在這些代碼示例中,“byte”是8位無符號值的別名,有時以不同的方式標記,例如UINT8。
Send1為第一個字節,send2為第二個字節,發送至MAX14915。代碼應先發送1,后發送2,再crc_code至MAX14915。
crc_code = crc5encode (send1, send2);
用戶應通過SPI接口發送3個字節,先發送1,后跟send2,然后發送crc_code。當微控制器通過SPI接口將配置設置發送到MAX14915時,MAX14915同時將狀態信息返回給微控制器。這是檢查從MAX14915接收的crc_code是否正確的方法:
crc_ret = crc5decode (ret1, ret2);
字節結果“crc_ret”應與MAX14915接收的第三個字節相同。
圖 3 和圖 4 顯示了 C 函數注釋中提到的數據位置。下載電子表格
圖3.CRC5數據發送到SDI上的MAX14915。
圖4.MAX5在SDO上發送的CRC14915數據。
public byte crc5encode(byte BYTE1, byte BYTE2)
{
byte crc5_start = 0x1f;
byte crc5_poly = 0x15;
byte crc_result = crc5_start;
// BYTE1
for (int i=0; i<8; i++)
{
if( ((( BYTE1>>(7-i) ) &0x01) ^ ((crc_result & 0x10)>>4)) > 0 ) // IF(XOR(C6;BITAND(D5;2^4)/2^4)
{ crc_result = (byte) (crc5_poly ^ ((crc_result<<1) & 0x1f)); } // BITXOR($D$1;BITAND((D5*2);31))
else
{ crc_result = (byte)((crc_result<<1) & 0x1f); } // shift left, keep only lower 6 bits
}
// BYTE2
for (int i=0; i<8; i++)
{
if( ((( BYTE2>>(7-i) ) &0x01) ^ ((crc_result & 0x10)>>4)) > 0 ) // IF(XOR(C6;BITAND(D5;2^4)/2^4)
{ crc_result = (byte) (crc5_poly ^ ((crc_result<<1) & 0x1f)); } // BITXOR($D$1;BITAND((D5*2);31))
else
{ crc_result = (byte)((crc_result<<1) & 0x1f); } // shift left, keep only lower 6 bits
}
// 3 extra bits set to zero
byte BYTE3=0x00;
for (int i=0; i<3; i++)
{
if( ((( BYTE3>>(7-i) ) &0x01) ^ ((crc_result & 0x10)>>4)) > 0 ) // IF(XOR(C6;BITAND(D5;2^4)/2^4)
{ crc_result = (byte) (crc5_poly ^ ((crc_result<<1) & 0x1f)); } // BITXOR($D$1;BITAND((D5*2);31))
else
{ crc_result = (byte)((crc_result<<1) & 0x1f)); } // shift left, keep only lower 6 bits
}
return crc_result;
}
byte crc5_decode(byte BYTE1, byte BYTE2)
{
byte crc5_start = 0x1f;
byte crc5_poly = 0x15;
byte crc_result = crc5_start;
// BYTE1
for (int i=2; i<8; i++)
{
if( ((( BYTE1>>(7-i) ) &0x01) ^ ((crc_result & 0x10)>>4)) > 0 ) // IF(XOR(C6;BITAND(D5;2^4)/2^4)
{ crc_result = (byte) (crc5_poly ^ ((crc_result<<1) & 0x1f)); } // BITXOR($D$1;BITAND((D5*2);31))
else
{ crc_result = (byte)((crc_result<<1) & 0x1f); } // shift left, keep only lower 6 bits
}
// BYTE2
for (int i=0; i<8; i++)
{
if( ((( BYTE2>>(7-i) ) &0x01) ^ ((crc_result & 0x10)>>4)) > 0 ) // IF(XOR(C6;BITAND(D5;2^4)/2^4)
{ crc_result = (byte) (crc5_poly ^ ((crc_result<<1) & 0x1f)); } // BITXOR($D$1;BITAND((D5*2);31))
else
{ crc_result = (byte)((crc_result<<1) & 0x1f); } // shift left, keep only lower 6 bits
}
// 3 extra bits set to zero
byte BYTE3=0x00;
for (int i=0; i<3; i++)
{
if( ((( BYTE3>>(7-i) ) &0x01) ^ ((crc_result & 0x10)>>4)) > 0 ) // IF(XOR(C6;BITAND(D5;2^4)/2^4)
{ crc_result = (byte) (crc5_poly ^ ((crc_result<<1) & 0x1f)); } // BITXOR($D$1;BITAND((D5*2);31))
else
{ crc_result = (byte)((crc_result<<1) & 0x1f); } // shift left, keep only lower 6 bits
}
return crc_result;
}
結論
本應用筆記介紹了如何在與MAX14915八通道工業高邊開關通信的微控制器上對CRC算法進行編碼。該代碼使用MAX14915EVKIT和相應的GUI進行測試。通過利用本應用筆記中的C代碼示例,工程師獲得了一個經過驗證的解決方案來實現這種額外的數據通信保護。在某些情況下,應在目標微控制器上執行一些基準測試,尤其是在優先考慮快速執行速度的情況下。
審核編輯:郭婷
-
微控制器
+關注
關注
48文章
7336瀏覽量
150107 -
控制器
+關注
關注
112文章
15885瀏覽量
175372 -
SPI
+關注
關注
17文章
1669瀏覽量
90733
發布評論請先 登錄
相關推薦
評論