題:
dsPIC上的EEPROM讀/寫錯誤
Stephen Collings
2012-08-06 18:14:46 UTC
view on stackexchange narkive permalink

我正在運行Microchip dsPIC30F6012a。我在多個PCB上都裝有該芯片,它們都運行相同的軟件,並且在所有PCB上都觀察到相同的問題。這意味著系統性問題,而不是一次性生產問題。這個問題也是可以重現的,這意味著如果我知道在哪裡看,我應該可以殺死它。但是我仍然很難調試應用程序。

被測板接受24V電壓,通過V7805將其降至5V。該芯片在帶有16x PLL的內部振盪器上運行,運行速度約為29.5 MIPS。該板上的相關代碼本質上非常簡單:喚醒,從EEPROM讀取數據,然後進入無限循環。每毫秒中斷一次,觀察一些環境數據,並將更新的值寫入EEPROM。還有其他事情,但是即使不相關的代碼被註釋掉,問題仍然會發生,因此我可以肯定地確定它與手頭的問題無關。

通常,95%的董事會以正確的內存值喚醒後,繼續其業務。但是,其他5%的時間會以錯誤的值喚醒。具體來說,它會以本應具有的數據的位翻轉版本喚醒。我正在看的是一個四字節的無符號長整數,長整數的高位或低位字都可能被翻轉。例如,10變成2 ^ 16-10,後來變成2 ^ 32-10。我可以通過手動重啟幾次電源來重現毛刺,但這不是很一致,而且我的開關手指已磨損。 >

為了以受控方式重現該問題,我構建了第二塊板,該板驅動被測板的24V電源。 (另一個dsPIC驅動達林頓光電耦合器。)測試板將24V關斷1.5秒(足夠長,以使5V電源軌降到基本為0並停留在那裡一秒鐘),然後將24V開通一段可配置的時間長度。憑藉大約520 mS的接通時間,我每次都能在五個電源週期內重現此EEPROM毛刺。

5V供電軌表現合理。假設我可以相信我的示波器,它會在開機1 ms內穩定在5V,可能會有0.4V的過衝。關斷時,它以指數形式衰減至0V,在50 mS內達到1V。我沒有看似相關的構建警告,只是未使用的變量和文件末尾缺少換行符。

我已經嘗試了幾件事:

  • 啟用/禁用MCLR
  • 啟用/禁用WDT
  • 啟用/禁用代碼保護
  • 啟用/禁用/更改掉電檢測電壓
  • 啟用/禁用/更改上電計時器
  • 主內部振盪器上的不同PLL設置
  • 連接/斷開PICkit 3編程器
  • 為5V添加470uF電容rail
  • 在我的MCLR引腳上的4.7k上拉電阻上添加/移除.1 uF
  • 禁用代碼中的所有中斷,並且在主循環中僅保留EEPROM更新
  • 在我開始讀取EEPROM之前,我的啟動例程中增加了1.5秒的延遲

我還編寫了單獨的測試代碼,該代碼除了繼續將值寫入EEPROM並隨後將其讀回外,什麼也不做,請確保該值未更改。數以萬計的迭代沒有出錯。我只能得出的結論是,EEPROM讀取或寫入出現問題,特別是在上電/掉電時。

自2007年以來,我一直在使用相同的EEPROM庫。我偶爾看到故障,但沒有可重複的內容。相關代碼可以在這裡找到:
http://srange.net/code/eeprom.c
http://srange.net/code/readEEByte .s
http://srange.net/code/eraseEEWord.s
http://srange.net/code/writeEEWord.s

我以前在其他應用程序中曾見過EEPROM錯誤,但始終是一次過的小故障,沒有這種可重現或一致的結果。

任何人都有知道發生了什麼嗎?我沒辦法嘗試了。

請參閱此處以獲取有關解決此問題的更新:http://electronics.stackexchange.com/questions/38083/unable-to-use-compiler-built-in-functions-to-write-to-dspic-eeprom
三 答案:
Olin Lathrop
2012-08-06 19:12:29 UTC
view on stackexchange narkive permalink

您已經研究了許多可能的硬件問題。沒關係,但這很可能是固件錯誤。

不幸的是,您的源代碼文檔編寫得很差,而且格式難以視覺化。第一個文件在頂部包含外部例程的聲明:

 void readEEByte(unsigned int,unsigned int,void *); void deleteEEWord(unsigned int,unsigned int); void writeEEWord(unsigned int,unsigned int) ,void *); 

將這樣的聲明放在客戶端模塊中不僅是個壞主意,而且看不到任何註釋!我們只能從它們的名稱中猜出這些例程打算做什麼,並且調用參數是完全未記錄的。此外,在該文件中,您具有以“ //”開頭的各行以及等號的整行。這些增加了視覺上的混亂,使嘗試遵循該代碼變得非常麻煩。

