(玩電子) 電子技術學習與(yu)研究
當前位置︰單(dan)片機教程網 >> 基礎教程 >> 瀏覽文章

全明星彩票官网

作者:佚名   來(lai)源:本(ben)站原創   點(dian)擊數:x  更新時間︰2020年02月10日   【字體︰

上一篇的最後一個例子中有(you)用到(dao)函數,其實一直出現在例子中的  main()也(ye)算是一個函數,只不過它比較特殊,編譯時以yun)鑫 絛虻目 級巍Syou)了函數 C 語言就(jiu)有(you)了si)?kuai)化的優 點(dian),一hua)愎δ芙隙duo)的程序,會在編寫程序時把(ba)每項(xiang)單(dan)獨的功能分成數個子程序模塊(kuai),每個子 程序就(jiu)能用函數來(lai)實現。函數還能被反復的調用,因此一些常用的函數能做成函數庫 以供(gong)在編寫程序時直接(jie)調用,從而(er)更好(hao)的實現模塊(kuai)化的設計,大大提高編程工作的效率。 一.函數定義

通常 C 語言的編譯器會自帶標準的函數庫,這些都(du)是一些常用的函數,Keil uv 中也(ye)不 例外。標準函數已(yi)yan)殺嘁肫魅砑癱嘈炊ㄒ澹 褂謎咧苯jie)調用就(jiu)能了,而(er)無(wu)需定義。但(dan)是 標準的函數不足以滿(man)足使用者的特殊要求,因此 C 語言允許使用者根據需要編寫特定功能的 函數,要調用它必須要先對(dui)其進行定義。定義的模式(shi)如下︰

函數類型(xing)    函數名稱(形(xing)式(shi)參數表)

函數體

函數類型(xing)是說明(ming)所定義函數返回(hui)值的類型(xing)。返回(hui)值其實就(jiu)是一個變量,只要按變量

類型(xing)來(lai)定義函數類型(xing)就(jiu)行了。如函數不需要返回(hui)值函數類型(xing)能寫作“void”表示該函數沒(mei) 有(you)返回(hui)值。注(zhu)意的是函數體返回(hui)值的類型(xing)一定要和函數類型(xing)一致,不然會造成錯(cuo)誤。函數名 稱的定義在遵循 C 語言變量命(ming)名規則的同時,不能在同一程序中定義同名的函數這將會造成 編譯錯(cuo)誤(同一程序中是允許有(you)同名變量的,因為變量有(you)全(quan)局(ju)和局(ju)部變量之分)。形(xing)式(shi)參數 是指調用函數時要傳(chuan)入到(dao)函數體內參與(yu)運(yun)算的變量,它能有(you)一個、幾個或沒(mei)有(you),當不需要 形(xing)式(shi)參數也(ye)就(jiu)是無(wu)參函數,括號內能為空或寫入“void”表示,但(dan)括號不能少。函數體中 能包(bao)含(han)有(you)局(ju)部變量的定義和程序語句(ju),如函數要返回(hui)運(yun)算值則要使用 return 語句(ju)進行返 回(hui)。在函數的{}號中也(ye)能什(shi)麼也(ye)不寫,這就(jiu)成了空函數,在一個程序項(xiang)目中能寫一些 空函數,在以後的修(xiu)改(gai)和升(sheng)級中能方便的在這些空函數中進行功能擴充(chong)。

二.函數的調用

函數定義好(hao)以後,要被其它函數調用了才能被執行。C 語言的函數是能相(xiang)互調用的, 但(dan)在調用函數前,必須對(dui)函數的類型(xing)進行xing)得ming),就(jiu)算是標準庫函數也(ye)不例外。標準庫函數的 說明(ming)會被hua)垂δ芊直鸚叢誆灰謊yang)的頭文件中,使用時只要在文件最前面(mian)用#include  預處理語 句(ju)引入相(xiang)應的頭文件。如前面(mian)一直有(you)使用的 printf 函數說明(ming)就(jiu)是放在文件名為 stdio.h 的 頭文件中。調用就(jiu)是指一個函數體中引用另(ling)一個已(yi)定義的函數來(lai)實現所需要的功能,這個時候函 數體稱為主調用函數,函數體中xing)玫暮 莆 壞饔煤 R桓齪 逯心艿饔檬其它的函數,這些被調用的函數同樣(yang)也(ye)能調用其它函數,也(ye)能嵌套(tao)調用。筆者本(ben)人(ren)認為 主函數只是相(xiang)對(dui)于被調用函數而(er)言。在 c51 語言中有(you)一個函數是不能被其它函數所調用的, 它就(jiu)是 main 主函數。調用函數的一hua)閾xing)式(shi)如下:

函數名  (實際shi)問 “函數名”ben)jiu)是指被調用的函數。實際shi)問砟  慊蚨duo)個參數,多(duo)個參數時要用逗

