C語言中回調函數的使用詳情

下文將學習到;

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

1.程序架構

一個好的程序架構至少要達到以下要求:

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

用專業術語描述就是可移植性、可擴展性。

在51單片機寫程序時,基本上一個.c文件解決,包括寄存器配置,產品功能。到瞭stm32時,我們會把不同的外設功能,比如led,按鍵,串口等外設功能代碼分別寫在不同的.c文件裡,然後統一用函數接口去調用它,比方說控制一個LED燈亮,直接在led.c文件裡寫一個驅動led燈狀態的函數然後給外部調用就好瞭。硬件層和應用層代碼分開,應用層用硬件層提供的接口來控制,而且不會有硬件層和應用層共享的全部變量或數組。
還有一種情況,應用程序需要收集硬件層的數據,比如串口接收數據,按鍵采集,adc值采集,這種值應該怎麼樣從硬件層獲取呢?
簡單的方法就是用全局變量或者數組,比方說硬件層串口接收到數據瞭,那麼我們把數據丟到數組裡面,然後把接收完成的全局變量標志置為1,比方說全局變量名為RcvFlag,然後應用層程序會輪詢判斷RcvFlag==1?是的話就把數組裡面的數據取出來解析。
但是這種方法存在實時性差和移植性差的問題,比如說需要把串口的硬件層封裝起來給客戶使用,不能讓客戶看到實現的源碼,隻能提供函數接口給客戶使用,不可能通過告訴客戶先判斷哪個變量為1,然後在取哪個數組中的數據這種做法。
在這裡就需要回調函數瞭。

2.回調函數的作用

在stm32中,像外部中斷、定時器中斷、串口中斷都有點類似回調函數,這種函數的目的是把采集到的數據傳遞給cpu使用。

回調函數的核心作用:

  • 把數據從一個.c文件傳遞到另一個.c文件。

3.掌握回調函數的程序編寫

傳統寫法的缺點:

  • 1、移植性差
  • 2、實時性差
  • 3、功能代碼封裝難

回調函數寫法:

main.c代碼:

#include <stdio.h>
#include "key.h" 

void KeyScanHandle(KEY_ID_TYPEDEF KeyID,KEY_STATE_TYPEDEF KeyState)
{
//    if(KeyID == KEY2)
//    {
//        if(KeyState = KEY_PRESS)
//        {
            
            printf("KeyID=%d, KeyState=%d\r\n",KeyID,KeyState);
//        }
//    }
}

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

key.c代碼:

#include "key.h"

KEY_ID_TYPEDEF keyVal;    //按鍵ID
KEY_STATE_TYPEDEF keyState;    

pKeyScanCallBack pKeyScanCBS;

void KeyInit()
{
    keyVal = 0;
    keyState = KEY_IDLE;
    pKeyScanCBS = 0;
} 

void KeyScanCBSRegister(pKeyScanCallBack pCBS)
{
    if(pKeyScanCBS == 0)
    {
        pKeyScanCBS = pCBS;
    }
}

void KeyPoll()
{
    printf("Please Enter key value:");
    if(scanf("%d",&keyVal)==1)
    {
        printf("\r\n");
        printf("Please enter key state:");
        if(scanf("%d",&keyState)==1)
        {
            if(pKeyScanCBS != 0)
            {
                pKeyScanCBS(keyVal,keyState);
            }
        }        
    }
}

key.h代碼:

#ifndef _KEY_H_
#define _KEY_H_
typedef enum 
{
    KEY1,
    KEY2,    
}KEY_ID_TYPEDEF;

typedef enum
{
    KEY_IDLE,    //空閑 
    KEY_PRESS,    //按鍵短按
    KEY_LONG_PRESS,    //按鍵長按
    KEY_RELEASE,//按鍵釋放
 
}KEY_STATE_TYPEDEF; 

typedef void (*pKeyScanCallBack)(KEY_ID_TYPEDEF KeyID,KEY_STATE_TYPEDEF KeyState);
 
void KeyInit();
void KeyPoll();
void KeyScanCBSRegister(pKeyScanCallBack pCBS);
#endif

4.回調函數在產品中的應用

根據收到的不同幀內容,做出不同的功能

到此這篇關於C語言中回調函數的使用詳情的文章就介紹到這瞭,更多相關C語言回調函數內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: