微控制器C語言程式設計應注意的若干問題

2021-04-20 18:57:05 字數 4593 閱讀 4223

微控制器c語言程式設計應注意的若干問題

1 微控制器c語言主要特點

用c 編寫程式比彙編更符合人們的思考習慣,開發者可以擺脫與硬體無必要的接觸,更專心的考慮功能和演算法而不是考慮一些細節問題,這樣就減少了開發和除錯的時間。c語言具有良好的程式結構,適用於模組化程式設計,因此採用c語言設計微控制器應用系統程式時,首先要盡可能地採用結構化的程式設計方法,將功能模組化,由不同的模組完成不同的功能[1],這樣可使整個應用系統程式結構清晰,易於除錯和維護。不同的功能模組,分別指定相應的入口引數和出口引數,對於一些要重複呼叫的程式一般把其編成函式,這樣可以減少程式**的長度,又便於整個程式的管理,還可增強可讀性和移植性。

在實際微控制器程式設計中,程式結構一般均採用如下結構:

#include/*標頭檔案說明部份*/

unsigned char x1,x2;  /*全域性變數宣告部份*/

…function1(… )

main() 

2 微控制器c語言與標準c語言的區別

由於現在越來越多的產品都採用微控制器開發,所完成的計算和控制工作也日趨複雜,但是微控制器系統是一種資源十分有限的系統,這主要表現在程式儲存器資源的不足,因此在程式設計時如何使用好這些有限的資源就顯得十分重要。用c語言程式設計雖然具有許多的優點,但是生成的**相對要長,要是程式設計技術不好,生成的**甚至有可能比組合語言生成的**長幾倍,因此對程式設計者來說,應該注意到微控制器c語言和一般意義上的標準c語言的區別,對程式進行適當的優化。

2.1 資料型別的選用

微控制器c語言程式設計不同於一般的c語言程式設計的顯著的乙個特點,就是要和程式儲存器資源結合起來,雖然其提供的資料據型別十分豐富,但是只有bit和char等資料型別是是機器語言直接支援的資料型別,用此類資料型別的語句所生成的**較短;而其它的資料型別如整型、浮點型等資料要有一定的內部程式或內部函式的支援,相對來說用該類資料型別的語句生成的**要長。有些c語言程式表面上看起來十分的簡單,但在在實際編譯時,生成的**卻相當長。因此我們要按照實際需要,合理地選用資料,可以大大的減少所生成的**長度。例如在c51中每種資料型別變數所占用儲存器位元組數和經編譯後生成的**長度如表1所示:

表1 不同資料型別占用儲存器位元組數和**長度對比

通過表1我們知道,不同的資料型別所生成的機器**長度相差很多,相同型別的資料型別有無符號對機器**長度也有影響。在程式編譯時生成機器**長的資料型別的優先順序越高,不同的資料型別在進行程式運算時要轉化為高優先順序的的資料型別,相應的**長度也會增長[2]。因此我們應盡可能地使用bit,char等機器語言直接支援的資料型別,無符號數的變數應宣告為無符號數,盡可能地減少程式中使用的資料型別的種類。

2.2 演算法設計問題

微控制器c語言和標準c語言存在著很大差別,在計算機上進行c語言程式設計時由於不必考慮程式**的長短,只需考慮程式功能實現,但是在微控制器上進行c語言程式設計就必須考慮系統的硬體資源。有時並不是程式的演算法越簡單、長度越短越好,因為有一些演算法要呼叫一些內部的子程式和函式,生成的機器**長度非常長。不同的演算法對程式**長度影響十分大,因此在進行程式設計時,就盡量採用程式生成**短的演算法,在不影響程式功能實現的情況下可以採用一些優化演算法[2]。

在微控制器c語言編譯成機器**時,不同的運算生成的機器**的長度相差很大,盡可能地減少程式中對某種資料型別的運算種類,越複雜的資料型別效果越明顯。在進行資料計算時,在一定的精度範圍內,可以用一些近似的計算來完成一些運算,既不損失精度又能減少大量的**。比如:用邏輯and/&取模比mod/%操作更有效。

