<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > C8051Fxxx程序丟失問題及預防措施分析

          C8051Fxxx程序丟失問題及預防措施分析

          作者: 時間:2012-07-29 來源:網(wǎng)絡 收藏

          1 單片機簡單介紹和Flash結構

          本文引用地址:http://www.ex-cimer.com/article/171115.htm

            系列器件是Silicon Labs推出的一個高速單片機系列。這款單片機是完全集成的混合信號片上系統(tǒng)型MCU 芯片,具有高速、流水線結構的8051 兼容的CIP51內(nèi)核;70%的指令的執(zhí)行時間為1個或2個系統(tǒng)時鐘周期;片上有豐富的片內(nèi)外設,根據(jù)型號的不同,包括ADC、DAC、UART、捕捉/比較模塊的可編程計數(shù)器/定時器陣列、SPI、SMBus等。

            單片機有大容量的Flash存儲器,用于代碼和非易失性數(shù)據(jù)存儲,可在系統(tǒng)編程。Flash的結構是以扇區(qū)為單位組織的(128 KB系列以1 024字節(jié)為1個扇區(qū),64 KB系列以512字節(jié)為1個扇區(qū))。非易失性Flash可以用來存儲系統(tǒng)的參數(shù),如軟件版本、生產(chǎn)日期等。Flash可以使用編程器擦寫,也可以在中使用MOVX指令來修改,從而使Flash 存儲器具有在系統(tǒng)重新編程能力,允許現(xiàn)場更新8051 固件。Flash的寫和擦除操作由硬件自動定時,以保證操作正確通過。C8051Fxxx的Flash保存下載的程序,在系統(tǒng)上電后,單片機從Flash讀出代碼數(shù)據(jù)到RAM,之后程序開始運行。

          2 程序的出現(xiàn)和原因

            在一些實際應用中,系統(tǒng)重新上電后會出現(xiàn)程序不能正常運行的,常表現(xiàn)為“程序”。通常是由于程序代碼被損壞或被修改造成的。

            造成程序的原因很多,可以歸結到一個基本原因,即對Flash的訪問失敗而造成Flash保存的代碼出現(xiàn)錯誤。對于所有包含有Flash寫/擦除子程序的系統(tǒng),當CPU工作在規(guī)定的VDD、溫度、系統(tǒng)時鐘頻率范圍之外時,對Flash進行寫/擦除操作,都有可能出現(xiàn)Flash數(shù)據(jù)錯誤的現(xiàn)象。

          2.1 Flash數(shù)據(jù)錯誤的硬件原因

            C8051Fxxx單片機的Flash操作由硬件控制,所以硬件上的不穩(wěn)定可能造成Flash操作錯誤。硬件原因主要是能影響CPU正常運行的因素,以及能影響Flash操作環(huán)境的因素。這些因素包括操作電壓、溫度以及外部干擾脈沖等,具體如下:

           ?、?能影響CPU運行可靠性的參數(shù)有系統(tǒng)時鐘源。如果系統(tǒng)時鐘由外部晶振提供,外部的電磁干擾引起尖脈沖,并耦合到系統(tǒng)時鐘上,則會導致不可預知的操作。
           ?、?系統(tǒng)在單片機的工作電壓沒有穩(wěn)定(VDD上升時間低于規(guī)定的1 ms)時就已經(jīng)完成復位,由于系統(tǒng)復位時需要從Flash讀出代碼數(shù)據(jù),F(xiàn)lash電壓不穩(wěn)定會出現(xiàn)不可預測的錯誤。
           ?、?在對Flash的操作過程中,如果溫度、電壓不穩(wěn)定,也可能造成Flash數(shù)據(jù)錯誤。

          2.2 Flash數(shù)據(jù)錯誤的軟件原因

            代碼設計的缺陷是程序丟失的主要原因,因為單片機的Flash是由硬件來控制的,不能由軟件來控制操作的細節(jié),所以程序的不完善可能造成Flash的訪問出錯,從而使Flash數(shù)據(jù)出現(xiàn)錯誤。 這些操作包括: 在PSWE位(PSCTL.0)置1時CPU執(zhí)行中斷服務程序中的MOVX寫操作,該中斷服務程序要使用xdata 或pdata 的易失性存儲區(qū)單元,這樣可能導致向xdata 或pdata存儲區(qū)寫的數(shù)據(jù)寫到Flash中了,從而出現(xiàn)問題。另外,如果使用外部晶振作系統(tǒng)時鐘,在時鐘沒有穩(wěn)定時就對Flash進行寫操作,也可能造成程序丟失。

          3 程序丟失問題的解決方法

            針對以上可能的原因,可以從軟硬件兩個方面來解決程序丟失問題。在硬件方面,主要是給系統(tǒng)提供穩(wěn)定的工作環(huán)境,并避免外部干擾對CPU運行環(huán)境的影響;在軟件方面,主要是規(guī)范對Flash的操作。

          3.1 從硬件方面預防程序丟失

            注意,以下的方法不是對所有的器件都適用,要根據(jù)具體的硬件情況選擇相應的方法:

           ?、?在RST引腳安裝VDD監(jiān)測電路,并將VDD監(jiān)視設置為一個復位源(置RSTSRC.1為1)。這樣如果系統(tǒng)電壓不穩(wěn)定,系統(tǒng)將自動復位,從而避免在電壓不穩(wěn)時訪問Flash。
           ?、?對外部晶振時鐘2分頻,更好的方法是使用內(nèi)部振蕩器,這樣能提高系統(tǒng)時鐘的抗干擾能力。
           ?、?如果使用外部晶振提供系統(tǒng)時鐘,信號線應盡量靠近單片機的輸入端,同時晶振外殼接地。
           ?、?對于使用外部晶振作時鐘源的系統(tǒng),應盡量增強晶振的驅動能力,這樣也能在一定程度上預防程序丟失。

          3.2 從軟件方面預防程序丟失

            程序丟失的主要原因是程序設計的缺陷,所以合理的程序代碼設計能極大地預防該問題的出現(xiàn)。在代碼中可以用多種方法來預防Flash數(shù)據(jù)丟失:

           ?、?在PSWE=1下禁止中斷,使得程序中的MOVX寫指令是對Flash而不是對XRAM。
            ② 在PSWE=1下盡可能少地訪問變量。在PSWE=0下執(zhí)行地址譯碼操作,并用間接尋址方式執(zhí)行MOVX寫操作。例如,向Flash寫多個字節(jié),間接尋址和寫PSWE過程如下:

            unsigned char xdata * idata pwrite;//使用idata指針指向Flash
            unsigned char *source;
            unsigned char mydata;
            for (addr = 0; addr 100; addr++) {
              //PSWE =0時獲取要寫入的數(shù)據(jù)
              mydata = *source++;
              //PSWE =0時修改寫入數(shù)據(jù)的目標地址
              pwrite = (unsigned char xdata *) addr;
              PSCTL = 0x01;//PSWE=1
              //賦值方式寫入數(shù)據(jù),此時不執(zhí)行目標地址的修改操作
              *pwrite = mydata;
              PSCTL = 0x00;//PSWE=0
            }

            以上代碼中,當PSWE = 1時只執(zhí)行寫Flash操作(*pwrite = mydata);其他操作,如修改addr的值、獲取源數(shù)據(jù)和目的地址,都是在PSWE = 0時執(zhí)行的。


          上一頁 1 2 下一頁

          評論


          相關推薦

          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();