摘 要:在單片機的應用中,逐步引入了高級語言,C語言就是其中一種。但是如果C語言應用不當很可能會引起單片機系統無法正常運行,重點介紹了利用C51作為編程語言在使用W77E58時,如果程序在定義全局變量或靜態變量時進行了初始化會對Watchdog的復位產生的影響及其解決方法。
關鍵詞:C51;Watchdog;W77E58
引言
W77E58是華邦公司設計的一片增強型MCS-51單片機,它的最高工作頻率40MHZ,指令系統采用4個機器周期,具有3個16位定時器,12個中斷,32KB flashEPROM程序空間,兩個UART串口等特性。尤其適用于對存儲器資源有一定要求和對軟件運行速度有特別要求的場合,目前在工業控制中得到了廣泛應用。單片機系統受干擾后,經常出現的問題是程序執行進入一種“跑飛”或“死機”狀態,為此,可以采用Watchdog技術保持系統的正常運行。在W77E58已經集成了一個用戶可編程的看門狗定成器,因此只要硬件接法正確,在軟件設計中調用相應語句即可啟動Watchdog。
C語言可以縮短開發周期,降低開發成本,而且開發出的系統易于維護、可靠性高、可移植性好,筆者編制程序使用的是C51。程序中開啟使用watchdog定時器后,發現當看門狗定時器溢出引起系統復位后系統無法重新
開始正常運行,即復位后程序運行到main()函數之前一直在不停的復位,經過詳細分析之后發現是由于在定義全局變量或靜態變量時進行變量初始化使得初始化程序執行時間長于看門狗設置的最長時間引起的。
W77E58Watchdog簡介
W77E58自帶有看門狗定時器,此定時器是一個獨立于CPU自行運行的定時器,系統可通過編程將其設置為系統監控器,時基發生器或事件定時器。該定時器基于一組分頻器,對系統時鐘頻率進行分割。分頻器輸出可選,并決定溢出時間。溢出時,如果看門狗有效(且看門狗定時器打開),將引起系統復位,系統復位將使“飛掉”的程序重新恢復運行,以達到提高程序運行的可靠性。看門狗溢出中斷以及看門狗復位可利用軟件進行設置,將兩者合并或分離(即看門狗定時器溢出并使系統復位以及看門狗定時器僅溢出而不引起系統復位)。
看門狗定時器先用RWT來啟動,這保證看門狗定時器從一個確定的狀態開始運行。RWT位用來啟動看門狗定時器。該位會自動清零,就是說在軟件向該位寫入1后,系統會自動把該位清為0。將RWT設為1后,看門狗定時器會對時鐘周期進行計數。超時時間由WDl和WD0位來決定(CKCON.7和CKCON.6)。超時時間到以后,WDIF位置位,之后看門狗定時器將等待512個時鐘周期,如果EWT=1且在等待期間沒有對RWT進行操作,那么512個時鐘周期以后會產生看門狗定時器復位。這個復位會連續兩個周期同時WTRF標志位置位,軟件可以用此來判斷是否是看門狗定時器復位。
表1給出了看門狗定時器的溢出值,對于不同的時鐘頻率,看門狗定時器就會產生不同的溢出時間。當使能看門狗定時器復位后,這個復位會在其溢出并經過512個時鐘周期后結束。看門狗定時器在上電或掉電復位后,看門狗定時器復位不會關閉看門狗定時器,但會將其重新啟動,軟件應重新啟動定時器把它放入一個確定的狀態。
CPU使用W77E58,主程序由C語言開發的系統,最初在設計編制Watchdog定時器程序時發現開啟Watchdog定時器后,當定時器溢出引起系統復位后系統無法重新開始正常運行,即復位后程序運行到main()函數之前一直在不停的復位。經過認真分析發現原來是在定義全局變量或靜態變量時對這些變量進行初始化引起的。
問題產生的原因
用C語言編程時,系統復位Reset后所執行的第一個程序模塊并不是使用者的主程序main(),而是一個隱藏在KEIL—C51標準程序庫中稱為startup.a51的程序模塊。startup.a51的主要作用是將單片機內部所有RAM單元清零,接著startup.a51被執行的仍然是一個隱藏在KEIL-C51標準程序庫中被稱為init.a51的程序模塊,init.a51的主要工作是初始化程序的全局變量或靜態變量。完成上述初始化程序之后,才會開始執行main()程序。由前面的介紹可知看門狗定時器在上電或掉電復位后,看門狗定時器復位不會關閉看門狗定時器,即在系統熱啟動(看門狗或其他原因引起的復位)程序重新開始運行startup.a51、init.a51時,看門狗定時器仍在繼續運行;由于運行startup.a51、init.a51花費的時間比較長,即使將看門狗定時器中斷時間設置為最長,程序運行到main()程序之前看門狗定時器將溢出并引起系統復位。所以由熱啟動引起系統復位時,看門狗定時器在運行到main()函數之前將反復引起系統復位此時系統將無法進入main()程序運行。
問題解決的方法
針對上述情況W77E58C51編程環境下初始化程序執行時間長于看門狗設置的最長時間,如果想使watchdog正常運行下面提供了兩種方法:
1.最簡單的方法是在程序中定義全局變量和靜態變量時不要對這些變量賦以初值,對這些變量的賦置可以放在程序中進行。這樣系統復位(Reset)后程序在運行到main()函數之前只運行startup.a5l,運行startup.a51所占用的時間比較短,程序運行到main()函數時看門狗定時器將不溢出。當程序運行到main()函數時可以將main()的第一條語句寫為“喂狗”(將看門狗定時器值復零)指令,這樣可以確保熱啟動時看門狗定時器不溢出,系統得以正常運行。對于W77E58單片機來說其內部資源有限,程序代碼空間為32K,如果程序量比較大,精簡指令減少程序代碼是非常有必要的,采用這種方法時程序代碼中不包含有init.a51初始化程序全局變量或靜態變量的代碼,可以有效的縮減程序代碼。
如果程序量比較少,為了簡便在定義全局變量和靜態變量時對這些變量進行了初始化,在這種情況下可以在將init.a51添加到項目程序中。Init.a51模塊中包含有watchdog宏,在初始化程序執行時間長于看門狗設置的最長時間的時候可以設置這個宏,即在系統熱啟動程序重新運行到init.a51時,首先執行“喂狗”指令,這樣可以確保程序在運行到main()之前看門狗不溢出,系統可以正常運行。
結語
在惡劣的現場環境下受到外部干擾,單片機系統會出現“死機”、程序“跑飛”等現象,Watchdog技術是恢復系統的有效方法之一。隨著C語言在開發單片機系統中越來越廣泛的被應用,確保C51環境下正常運行Watchdog也尤為重要。文中給出了使用W77E58作為系統CPU,在利用C語言編制程序時定義全局變量或靜態變量時進行變量初始化對Watchdog的使用產生的影響及解決方法,當然利用C語言編程在使用其他CPU的Watchdog時也可以借鑒此種方法,利用這種方法可以保證Watchdog的正常運行,有效提高單片機系統運行的可靠性。