在编程中,我们常常会遇到回调函数这个概念,但它到底是如何工作的呢?
一、理解回调函数
回调函数的“幕后故事”
回调函数,顾名思义,就是被调用的函数。
想象一下,程序就像一场交响乐演出,而回调函数就是指挥家手中的指令,指挥乐队在合适的时刻演奏。听起来很酷吧?但是,如何才能让指挥家在准确的时刻发出指令呢?这就涉及到回调函数的机制了。
关键角色
-
中间函数(高阶函数):这个中间人负责接收你的请求,并安排执行回调。它像是一个安排任务的人,负责调度回调函数的执行。
-
回调函数:回调函数就像是执行任务的“员工”。它不直接由调用者启动,而是间接的被中间人调用来执行。
二、回调函数的实际应用
应用层代码示例、
LED_Flip就作为回调函数,被中间函数LED_FUN调用
调用方向:中间函数LED_FUN指向LED_Flip
typedef struct
{
void (*LED_Fun)(uint8_t,void(*Callback)(uint8_t));
} LED_t;
解释:
1、新定义一个结构体类型:类型是LED_t,其中包含一个成员变量 LED_Fun,LED_Fun是一个函数指针,指向的函数就是void LED_Fun(uint8_t, void(*Callback)(uint8_t))。
2、函数指针 LED_Fun
会指向一个接受 uint8_t
类型参数,并且第二个参数是一个指向另一个函数(Callback
)的指针的函数。
3、这个Callback函数就是回调函数
LED.c
#include "MyApplication.h"
static void LED_FUN(LED_NUM_t,void(*callback)(LED_NUM_t));
//初始化变量LED
LED_Mid_t LED=
{
LED_FUN,
};
static void LED_FUN(LED_NUM_t led,void(*callback)(uint8_t))
{
//调用回调函数
(*callback)(led);
}
//定义底层函数
void LED_Init(LED_NUM_t led)
{
//³õʼ»¯LED
HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_RESET);
}
void LED_Open(LED_NUM_t led){
switch(led){
case LED1:
HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET);
break;
case LED2:
HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET);
break;
case LED3:
HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_SET);
break;
}
}
void LED_Close(LED_NUM_t led){
switch(led){
case LED1:
HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);
break;
case LED2:
HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_RESET);
break;
case LED3:
HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin,GPIO_PIN_RESET);
break;
}
}
void LED_Toggle(LED_NUM_t led)
{
switch(led){
case LED1:
HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
break;
case LED2:
HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);
break;
case LED3:
HAL_GPIO_TogglePin(LED3_GPIO_Port,LED3_Pin);
}
}