號隔開,每個參數的類型(xing)、位置應與(yu)函數定義時所的形(xing)式(shi)參數一一對(dui)應,它的作用就(jiu)是把(ba)參 數傳(chuan)到(dao)被調用函數中的形(xing)式(shi)參數,如果類型(xing)不對(dui)應就(jiu)會產(chan)生一些錯(cuo)誤。調用的函數是無(wu)參函 數時不寫參數,但(dan)不能省後面(mian)的括號。

在以前的一些例子我(wo)們也(ye)能看不一樣(yang)的調用方式(shi)︰

1.函數語句(ju)


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

World!\n"為參數調用 printf 這個庫函數。在這里函數調用被看作了一條語句(ju)。

2.函數參數 “函數參數”這種zhi)絞shi)是指被調用函數的返回(hui)值當作另(ling)一個被調用函數的實際shi)/p>

數,如 temp=StrToInt(CharB(16));CharB 的返回(hui)值作為 StrToInt 函數的實際shi)問chuan)遞。

3.函數表達式(shi)

而(er)在上一篇的例子中有(you) temp = Count();這樣(yang)一句(ju),這個時候函數的調用作為一個運(yun)算 對(dui)象(xiang)出現在表達式(shi)中,能稱為函數表達式(shi)。例子中 Count()返回(hui)一個 int 類型(xing)的返回(hui) 值直接(jie)賦chi)蹈temp。注(zhu)意的是這種調用方式(shi)要求被調用的函數能返回(hui)一個同類型(xing)的值, 不然會出現不可(ke)預料的錯(cuo)誤。

前面(mian)說到(dao)調用函數前要對(dui)被調用的函數進行xing)得ming)。標準庫函數只要用#include  引入已(yi) 寫好(hao)說明(ming)的頭文件,在程序就(jiu)能直接(jie)調用函數了。如調用的是自定義的函數則要用如下形(xing) 式(shi)編寫函數類型(xing)說明(ming)

類型(xing)標識符    函數的名稱(形(xing)式(shi)參數表); 這樣(yang)的說明(ming)方式(shi)是用在被調函數定義和主調函數是在同一文件中。你也(ye)能把(ba)這些寫到(dao)

文件名.h 的文件中用#include "文件名.h"引入。如果被調函數的定義和主調函數不是在同 一文件中的,則要用如下的方式(shi)進行xing)得ming),說明(ming)被調函數的定義在同一項(xiang)目的不一樣(yang)文件之上, 其實庫函數的頭文件也(ye)是如此說明(ming)庫函數的,如果說明(ming)的函數也(ye)能稱為外部函數。

extern    類型(xing)標識符    函數的名稱(形(xing)式(shi)參數表); 函數的定義和說明(ming)是完全(quan)不一樣(yang)的,在編譯的角度上看函數的定義是把(ba)函數編譯存放在

ROM  的某一段地址(zhi)上,而(er)函數說明(ming)是告訴編譯器要在程序中使用那(na)些函數並確定函數的地 址(zhi)。如果在同一文件中被調函數的定義在主調函數之前,這個時候能不用說明(ming)函數類型(xing)。也(ye)就(jiu) 是說在 main 函數之前定義的函數,在程序中就(jiu)能不用寫函數類型(xing)說明(ming)了。能在一個函 數體調用另(ling)一個函數(嵌套(tao)調用),但(dan)不允許在一個函數定義中定義另(ling)一個函數。還要注(zhu)意 的是函數定義和說明(ming)中的“類型(xing)、形(xing)參表、名稱”等都(du)要相(xiang)一致。

三.中斷函數 中斷服(fu)務函數是編寫單(dan)片機應用程序不可(ke)缺少的。中斷服(fu)務函數只有(you)在中斷源請求響應

中斷時才會被執行,這在處理突發事件和實時控制是十分有(you)效的。例如︰電路(lu)中一個按鈕(niu), 要求按鈕(niu)後 LED 點(dian)亮,這個按鈕(niu)何時會被hua)聰率遣豢ke)預知(zhi)的,為了要捕獲這個按鈕(niu)的事件, 通常會有(you)三種zhi)椒  皇怯醚 酚錁ju)不斷的對(dui)按鈕(niu)進行查詢(xun),二是用定時中斷在間隔時間內 掃(sao)描按鈕(niu),三是用外部中斷服(fu)務函數對(dui)按鈕(niu)進行捕獲。在這個應用中只有(you)單(dan)一的按鈕(niu)功能, 那(na)麼第一種zhi)絞shi)就(jiu)能勝任了,程序也(ye)很簡單(dan),但(dan)是它會不停的在對(dui)按鈕(niu)進行查詢(xun)浪費了

CPU 的時間。實際應用中一hua)愣du)會還有(you)其它的功能要求同時實現,這個時候能根據需要選用第 二或第三種zhi)絞shi),第三種zhi)絞shi)佔用的 CPU 時間最少,只有(you)在有(you)按鈕(niu)事件發生時,中斷服(fu)務函 數才會被執行,其余的時間則是執行其它的任務。