在用熱敏電阻測量溫度時,可根據熱敏電阻—溫度特性公式來求值。數學表示式表示為:

rt=rt0expb(1/t-1/t0)

如果直接按照公式溫度時程式結構簡單,演算法複雜度不高,但是程式將呼叫檔案中的對數函式,在編譯成機器碼時函式有1k多位元組,對於一般只有幾k位元組的微控制器系統來說,這是十分不合適的。考慮到系統資源問題可以用一種替代方法—查表法來實現演算法。只要給出一定溫度範圍內不同溫度值對應熱敏電阻的電阻值,然後建立**,只要按照系統求出的阻值,進行查表,插值,就可以求出相應的溫度值。這種演算法相比前面的的公式法的演算法複雜高,c語言程式**也長,但在編譯成機器碼時,**長度卻很短,只有

一、二百位元組。

3  資料儲存器的分配

微控制器內部資料儲存器ram只有幾百位元組,如果擴充套件外部儲存器ram來提高資料儲存量話必將會增加了硬體成本,使系統更加的複雜,訪問外部儲存器比訪問內部儲存器所需的**也要長得多。有效地使用片記憶體儲器、提高儲存器空間的利用率對開發者來說十分關鍵。

內部處理器、內部堆疊、壓縮棧、所有程式變數和所有包含進來的庫函式都將使用數量有限的內部資料儲存器ram。因為c語言採用了儲存器的覆蓋技術[2],可以在程式進行連線時,它將那些已經被其它程式段釋放了的儲存器空間重新定義給另乙個程式段的變數使用,當這個程式執行結束時再將這些儲存器釋放以供其它程式段使用。全域性變數的作用範圍是整個程式,因此不能被釋放;靜態變數由於在函式的呼叫中專用不變,也不能被釋放;只有區域性變數中的動態變數可以被釋放。

因此在進行程式設計時應該盡量的使用區域性變數,提高內部資料儲存器的使用率。在c語言中程式中間結果及引數傳傳遞是通過內部的暫存器來完成的,要是內部的儲存器不夠,將會給你的程式帶來許多莫名其妙的錯誤。例如在進行程式設計時語句不應該太長,乙個長語句可以分成多個語句,這樣的話可以大的減少中間變數,當然太長時就會造成臨時暫存器的不夠用,導致計算出錯。

4 微控制器c語言與組合語言的混合程式設計

在絕大多數場合採用c語言程式設計即可完成預期的目的,但是對實時時鐘系統、要求執行效率高的的系統就不適合採用c語言程式設計,對這些特殊情況進行程式設計時要結合組合語言。組合語言具有直接和硬體打道、執行**的效率高等特點,可以做到c語言所不能做到的一些事情,例如對時鐘要求很嚴格時,使用組合語言成了唯一的選擇。這種混合程式設計[2]的方法將c語言和組合語言的優點結合起來,已經成為目前微控制器開發最流行的程式設計方法。

目前大多數據微控制器系統,在c語言中使用組合語言有兩種情況:一種是匯程式設計序部分和c程式部分為不同的模組,或不同的檔案,通常由c程式呼叫匯程式設計序模組的變數和函式(也可稱為子程式或過程);另一種是嵌入式彙編,即在c語言程式中嵌入一段組合語言程式。

當匯程式設計序和c程式為不同模組時程式一般可分為若於個c程式模組和匯程式設計序模組,c程式模組通常是程式的主體框架,而匯程式設計序模組通常由用c語言實現效率不高的函式組成,也可以是已經成熟的、沒有必要再轉化成c語言的彙編子程式。在這種混合程式設計技術中,關鍵是引數的傳遞和函式的返回值。它們必須有完整的約定,否則資料的交換就可能出錯。

對於嵌入式彙編,可以在c程式中使用一些關鍵字嵌入下些匯程式設計序,這種方法主要用於實現數**算或中斷處理,以便生成精練的**,減少執行時間。當彙編函式不大,且內部沒有複雜的跳轉時,可以用嵌入式彙編實現。

下面就以at89c2051微控制器在模擬電壓檢測中的應用為例說明c語言程式與組合語言程式的呼叫。電路圖如圖1所示:

at89c2051微控制器內建模擬比較器,13腳即p1.1是比較器的負輸入端,12腳即p1.0是比較器的正輸入端,比較器的輸出端做在了cpu內部即p3.6未被引出,cpu可以直接讀取p3.6狀態來判定兩輸入端比較的結果其和乙個外部電阻及乙個外部電容器就可以設計成乙個a/d轉換器,採用rc模擬轉換的原理,來檢測外部p1.1引腳的輸入電壓。由於系統對時鐘要求很嚴格,因此就採用了c語言和組合語言混合程式設計技術,程式呼叫形式如下:

彙編子程式:

public  _ad           ;入口位址

con  segment code     ;程式段

rseg    con

_ad:   setb  p3.7       ;充電

loop:    jb  p3.6,ad_end   ;開始計數匹配

inc a       

cjne  a,#100,loop

ad_end:  clr p3.7  ;放電       

cjne  a,#100,ret_val   ;看結果是否有溢位,有溢位說明結果不對

sjmp  con_ov;返回值         

ret_val:dec a

mov r7,a         ;a/d轉換的結果儲存在r7中,傳遞給主程式

con_ov: ret 

end微控制器c程式:

include

unsigned char ad(unsigned char);//在c程式中宣告彙編模數轉換子程式

……………

void timer0(void) interrupt 1 using 1

main

在以上程式中,函式的返回值為一無符號字元型數,根據呼叫規則,返回值在r7中,這樣才可保證資料的傳遞不出錯。另外,在呼叫過程中,必須注意暫存器的入棧。這樣在以後用到a/d轉換時,在c語言中呼叫組合語言子程式ad()即可。

5 結束語

c語言具有很強的功能性和結構性,可以縮短微控制器控制系統的開發周期,而且易於除錯和維護,已經成為目前微控制器語言中最流行的程式語言。

本文就微控制器c語言的特點以及在開發過程中的一些問題給予分析並提供了解決方法,為廣大微控制器開發人員提供了可借鑑的經驗。

參考文獻

1 王平,邢建春,王林.一種快速有效攔截彈飛的微控制器程式新方法. 微計算機資訊,1997,4(13):80-81.

2 馬忠梅,籍順心,張凱,馬巖.微控制器的c語言應用程式設計.北京:北京航空航天大學出版社,1999.

微控制器C語言程式設計

一 首先我們先了解一下51微控制器的標頭檔案 include 為了能看懂reg51.h標頭檔案,下面需了解keil c51編譯器擴充套件的關鍵字 關鍵字用途 說明bit 位標量宣告 宣告乙個位標量或位型別 sbit 位變數宣告 宣告乙個可位定址變數 sfr特殊功能暫存器宣告 宣告乙個特殊功能暫存器 ...

微控制器程式設計中的注意點

1 延時的問題。延時的方法有死迴圈延時 定時器中斷。案例。鍵盤掃瞄,掃瞄間隔10ms 液晶閃爍,需要用到延時開關,形成閃爍效果。這樣的情況需要採用定時器中斷延時,避免減小按鍵掃瞄的識別精度 按下了,但沒有識別 2 對於段碼屏中有符號和數字共用乙個位址的情況,一定要先讀取快取資料,判斷符號的情況,再進...

微控制器程式語言的比較

微控制器又稱單片微控制器,它是把乙個計算機系統,包括cpu ram rom 定時 計數器和多種i o介面整合到乙個晶元上。由於微控制器的種種優點和特性,其應用領域極其廣泛。微控制器系統同樣也由硬體系統和軟體系統構成,因此涉及到程式的編寫問題。微控制器的程式語言很多,大致分成三類 機器語言 組合語言 ...