當(dāng)前位置:首頁(yè) > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]其實(shí)一直出現(xiàn)在例子中的 main()也算是一個(gè)函數(shù),只不過(guò)它比較特殊,編譯時(shí)以它做為程序的開(kāi)始段。有了函數(shù)C 語(yǔ)言就有了模塊化的優(yōu)點(diǎn),一般功能較多的程序,會(huì)在編寫(xiě)程序時(shí)把每項(xiàng)單獨(dú)的功能分成數(shù)個(gè)子程序模塊,每個(gè)子

其實(shí)一直出現(xiàn)在例子中的 main()也算是一個(gè)函數(shù),只不過(guò)它比較特殊,編譯時(shí)以它做為程序的開(kāi)始段。有了函數(shù)C 語(yǔ)言就有了模塊化的優(yōu)點(diǎn),一般功能較多的程序,會(huì)在編寫(xiě)程序時(shí)把每項(xiàng)單獨(dú)的功能分成數(shù)個(gè)子程序模塊,每個(gè)子 程序就能用函數(shù)來(lái)實(shí)現(xiàn)。函數(shù)還能被反復(fù)的調(diào)用,因此一些常用的函數(shù)能做成函數(shù)庫(kù)以供在編寫(xiě)程序時(shí)直接調(diào)用,從而更好的實(shí)現(xiàn)模塊化的設(shè)計(jì),大大提高編程工作的效率。

 一.函數(shù)定義

通常 C 語(yǔ)言的編譯器會(huì)自帶標(biāo)準(zhǔn)的函數(shù)庫(kù),這些都是一些常用的函數(shù),Keil uv 中也不 例外。標(biāo)準(zhǔn)函數(shù)已由編譯器軟件商編寫(xiě)定義,使用者直接調(diào)用就能了,而無(wú)需定義。但是 標(biāo)準(zhǔn)的函數(shù)不足以滿(mǎn)足使用者的特殊要求,因此 C 語(yǔ)言允許使用者根據(jù)需要編寫(xiě)特定功能的 函數(shù),要調(diào)用它必須要先對(duì)其進(jìn)行定義。定義的模式如下:

函數(shù)類(lèi)型 函數(shù)名稱(chēng)(形式參數(shù)表)

{

函數(shù)體

函數(shù)類(lèi)型是說(shuō)明所定義函數(shù)返回值的類(lèi)型。返回值其實(shí)就是一個(gè)變量,只要按變量

類(lèi)型來(lái)定義函數(shù)類(lèi)型就行了。如函數(shù)不需要返回值函數(shù)類(lèi)型能寫(xiě)作“void”表示該函數(shù)沒(méi) 有返回值。注意的是函數(shù)體返回值的類(lèi)型一定要和函數(shù)類(lèi)型一致,不然會(huì)造成錯(cuò)誤。函數(shù)名 稱(chēng)的定義在遵循 C 語(yǔ)言變量命名規(guī)則的同時(shí),不能在同一程序中定義同名的函數(shù)這將會(huì)造成 編譯錯(cuò)誤(同一程序中是允許有同名變量的,因?yàn)樽兞坑腥趾途植孔兞恐?。形式參數(shù) 是指調(diào)用函數(shù)時(shí)要傳入到函數(shù)體內(nèi)參與運(yùn)算的變量,它能有一個(gè)、幾個(gè)或沒(méi)有,當(dāng)不需要 形式參數(shù)也就是無(wú)參函數(shù),括號(hào)內(nèi)能為空或?qū)懭?ldquo;void”表示,但括號(hào)不能少。函數(shù)體中 能包含有局部變量的定義和程序語(yǔ)句,如函數(shù)要返回運(yùn)算值則要使用 return 語(yǔ)句進(jìn)行返 回。在函數(shù)的{}號(hào)中也能什么也不寫(xiě),這就成了空函數(shù),在一個(gè)程序項(xiàng)目中能寫(xiě)一些 空函數(shù),在以后的修改和升級(jí)中能方便的在這些空函數(shù)中進(jìn)行功能擴(kuò)充。

二.函數(shù)的調(diào)用

