函数指针在单片机中的应用
一、回调函数
1、什么是回调函数
回调函数就是一个被作为参数传递的函数
2、创建、使用回调函数
#callback.c
/* 定义函数指针 */
typedef void(*transion_data_callback)(uint8_t data);
/* 申明一个函数指针 */
transion_data_callback transion_data_cbs;
/* 定义一个结构体 */
typedef struct
{
uint8_t sta; /* 设备状态 */
void (*callback)(uint8_t data);
}CALLBACK_T;
/* 初始化函数 */
void inti(uint8_t sta,
transion_data_callback ts_callback,
)
{
transion_data_cbs = ts_callback;
}
void callback_proc(void)
{
static uint8_t callback_data,sta;
if(transion_data_cbs != NULL)
transion_data_cbs(sta,callback_data);
}
#callbackhandle.c
/* 当transion_data_cbs被注册后,rev_data会通过callback_handle函数赋值 */
uint8_t rev_data;
void callback_handle(uint8_t data)
{
rev_data = data;
}
void callback_init(void)
{
static uint8_t sta;
inti(sta,callback_handle);//注册回调函数
}
二、结构体和函数指针的技巧
/* 创建一个枚举,和结构体中的index一一对应 */
typedef enum
{
disp1,
disp2,
disp3
}INDEX_TYPE;
/* 创建一个结构体 */
typedef struct
{
uint8_t index;
void (*disp)(void);
}DISP_T;
/* 创建一个当前的显示设备 */
DISP_T dev_disp_currnt;
static void disp_01(void);
static void disp_02(void);
static void disp_03(void);
/* 创建一个结构体数组 */
DISP_T disp_list[] =
{
{disp1,disp_01},
{disp2,disp_02},
{disp3,disp_03},
};
/* 显示设备运行流程
* 通过改变dev_disp_currnt.index的值来切换相对应的函数执行
*/
void disp_proc(void)
{
dev_disp_currnt = disp_list[dev_disp_currnt.index];
dev_disp_currnt.disp();
}
/* 显示函数01 */
void disp_01(void)
{
}
/* 显示函数02 */
void disp_02(void)
{
}
/* 显示函数03 */
void disp_03(void)
{
}
三、设备抽象
#include "led.h"
/* 把所有的灯装状态通过函数封装 */
/* 红灯初始化 */
void red_init(void)
{
}
/* 绿灯初始化 */
void green_init(void)
{
}
/* 红灯打开 */
void red_on(void)
{
}
/* 绿灯打开 */
void green_on(void)
{
}
/* 红灯关闭 */
void red_off(void)
{
}
/* 绿灯关闭 */
void green_off(void)
{
}
#include "ledhandle.h"
#include "led.h"
typedef enum
{
red,
green,
}LED_TYPE;
typedef enum
{
ON,
OFF
}LED_STATE;
typedef struct
{
uint8_t sta; /* 设备的状态 */
void (*on)(void);/* 开灯 */
void (*off)(void);/* 关灯 */
void (*init)(void);/* 初始化 */
}LED_T,*pLED;
pLED dev_red; /* 申明红灯设备 */
pLED dev_green; /* 申明绿灯设备 */
LED_T led_list[] =
{
{OFF,red_on,red_off,red_init},
{OFF,green_on,green_off,green_init},
};
pLED dev_led_open(LED_TYPE led_type)
{
return &led_list[led_type];
}
void dev_led_init(void)
{
dev_red = dev_led_open(red);
dev_red->init();
dev_green = dev_led_open(green);
dev_green->init();
}
void led_proc(void)
{
if(dev_red->sta == ON)
dev_red->on();
if(dev_red->sta == OFF)
dev_red->off();
if(dev_green->sta == ON)
dev_green->on();
if(dev_green->sta == OFF)
dev_green->off();
}