來(lái)源:Digi-Key 作者:Jacob Beningo 這是最奇怪的問(wèn)題之一。該系統似乎在按預期工作,但遙測數據表明情況并非如此。決定電機轉速的“按需輸入”報告為 85%,但幸運的是,電機并沒(méi)有轉起來(lái)。我很想揮揮手說(shuō)這沒(méi)什么大不了的,或者說(shuō)這是遙測分析軟件的問(wèn)題,但有些地方不太對勁,F在應該好好研究一下了,進(jìn)行全系統檢查,找到問(wèn)題原因。 這個(gè)特殊的系統使用的是 Allegro Microsystems A4964 無(wú)刷直流 (BLDC) 電機驅動(dòng)芯片。我越來(lái)越喜歡這個(gè)芯片,因為它是一種靈活的電機驅動(dòng)解決方案,而且把所有可能占用 CPU 周期的控制代碼從微控制器 (MCU) 移走,由專(zhuān)門(mén)的硬件芯片執行(圖 1)。 ![]() 圖 1:A4964 很有用,因為它將無(wú)刷直流電機的控制功能從 MCU 遷移至專(zhuān)用硬件。(圖片來(lái)源:Allegro Microsystems) 在這個(gè)系統配置中,我利用 SPI 通信接口來(lái)設置 32 個(gè)片上寄存器,這些寄存器將決定 BLDC 電機的驅動(dòng)和控制方式。 對于該應用,A4964 在安裝過(guò)程中由初始化程序讀取包含所需電機配置參數的配置表完成其配置。偽碼(此處僅用于舉例)如下所示(列表 1)。 副本 for(uint8_t WriteIndex = 0; WriteIndex < A4964MaxRegister; WriteIndex++) { // Write value stored in A4964Config at index WriteIndex to the chip } 列表 1:所示為讀取電機配置參數的初始化程序。(代碼來(lái)源:Jacob Beningo) 從初始化角度來(lái)看,這段代碼沒(méi)有什么問(wèn)題,所以我很快決定檢查該應用中經(jīng)常被調用的主要邏輯。這段代碼有點(diǎn)兒意思。該應用所處的環(huán)境中存在大量輻射,這可能會(huì )影響 RAM 中存儲的值。初始化值在啟動(dòng)時(shí)被寫(xiě)入 A4964 的 RAM 中,所以為了迅速克服可能發(fā)生的“位翻轉”,A4964 的內存被定期讀。喝绻霈F不匹配,則會(huì )更新設置。偽代碼如下(列表 2): 副本 for(uint8_t Index = 0; Index < A4964MaxRegister; Index++) { // Read the A4964 configuration register at location Index // If read value does not match expected value, write configuration value } 列表 2:本地輻射可能會(huì )影響存儲在 RAM 中的值,因此為了應對“位翻轉”,A4964 的內存會(huì )被定期讀取,如果出現不匹配,則更新設置。(代碼來(lái)源:Jacob Beningo) 又出現類(lèi)似情況,代碼非常簡(jiǎn)單,不可能出錯,但芯片中莫名其妙地被寫(xiě)入了不正確的需求輸入值。這個(gè)值似乎是短暫存在的,在報告正確值之前,該值在一些遙測值中出現,然后又一次提供了錯誤的值。真令人費解! 更為有趣的是,沒(méi)有任何配置值或應用值可以將 85% 的值寫(xiě)入寄存器!那么,這個(gè) 85% 的值到底是從哪里來(lái)的呢?十進(jìn)制 85 轉換成十六進(jìn)制時(shí)為 0x55。在代碼庫中有出現 0x55 的地方嗎?當然有。0x55 被用作 SPI 總線(xiàn)上讀操作的虛設寫(xiě)字符!但是,讀操作是如何被轉換為寫(xiě)操作的呢? 事實(shí)證明,只要我們仔細觀(guān)察 A4964 的規格書(shū)(圖 2),答案就非常明顯。 ![]() 圖 2:數據手冊中的一個(gè)片段顯示了這個(gè)問(wèn)題。寄存器 30 的特點(diǎn)是只寫(xiě)。▓D片來(lái)源:Allegro Microsystems) 寄存器 30 管理電機的“按需輸入 (DI)”,是只寫(xiě)寄存器!嘗試從該寄存器中讀出數據,會(huì )導致向該寄存器中寫(xiě)入虛字節!簡(jiǎn)單的初始化和芯片刷新功能?chē)L試從“按需駛入”寄存器中讀取以驗證設置,并在無(wú)意中寫(xiě)入了一個(gè)新的“按需輸入”值。系統繼續按預期工作,因為對寫(xiě)寄存器的讀取操作總是導致隨后會(huì )寫(xiě)入正確的值,但并不總是足夠快,所以錯誤值沒(méi)有出現在系統遙測值中。 對于 A4964,軟件開(kāi)發(fā)者不應在整個(gè)內存圖中寫(xiě)入配置數據,而是需要在寫(xiě)入寄存器 29 之后停止。最后兩個(gè)可尋址的寄存器是特殊的寫(xiě)和只讀寄存器。 有時(shí),不管我們?yōu)檎_編寫(xiě)驅動(dòng)程序或實(shí)施軟件付出了多少努力,總會(huì )有一些奇奇怪怪的問(wèn)題。奇怪的問(wèn)題往往是一個(gè)學(xué)習有關(guān)硬件新知識的機會(huì ),而且總會(huì )形成新的最佳實(shí)踐。就是由于這個(gè)奇怪的問(wèn)題,我把“仔細觀(guān)察只讀/只寫(xiě)寄存器”添加到我的列表中,并確保我正確理解、使用這些寄存器。否則,讀取那個(gè)只寫(xiě)寄存器可能會(huì )給系統帶來(lái)生災難性后果。 |