函數(shù)定義好以后,要被其它函數(shù)調(diào)用了才能被執(zhí)行。C 語(yǔ)言的函數(shù)是能相互調(diào)用的, 但在調(diào)用函數(shù)前,必須對(duì)函數(shù)的類(lèi)型進(jìn)行說(shuō)明,就算是標(biāo)準(zhǔn)庫(kù)函數(shù)也不例外。標(biāo)準(zhǔn)庫(kù)函數(shù)的 說(shuō)明會(huì)被按功能分別寫(xiě)在不一樣的頭文件中,使用時(shí)只要在文件最前面用#include 預(yù)處理語(yǔ) 句引入相應(yīng)的頭文件。如前面一直有使用的 printf 函數(shù)說(shuō)明就是放在文件名為 stdio.h 的 頭文件中。調(diào)用就是指一個(gè)函數(shù)體中引用另一個(gè)已定義的函數(shù)來(lái)實(shí)現(xiàn)所需要的功能,這個(gè)時(shí)候函 數(shù)體稱(chēng)為主調(diào)用函數(shù),函數(shù)體中所引用的函數(shù)稱(chēng)為被調(diào)用函數(shù)。一個(gè)函數(shù)體中能調(diào)用數(shù)個(gè) 其它的函數(shù),這些被調(diào)用的函數(shù)同樣也能調(diào)用其它函數(shù),也能嵌套調(diào)用。筆者本人認(rèn)為 主函數(shù)只是相對(duì)于被調(diào)用函數(shù)而言。在 c51 語(yǔ)言中有一個(gè)函數(shù)是不能被其它函數(shù)所調(diào)用的, 它就是 main 主函數(shù)。調(diào)用函數(shù)的一般形式如下:

函數(shù)名 (實(shí)際參數(shù)表) “函數(shù)名”就是指被調(diào)用的函數(shù)。實(shí)際參數(shù)表能為零或多個(gè)參數(shù),多個(gè)參數(shù)時(shí)要用逗

號(hào)隔開(kāi),每個(gè)參數(shù)的類(lèi)型、位置應(yīng)與函數(shù)定義時(shí)所的形式參數(shù)一一對(duì)應(yīng),它的作用就是把參 數(shù)傳到被調(diào)用函數(shù)中的形式參數(shù),如果類(lèi)型不對(duì)應(yīng)就會(huì)產(chǎn)生一些錯(cuò)誤。調(diào)用的函數(shù)是無(wú)參函 數(shù)時(shí)不寫(xiě)參數(shù),但不能省后面的括號(hào)。

在以前的一些例子我們也能看不一樣的調(diào)用方式:

1.函數(shù)語(yǔ)句

如 printf ("Hello World!n"); 這是在 我們的第一個(gè)程序中出現(xiàn)的,它以 "Hello

World!n"為參數(shù)調(diào)用 printf 這個(gè)庫(kù)函數(shù)。在這里函數(shù)調(diào)用被看作了一條語(yǔ)句。

2.函數(shù)參數(shù) “函數(shù)參數(shù)”這種方式是指被調(diào)用函數(shù)的返回值當(dāng)作另一個(gè)被調(diào)用函數(shù)的實(shí)際參

數(shù),如 temp=StrToInt(CharB(16));CharB 的返回值作為 StrToInt 函數(shù)的實(shí)際參數(shù)傳遞。

3.函數(shù)表達(dá)式

而在上一篇的例子中有 temp = Count();這樣一句,這個(gè)時(shí)候函數(shù)的調(diào)用作為一個(gè)運(yùn)算 對(duì)象出現(xiàn)在表達(dá)式中,能稱(chēng)為函數(shù)表達(dá)式。例子中 Count()返回一個(gè) int 類(lèi)型的返回 值直接賦值給 temp。注意的是這種調(diào)用方式要求被調(diào)用的函數(shù)能返回一個(gè)同類(lèi)型的值, 不然會(huì)出現(xiàn)不可預(yù)料的錯(cuò)誤。

前面說(shuō)到調(diào)用函數(shù)前要對(duì)被調(diào)用的函數(shù)進(jìn)行說(shuō)明。標(biāo)準(zhǔn)庫(kù)函數(shù)只要用#include 引入已 寫(xiě)好說(shuō)明的頭文件,在程序就能直接調(diào)用函數(shù)了。如調(diào)用的是自定義的函數(shù)則要用如下形 式編寫(xiě)函數(shù)類(lèi)型說(shuō)明

類(lèi)型標(biāo)識(shí)符 函數(shù)的名稱(chēng)(形式參數(shù)表); 這樣的說(shuō)明方式是用在被調(diào)函數(shù)定義和主調(diào)函數(shù)是在同一文件中。你也能把這些寫(xiě)到

