函数指针在单片机中的应用

函数指针在单片机中的应用

一、回调函数

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();
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值