91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

c語言中回調函數的使用方法及作用是什么

發布時間:2021-07-19 18:25:04 來源:億速云 閱讀:458 作者:chen 欄目:開發技術

本篇內容介紹了“c語言中回調函數的使用方法及作用是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

目錄
  • 前言

  • 一、通過這節課程你能掌握以下知識:

  • 二、程序架構的核心理念和需求

  • 三、回調函數的作用

    • 1.輸出型

    • 2.輸入型

  • 四、掌握回調函數的程序編寫

前言

今天給大家講一下芯片/模塊廠家寫SDK必須會使用的一種技術:回調函數。

回調函數這個知識點其實并不是很難,難是難在網上很多講解回調函數的都說的太學術化了化了,一點也不親民。

很多人即使知道怎么寫回調函數也根本就搞不懂它們在實際產品中也有什么用,什么時候用。

所以這節課呢我們會以程序架構的需求為出發點,講解回調函數是怎么滿足它這個需求的。

為了方便大家理解,這篇內容也對應有一篇文章,大家可以找無際單片機編程獲取。

一、通過這節課程你能掌握以下知識:

掌握程序架構的核心理念或需求。掌握回調函數的作用掌握回調函數的程序編寫掌握回調函數在產品中的應用

二、程序架構的核心理念和需求

很多人可能會說一個好的程序架構啊,就是代碼很緊湊、執行效率也很高。

其實這個說的很片面,不完全對,這只能說明你程序算法寫的好,但架構不一定做的好。

即然是架構,那自然是以從”大局”為重,思維不能局限于當下的產品功能,還要考慮到以后功能的增加和裁剪,那么對于單片機開發來說,我認為一個好的程序架構至少要達到以下要求:

硬件層和應用層的程序代碼分開,相互之間的控制和通訊使用接口,而且不會共享的全局變量或數組。

這里呢,我就這個要求,別小看這一個要求,因為這個要求里面蘊藏著很多學問的,比如用專業稱為可移植性、可擴展性。

那么我們來想象一下我們通常寫單片機代碼的方式啊,在51的時候基本一個.c文件解決,包括寄存器配置啊,產品功能啊。

c語言中回調函數的使用方法及作用是什么

這種就是沒有架構的程序,然后我們進化到STM32這個單片機以后,程序大了,慢慢也會在工程文件里加幾個文件夾目錄把硬件層和應用層代碼分開了。

于是我們會把一些不同的外設功能,比如Led、按鍵、串口等外設功能代碼分別寫在不同的.c文件里,然后統一用函數接口去調用它。

c語言中回調函數的使用方法及作用是什么

比方說控制一個LED燈亮,直接在led.c文件里寫一個驅動led燈狀態的函數然后給外部調用就好了。

c語言中回調函數的使用方法及作用是什么

那我們我們看這種Led的控制函數確實也是滿足程序架構的需求的,硬件層和應用層代碼分開,應用層用硬件層提供的接口來控制,而且又不會有硬件層和應用層共享的全部變量或數組。像這種是不是很簡單?

那么不知道你們有沒有碰到另外一種情況,就是應用程序需要采集硬件層的數據,比如串口接收數據,按鍵采集、ADC值采集。

這種硬件層的數據怎么通知應用層來拿,或者怎么主動給它?

我們以往最簡單粗暴的方式是不是就是用一個全局變量,比方說硬件層串口接收到數據來了,那么我們把數據丟到數組里,然后把接收完成全局變量標志位置1。

比方說全局變量名為RcvFlag,然后應用層程序會輪詢判斷RcvFlag==1?是的話就開始把數組里的數據取出來解析。

很多人就會說了,你看我用這種方法照樣能實現功能啊,為什么還要學習別的架構。

這樣做當然可以實現功能,但是會存在移植性很差的問題。

比如說你們老板讓你把這個串口的硬件層封裝起來給客戶用,但不能讓客戶看到你實現的源代碼,只提供接口(函數名)給對方用。

那么這時候難道你要告訴客戶先判斷哪個變量為1,然后再取哪個數組的數據這么LOW的做法嗎?

那么如果是懂行的客戶一定會懷疑你們公司的技術實力是不是小學生水平。

那怎樣做才會既方便又專業呢? 這里我們就需要用到回調函數啦。

三、回調函數的作用

那么在講回調函數之前呢,對于函數調用呢我一般分為2種類型:

1.輸出型

不知道大家有沒有用過C語言自帶的一些庫函數,比如說sizeof()獲取數據長度的函數,memcpy()是內存拷貝函數,我們調用這個函數之后呢就能完成相應的功能。

還有我們基于單片機的一些程序函數,比方說控制LED點亮熄滅、繼電器吸合斷開、LCD驅動等等。

那么這些呢,我一般稱為輸出型的函數。

輸出型函數我們是主導的角色,我們知道什么時候該調用它。

2.輸入型

輸入型呢,也稱為的是響應式的函數

什么叫響應式的函數呢?

比方說接收串口的數據,我們不知道什么數據什么時候來。