文件名.h 的文件中用#include "文件名.h"引入。如果被調(diào)函數(shù)的定義和主調(diào)函數(shù)不是在同 一文件中的,則要用如下的方式進(jìn)行說(shuō)明,說(shuō)明被調(diào)函數(shù)的定義在同一項(xiàng)目的不一樣文件之上, 其實(shí)庫(kù)函數(shù)的頭文件也是如此說(shuō)明庫(kù)函數(shù)的,如果說(shuō)明的函數(shù)也能稱(chēng)為外部函數(shù)。

extern 類(lèi)型標(biāo)識(shí)符 函數(shù)的名稱(chēng)(形式參數(shù)表); 函數(shù)的定義和說(shuō)明是完全不一樣的,在編譯的角度上看函數(shù)的定義是把函數(shù)編譯存放在

ROM 的某一段地址上,而函數(shù)說(shuō)明是告訴編譯器要在程序中使用那些函數(shù)并確定函數(shù)的地 址。如果在同一文件中被調(diào)函數(shù)的定義在主調(diào)函數(shù)之前,這個(gè)時(shí)候能不用說(shuō)明函數(shù)類(lèi)型。也就 是說(shuō)在 main 函數(shù)之前定義的函數(shù),在程序中就能不用寫(xiě)函數(shù)類(lèi)型說(shuō)明了。能在一個(gè)函 數(shù)體調(diào)用另一個(gè)函數(shù)(嵌套調(diào)用),但不允許在一個(gè)函數(shù)定義中定義另一個(gè)函數(shù)。還要注意 的是函數(shù)定義和說(shuō)明中的“類(lèi)型、形參表、名稱(chēng)”等都要相一致。

三.中斷函數(shù)

中斷服務(wù)函數(shù)是編寫(xiě)單片機(jī)應(yīng)用程序不可缺少的。中斷服務(wù)函數(shù)只有在中斷源請(qǐng)求響應(yīng)

中斷時(shí)才會(huì)被執(zhí)行,這在處理突發(fā)事件和實(shí)時(shí)控制是十分有效的。例如:電路中一個(gè)按鈕, 要求按鈕后 LED 點(diǎn)亮,這個(gè)按鈕何時(shí)會(huì)被按下是不可預(yù)知的,為了要捕獲這個(gè)按鈕的事件, 通常會(huì)有三種方法,一是用循環(huán)語(yǔ)句不斷的對(duì)按鈕進(jìn)行查詢(xún),二是用定時(shí)中斷在間隔時(shí)間內(nèi) 掃描按鈕,三是用外部中斷服務(wù)函數(shù)對(duì)按鈕進(jìn)行捕獲。在這個(gè)應(yīng)用中只有單一的按鈕功能, 那么第一種方式就能勝任了,程序也很簡(jiǎn)單,但是它會(huì)不停的在對(duì)按鈕進(jìn)行查詢(xún)浪費(fèi)了

CPU 的時(shí)間。實(shí)際應(yīng)用中一般都會(huì)還有其它的功能要求同時(shí)實(shí)現(xiàn),這個(gè)時(shí)候能根據(jù)需要選用第 二或第三種方式,第三種方式占用的 CPU 時(shí)間最少,只有在有按鈕事件發(fā)生時(shí),中斷服務(wù)函 數(shù)才會(huì)被執(zhí)行,其余的時(shí)間則是執(zhí)行其它的任務(wù)。

如果你學(xué)習(xí)過(guò)匯編語(yǔ)言的話(huà),剛開(kāi)始寫(xiě)匯編的中斷應(yīng)用程序時(shí),你一定會(huì)為出入堆棧的 問(wèn)題而困擾過(guò)。單片機(jī)c語(yǔ)言 語(yǔ)言擴(kuò)展了函數(shù)的定義使它能直接編寫(xiě)中斷服務(wù)函數(shù),你能不必考 慮出入堆棧的問(wèn)題,從而提高了工作的效率。擴(kuò)展的關(guān)鍵字是 interrupt,它是函數(shù)定義時(shí) 的一個(gè)選項(xiàng),只要在一個(gè)函數(shù)定義后面加上這個(gè)選項(xiàng),那么這個(gè)函數(shù)就變成了中斷服務(wù)函數(shù)。

在后面還能加上一個(gè)選項(xiàng) using,這個(gè)選項(xiàng)是指定選用 51 芯片內(nèi)部 4 組工作寄存器中的

那個(gè)組。開(kāi)始學(xué)習(xí)者能不必去做工作寄存器設(shè)定,而由編譯器自動(dòng)選擇,避免產(chǎn)生不必要的錯(cuò) 誤。定義中斷服務(wù)函數(shù)時(shí)能用如下的形式。

函數(shù)類(lèi)型 函數(shù)名 (形式參數(shù)) interrupt n [using n]

interrupt 關(guān)鍵字是不可缺少的,由它告訴編譯器該函數(shù)是中斷服務(wù)函數(shù),并由后面的

n 指明所使用的中斷號(hào)。n 的取值范圍為 0-31,但具體的中斷號(hào)要取決于芯片的型號(hào),像 AT89c51 實(shí)際上就使用 0-4 號(hào)中斷。每個(gè)中斷號(hào)都對(duì)應(yīng)一個(gè)中斷向量,具體地址為 8n+3, 中斷源響應(yīng)后處理器會(huì)跳轉(zhuǎn)到中斷向量所處的地址執(zhí)行程序,編譯器會(huì)在這地址上產(chǎn)生一個(gè) 無(wú)條件跳轉(zhuǎn)語(yǔ)句,轉(zhuǎn)到中斷服務(wù)函數(shù)所在的地址執(zhí)行程序。下表是 51 芯片的中斷向量和中 斷號(hào)。

表 9-1 AT89c51 芯片中斷號(hào)和中斷向量

使用中斷服務(wù)函數(shù)時(shí)應(yīng)注意:中斷函數(shù)不能直接調(diào)用中斷函數(shù);不能通過(guò)形參傳速參數(shù); 在中斷函數(shù)中調(diào)用其它函數(shù),兩者所使用的寄存器組應(yīng)相同。限于篇幅其它與函數(shù)相關(guān)的知 識(shí)這里不能一一加以說(shuō)明,如變量的傳遞、存儲(chǔ),局部變量、全部變量等,有興趣的朋友可 以訪(fǎng)問(wèn)筆者的網(wǎng)站 閱讀更多相關(guān)文章。

下面是簡(jiǎn)單的例子。首先要在前面做好的實(shí)驗(yàn)電路中加多一個(gè)按鈕,接在 P3.2(12 引腳外 部中斷 INT0)和地線(xiàn)之間。把編譯好后的程序燒錄到芯片后,當(dāng)接在 P3.2 引腳的按鈕接下 時(shí),中斷服務(wù)函數(shù) Int0Demo 就會(huì)被執(zhí)行,把 P3 當(dāng)前的狀態(tài)反映到 P1,如按鈕接下后 P3.7

(之前有在這腳裝過(guò)一按鈕)為低,這個(gè)時(shí)候 P1.7 上的 LED 就會(huì)熄滅。放開(kāi) P3.2 上的按鈕后,

P1LED 狀態(tài)保持先前按下 P3.2 時(shí) P3 的狀態(tài)。

#include

unsigned char P3State(void); //函數(shù)的說(shuō)明,中斷函數(shù)不用說(shuō)明

void main(void)

{

IT0 = 0; //設(shè)外部中斷 0 為低電平觸發(fā)

EX0 = 1; //允許響應(yīng)外部中斷 0

EA = 1; //總中斷開(kāi)關(guān)

while(1);

}

//外部中斷 0 演示,使用 2 號(hào)寄存器組

void Int0Demo(void) interrupt 0 using 2

{

unsigned int Temp; //定義局部變量

P1 = ~P3State(); //調(diào)用函數(shù)取得 p2 的狀態(tài)反相后并賦給 P1

for (Temp=0; Temp<50; Temp++); //延時(shí) 這里只是演示局部變量的使用

}

//用于返回 P3 的狀態(tài),演示函數(shù)的使用

unsigned char P3State(void)

{

unsigned char Temp;

Temp = P3; //讀取 P3 的引腳狀態(tài)并保存在變量 Temp 中

//這樣只有一句語(yǔ)句實(shí)在沒(méi)必要做成函數(shù),這里只是學(xué)習(xí)函數(shù)的基本使用方法

return Temp;

}

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶(hù)希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱(chēng),數(shù)字世界的話(huà)語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱(chēng)"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