如果你學習過匯(hui)編語言的話(hua),剛開始寫匯(hui)編的中斷應用程序時,你一定會為出入堆棧的 問題而(er)困擾過。單(dan)片機c語言 語言擴展(zhan)了函數的定義使它能直接(jie)編寫中斷服(fu)務函數,你能不必考 慮出入堆棧的問題,從而(er)提高了工作的效率。擴展(zhan)的關鍵(jian)字是 interrupt,它是函數定義時 的一個選項(xiang),只要在一個函數定義後面(mian)加上這個選項(xiang),那(na)麼這個函數就(jiu)變成了中斷服(fu)務函數。

在後面(mian)還能加上一個選項(xiang) using,這個選項(xiang)是指定選用 51 芯片內部 4 組工作寄(ji)存器中的


那(na)個組。開始學習者能不必去做工作寄(ji)存器設定,而(er)由編譯器自動選擇,避(bi)免產(chan)生不必要的錯(cuo) 誤。定義中斷服(fu)務函數時能用如下的形(xing)式(shi)。

函數類型(xing)    函數名  (形(xing)式(shi)參數)  interrupt  n  [using  n]

interrupt 關鍵(jian)字是不可(ke)缺少的,由它告訴編譯器該函數是中斷服(fu)務函數,並由後面(mian)的

n 指明(ming)所使用的中斷號。n 的取值範圍(wei)為 0-31,但(dan)具(ju)體的中斷號要取決于芯片的型(xing)號,像 AT89c51 實際上就(jiu)使用 0-4 號中斷。每個中斷號都(du)對(dui)應一個中斷向量,具(ju)體地址(zhi)為 8n+3, 中斷源響應後處理器會跳(tiao)轉到(dao)中斷向量所處的地址(zhi)執行程序,編譯器會在這地址(zhi)上產(chan)生一個 無(wu)條件跳(tiao)轉語句(ju),轉到(dao)中斷服(fu)務函數所在的地址(zhi)執行程序。下表是 51 芯片的中斷向量和中 斷號。

中斷號

中斷源

中斷向量

0

外部中斷 0

0003H

1

定時器/計數器 0

000BH

2

外部中斷 1

0013H

3

定時器/計數器 1

001BH

4

串行口

0023H

表 9-1    AT89c51 芯片中斷號和中斷向量

使用中斷服(fu)務函數時應注(zhu)意︰中斷函數不能直接(jie)調用中斷函數;不能通過形(xing)參傳(chuan)速參數; 在中斷函數中調用其它函數,兩者所使用的寄(ji)存器組應相(xiang)同。限于篇幅其它與(yu)函數相(xiang)關的知(zhi) 識這里不能一一加以yun)得ming),如變量的傳(chuan)遞、存儲(chu),局(ju)部變量、全(quan)部變量等,有(you)興(xing)趣的朋友可(ke) 以訪問筆者的網站 閱讀更多(duo)相(xiang)關文章。

下面(mian)是簡單(dan)的例子。首(shou)先要在前面(mian)做好(hao)的實驗(yan)電路(lu)中加多(duo)一個按鈕(niu),接(jie)在 P3.2(12 引腳外 部中斷 INT0)和地線之間。把(ba)編譯好(hao)後的程序燒錄到(dao)芯片後,當接(jie)在 P3.2 引腳的按鈕(niu)接(jie)下 時,中斷服(fu)務函數 Int0Demo 就(jiu)會被執行,把(ba) P3 當前的狀態反映到(dao) P1,如按鈕(niu)接(jie)下後 P3.7

(之前有(you)在這腳裝過一hua)磁niu))為低,這個時候 P1.7 上的 LED 就(jiu)會熄滅。放開 P3.2 上的按鈕(niu)後,

P1LED 狀態保持(chi)先前按下 P3.2 時 P3 的狀態。

#include <at89x51.h>

unsigned char P3State(void); //函數的說明(ming),中斷函數不用說明(ming)

void main(void)

{

IT0 = 0; //設外部中斷 0 為低電平觸(chu)發

EX0 = 1; //允許響應外部中斷 0

EA = 1; //總中斷開關

while(1);

}

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

void Int0Demo(void) interrupt 0 using 2


{

unsigned int Temp; //定義局(ju)部變量

P1 = ~P3State(); //調用函數取得 p2 的狀態反相(xiang)後並賦給 P1

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

}

//用于返回(hui) P3 的狀態,演示函數的使用

unsigned char P3State(void)

{

unsigned char Temp;

Temp = P3; //讀取 P3 的引腳狀態並保存在變量 Temp 中

//這樣(yang)只有(you)一句(ju)語句(ju)實在沒(mei)必要做成函數,這里只是學習函數的基本(ben)使用方法

return Temp;

}

發表評(ping)論】【告訴好(hao)友】【收藏(cang)此文】【關閉窗口

全明星彩票官网

全明星彩票官网

全明星彩票官网 | 下一页