再比方說,我們按鍵檢測的函數,我們不知道什么時候會按下按鍵,那么這些就要定義成響應式函數來實現,而響應式函數就可以用回調函數來實現

所以通過這兩個種類型的分析啊,我們就可以知道,回調函數基本是用在輸入型的處理中。

比方說串口數據接收,那么數據是輸入到單片機里面的,單片機是處于從機角色。

按鍵檢測,按鍵狀態是輸入到單片機里的。

再比方說ADC值采集,ADC值也是輸入到單片機里的。

那么它們輸入的時間節點都是未知的,這些就能夠用回調函數來處理。

具體怎么處理后面我們會用代碼來給大家舉例。

回調函數還有一個作用就是為了封裝代碼

比如說做芯片或者模組的廠家,我們拿典型的STM32來舉例,像外部中斷、定時器、串口等中斷函數都是屬于回調函數,這種函數的目的是把采集到的數據傳遞給用戶,或者說應用層。

所以回調函數的核心作用是:

1.把數據從一個.c文件傳遞到另一個.c文件,而不用全局變量共享數據這么LOW的方法。

2.對于這種數據傳遞方式,回調函數更利于代碼的封裝。

四、掌握回調函數的程序編寫

前面說了很多概念性的東西,可能大家也比較難理解,回調函數最終呢是靠函數指針來實現的。

那么我這里通過一些模擬按鍵的例子來演示下怎么回通過調函數來處理它們。

下面是我們的c-free工程,用這個來模擬方便點:

c語言中回調函數的使用方法及作用是什么

從模塊化編程的思想來看,整個工程分為2個部分,應用層main.c文件,硬件層key.c和key.h文件。

不管再怎么復雜的程序,我們都要先從main函數一步步往下挖,main函數代碼如下。

int main(int argc, char *argv[])
{
KeyInit();
KeyScanCBSRegister(KeyScanHandle);
KeyPoll();
 
return 0;
}

KeyInit();是key.c文件的按鍵初始化函數

KeyScanCBSRegister(KeyScanHandle);是key.c的函數指針注冊函數。

這個函數可能大家會有點蒙,請跟進我們的節奏,下面開始燒腦環節,也是寫回調函數的必須步驟,

想理解這個回調函數注冊函數,我們要先從硬件層(key.h)頭文件的函數指針定義說起,具體看下圖。

c語言中回調函數的使用方法及作用是什么

這里自定義了一個函數指針類型,帶兩個形參。

然后,我們在key.c這個文件里定義了一個函數指針變量。

c語言中回調函數的使用方法及作用是什么

重點來了,我們就是通過這個函數指針,指向應用層的函數地址(函數名)

具體怎么實現指向呢?就是通過函數指針注冊函數。

c語言中回調函數的使用方法及作用是什么

這個函數是在main函數里調用,使用這種注冊函數的方式注冊靈活性也很高,你想要在哪個.c文件使用按鍵功能就在哪里調用。

c語言中回調函數的使用方法及作用是什么

這里要注意,main.c這個文件要定義一個函數來接收硬件層(key.c)過來的數據。

這里定義也不是亂定義的,一定要和那個自定義函數指針類型返回值、形參一致。

c語言中回調函數的使用方法及作用是什么

然后把這個函數名字直接復制給KeyScanCBSRegister函數的形參就可以了。

這樣調用后,我們key.c文件的pKeyScanCBS這個指針其實就是指向的KeyScanHandle函數。

也就是說執行pKeyScanCBS的時候,就是執行KeyScanHandle函數。

那具體檢測按鍵的功能就是KeyPoll函數,這個在main函數里調用。

c語言中回調函數的使用方法及作用是什么

當檢測到鍵盤有輸入以后,最終會調用pKeyScanCBS。

最終執行的是main.c文件的KeyScanHandle函數。

所以,我們來看下輸出結果。

c語言中回調函數的使用方法及作用是什么

如果還是有點模糊,下面我再給大家捋一捋編寫和使用回調函數的流程:

  1. 自定義函數指針,形參作為硬件層要傳到應用層的數據。

  2. 硬件層定義一個函數指針和函數指針注冊函數。

  3. 應用層定義一個函數,返回值和形參都要和函數指針一致。

  4. 應用層調用函數指針注冊函數,把定義好的函數名稱作為形參傳入。

Ok,這就是回調函數的使用。

如果還看不懂建議多看兩遍。

“c語言中回調函數的使用方法及作用是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

隆昌县| 紫云| 富蕴县| 兰考县| 洪江市| 桐柏县| 云和县| 台东县| 青川县| 四平市| 尼玛县| 如东县| 崇礼县| 金塔县| 荆门市| 拜城县| 肥西县| 丹阳市| 松阳县| 乐安县| 仁寿县| 韶关市| 邻水| 马山县| 门源| 长沙县| 汉寿县| 阿坝县| 玛纳斯县| 田东县| 安福县| 穆棱市| 通辽市| 沽源县| 信宜市| 溧阳市| 观塘区| 平顶山市| 和顺县| 康定县| 大连市|