1? C8051Fxxx單片機簡單介紹和Flash結構
C8051Fxxx系列器件是Silicon Labs推出的一個高速單片機系列。這款單片機是完全集成的混合信號片上系統型MCU 芯片,具有高速、流水線結構的8051 兼容的CIP51內核;70%的指令的執行時間為1個或2個系統時鐘周期;片上有豐富的片內外設,根據型號的不同,包括ADC、DAC、UART、捕捉/比較模塊的可編程計數器/定時器陣列、SPI、SMBus等。
C8051Fxxx單片機有大容量的Flash存儲器,用于程序代碼和非易失性數據存儲,可在系統編程。Flash的結構是以扇區為單位組織的(128 KB系列以1 024字節為1個扇區,64 KB系列以512字節為1個扇區)。非易失性Flash可以用來存儲系統的參數,如軟件版本、生產日期等。Flash可以使用編程器擦寫,也可以在程序中使用MOVX指令來修改,從而使Flash 存儲器具有在系統重新編程能力,允許現場更新8051 固件程序。Flash的寫和擦除操作由硬件自動定時,以保證操作正確通過。C8051Fxxx的Flash保存下載的程序,在系統上電后,單片機從Flash讀出代碼數據到RAM,之后程序開始運行。
2? 程序丟失問題的出現和原因
在一些實際應用中,系統重新上電后會出現程序不能正常運行的問題,常表現為“程序丟失”。通常是由于程序代碼被損壞或被修改造成的。
造成程序丟失問題的原因很多,可以歸結到一個基本原因,即對Flash的訪問失敗而造成Flash保存的代碼出現錯誤。對于所有包含有Flash寫/擦除子程序的系統,當CPU工作在規定的VDD、溫度、系統時鐘頻率范圍之外時,對Flash進行寫/擦除操作,都有可能出現Flash數據錯誤的現象。
2.1? Flash數據錯誤的硬件原因
C8051Fxxx單片機的Flash操作由硬件控制,所以硬件上的不穩定可能造成Flash操作錯誤。硬件原因主要是能影響CPU正常運行的因素,以及能影響Flash操作環境的因素。這些因素包括操作電壓、溫度以及外部干擾脈沖等,具體如下:
①? 能影響CPU運行可靠性的參數有系統時鐘源。如果系統時鐘由外部晶振提供,外部的電磁干擾引起尖脈沖,并耦合到系統時鐘上,則會導致不可預知的操作。
② ?系統在單片機的工作電壓沒有穩定(VDD上升時間低于規定的1 ms)時就已經完成復位,由于系統復位時需要從Flash讀出代碼數據,Flash電壓不穩定會出現不可預測的錯誤。
③? 在對Flash的操作過程中,如果溫度、電壓不穩定,也可能造成Flash數據錯誤。
2.2? Flash數據錯誤的軟件原因
代碼設計的缺陷是程序丟失的主要原因,因為單片機的Flash是由硬件來控制的,不能由軟件來控制操作的細節,所以程序的不完善可能造成Flash的訪問出錯,從而使Flash數據出現錯誤。 這些操作包括: 在PSWE位(PSCTL.0)置1時CPU執行中斷服務程序中的MOVX寫操作,該中斷服務程序要使用xdata 或pdata 的易失性存儲區單元,這樣可能導致向xdata 或pdata存儲區寫的數據寫到Flash中了,從而出現問題。另外,如果使用外部晶振作系統時鐘,在時鐘沒有穩定時就對Flash進行寫操作,也可能造成程序丟失。
3? 程序丟失問題的解決方法
針對以上可能的原因,可以從軟硬件兩個方面來解決程序丟失問題。在硬件方面,主要是給系統提供穩定的工作環境,并避免外部干擾對CPU運行環境的影響;在軟件方面,主要是規范對Flash的操作。
3.1? 從硬件方面預防程序丟失
注意,以下的方法不是對所有的器件都適用,要根據具體的硬件情況選擇相應的方法:
① ?在RST引腳安裝VDD監測電路,并將VDD監視設置為一個復位源(置RSTSRC.1為1)。這樣如果系統電壓不穩定,系統將自動復位,從而避免在電壓不穩時訪問Flash。
② ?對外部晶振時鐘2分頻,更好的方法是使用內部振蕩器,這樣能提高系統時鐘的抗干擾能力。
③? 如果使用外部晶振提供系統時鐘,信號線應盡量靠近單片機的輸入端,同時晶振外殼接地。
④? 對于使用外部晶振作時鐘源的系統,應盡量增強晶振的驅動能力,這樣也能在一定程度上預防程序丟失。
3.2? 從軟件方面預防程序丟失
程序丟失的主要原因是程序設計的缺陷,所以合理的程序代碼設計能極大地預防該問題的出現。在代碼中可以用多種方法來預防Flash數據丟失:
① ?在PSWE=1下禁止中斷,使得程序中的MOVX寫指令是對Flash而不是對XRAM。
②? 在PSWE=1下盡可能少地訪問變量。在PSWE=0下執行地址譯碼操作,并用間接尋址方式執行MOVX寫操作。例如,向Flash寫多個字節,間接尋址和寫PSWE過程如下:
unsigned char xdata * idata pwrite;//使用idata指針指向Flash
unsigned char *source;
unsigned char mydata;
for (addr = 0; addr < 100; addr++) {
//PSWE =0時獲取要寫入的數據
mydata = *source++;
//PSWE =0時修改寫入數據的目標地址
pwrite = (unsigned char xdata *) addr;
PSCTL = 0x01;//PSWE=1
//賦值方式寫入數據,此時不執行目標地址的修改操作
*pwrite = mydata;
PSCTL = 0x00;//PSWE=0
}
以上代碼中,當PSWE = 1時只執行寫Flash操作(*pwrite = mydata);其他操作,如修改addr的值、獲取源數據和目的地址,都是在PSWE = 0時執行的。
③? 將Flash寫/擦除指針指向data或idata區。
④? 減少將PSWE置1的指令操作。理想的情況是只有兩個操作將PSWE置1,即寫1個Flash字節和擦除1個Flash字節。
⑤? 在Flash寫/擦除函數中,使能VDD監視并設置復位源。使能和設置操作必須在實際的寫操作發生之前,置PSWE=1之后完成。
⑥? 代碼中所有的對RSTSRC的寫操作均用直接賦值方式完成(如RSTSRC = 0x02),不能用讀/寫指令(如ORL或ANL)來完成。例如,代碼“RSTSRC |= 0x02”是非法的。
⑦? 對于能用PORSF位來設置VDD為復位源的器件,保證在寫RSTSRC時置PORSF=1,即先使能VDD為復位源,再使能其他復位源的操作,如時鐘丟失監測(missing clock detector)、比較單元和軟件復位。
4? 一個實際應用方案
在有的應用場合,由于需要較快的執行速度,不能使用單片機的內部時鐘作系統時鐘源,所以使用外部晶振來提供時鐘。在這種情況下,首先要在硬件上確保系統工作參數正常。
在軟件上,由于最常見的Flash丟失原因是程序問題,所以可以在代碼中用多種方法來預防Flash數據丟失。首先,在初始化單片機時,使能VDD檢測,并設置VDD和時鐘丟失為復位源。如果程序中有寫/擦除Flash的代碼,則在寫/擦除操作前切換系統時鐘,將系統時鐘切到內部時鐘或對外部時鐘2分頻;寫/擦除操作完成之后,再恢復系統時鐘,通過增加Flash修改操作時的時間開銷來實現系統的穩定[2]。以下以C8051F126為例,給出了系統時鐘切換的程序清單:
void SYSCLKAdjust(unsigned char select) {
EA_Save=EA;
SFRPAGE=0x0f;
switch(select) {
case 0x01:
OSCICN_Save = OSCICN;
CLKSEL_Save = CLKSEL;
OSCICN = 0xc3;//內部時鐘,不分頻
CLKSEL = 0x00;
break;
case 0x02:
OSCXCN_Save = OSCXCN;
OSCXCN |= 0x70;//外部時鐘2分頻
break;
default://選擇內部時鐘
OSCICN_Save = OSCICN;
CLKSEL_Save = CLKSEL;
OSCICN = 0xc3;
CLKSEL = 0x00;
break;
}
}
要恢復系統時鐘到Flash操作前的狀態,只需將CLKSEL_Save、OSCICN_Save、OSCXCN_Save重新寫回到CLKSEL、OSCIN、OSCXCN。
C8051F126的系統時鐘(SYSCLK)可以在內部時鐘和外部時鐘之間自由切換,切換時的操作要求如下:
① ?在切換過程中,先設置所選時鐘的屬性,再用CLKSEL將其設置為SYSCLK。
② ?在還原過程中,先用CLKSEL選擇時鐘源,再設置其屬性。
③? 如果切換過程中關閉外部晶振,要再恢復外部時鐘,啟動后至少要等1 ms,再去讀XTLVLD(OSCXCN.7)來判斷晶振時鐘是否穩定。否則,可能讀到錯誤值。
④ ?在外部時鐘穩定運行后,再對其分頻,不必插入等待周期。
⑤? 在切換過程中,可以保持外部時鐘繼續運行,這樣在還原過程中就不必等待外部時鐘穩定,從而節省時間開銷,代價是系統功耗有所增加。
5? 總結
程序丟失會帶來各種不良的后果,最嚴重時致使程序無法正常運行,從而造成整個系統崩潰,給產品的應用帶來麻煩。在系統的硬件設計和代碼編寫過程中,通過對以上問題的注意,可以有效地防止程序丟失問題的出現。另外,由于系統時鐘的切換只發生在Flash的寫/擦除過程中,操作結束后又恢復成原來的設置,因而對系統運行速度的影響很小,從而保證了系統其他功能的實現。?
評論
查看更多