您可能會說,這與代碼的操作無關。但是,像這樣的不良編程習慣確實很重要。它們導致代碼編寫不當,使發現錯誤甚至代碼應該執行的工作變得困難。所有這些都會導致您難以發現所發現的問題。您甚至說自己,自2007年以來,您偶爾會看到該代碼的故障。這應該是錯誤的有力線索,甚至可能是整體設計不佳的原因。

修復混亂情況,正確記錄所有接口,並將公共聲明放入您一次編寫的包含文件中,然後在需要時進行引用。同樣,您對我沒有看似相關的構建警告 i>的聲明也是一個巨大的危險信號。再次,修復混亂。調試時,請務必先解決容易複製和修復的問題。有時,這些實際上是造成棘手問題的原因,或者有時,在解決這些問題時,您會發現其他問題的原因。編譯器警告您銀盤鬆懈。您還想要什麼?您不應該使用未使用的變量,因為它們會使任何試圖理解您的代碼的人感到困惑,並且根本沒有藉口丟失新行。再次,修復它們明顯的混亂,尤其是在要求其他人查看您的代碼之前。

整潔並註意細節問題 b>。很多

您對代碼非常正確。可以這樣說,我們很清楚,我是在五年前開始使用此代碼的,但其他人已經編寫了它。我不會寫類似這樣的東西。我仍然應該修復它,但是我沒有修復。只是為了讓我看起來不像Q個子那麼大。 :-)
訪問內部EEPROM很容易。對於這種簡單的東西,編寫自己的代碼比嘗試弄清楚別人的錯誤軟件的工作方式然後將其修補直到看起來可行要容易得多。閱讀數據表並編寫代碼。一個小時之內就可以完成。
我在這裡同意Olin的觀點,因為它很可能是固件。勘誤表(http://ww1.microchip.com/downloads/en/DeviceDoc/80457C.pdf)提到EEPROM毫無意義。
@Madmad-勘誤表可能不會說零件有些腥,但他們永遠不會說它沒什麼腥:-)
@Remiel:技術支持可能不想比我更麻煩地使用混亂且文檔記錄薄的代碼。當您做一個草率的演講時,討論(如果有的話)就變成了草率,您的原始觀點被劫持了。即使您最終修復它,也很難恢復,因為那時人們已經將您淘汰了。同樣,爭論芯片是否有故障也不會幫助您發現錯誤,也不會採取任何措施使人們認真對待您。
@stevenvh我與Microchip及其FAE的往來大多是積極的。我一直在使用的零件的勘誤表準確無誤,它們可以幫助我們解決問題,經常為我們找到解決方法。
hli
2012-09-13 01:10:51 UTC
view on stackexchange narkive permalink

我想到兩件事:

首先,根據數據手冊,擦除-寫入周期至少需要0.8ms,最多需要2.6ms。您說您每隔1毫秒就有一個中斷,這可能會導致寫操作。我在代碼中看到,您禁用了部分擦除和部分寫入功能的中斷。但是您仍然可能對函數調用進行有趣的交織。

第二個-您可能想在斷電時進行寫操作,而EEPROM的寫操作恰好在電源電壓下降的那一刻發生低於工作電壓。您可以嘗試監視電源電壓,並在低於4.5V時拒絕寫入。假定它在2.7V(最低工作電壓)以上保持足夠長的時間,並且欠壓檢測設置為僅在該點以下觸發。

你近了!週期為擦除->寫入,因此如果在擦除和寫入之間斷電,則會丟失數據。我的第一個解決方案是將EEPROM分成多個冗余副本,這些副本將自動檢查是否存在不一致。但是由於那隻佔了我EEPROM的3/4,所以我用一個簡單的寫緩衝區代替了它。緩衝區將是一個特殊的EEPROM塊,其中包含要寫入的數據,要寫入的地址以及指示寫入尚未完成的標誌。這樣可以解決問題,同時佔用更少的空間。
現在,我可以確認我的基於緩衝區的方法有效,並且不會由於擦除和寫入之間的異步掉電而遭受數據丟失。
Angelo
2012-09-12 21:16:33 UTC
view on stackexchange narkive permalink

我在4個dsPIC30F6014A上有相同的行為(在過去幾個月中使用了大約10個。),唯一避免電源關閉期間偶發數據損壞的方法是在關機前將MCLR設置為零。

顯然,這在實踐中是不可行的,因此,如果有人有其他解決方案,我選擇了替換“錯誤的” dsPIC ...

為什麼那不可行?即使在最後一個毫秒將數據保存到EEPROM中,也要進行很多次斷電檢測。


該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 3.0許可。
Loading...