打印
[技术问答]

51单片机的回调函数+定时中断

[复制链接]
156|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
szt1993|  楼主 | 2025-4-24 23:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

​ 使用回调函数有个有点,就是可以在高一层定义回调,高一层不用调用低一层的代码,低一层直接调用高一层的回调来掉自己这一层的函数。

​ 我们使用回调函数就是把我们想调用的函数套一层壳子,下面总结下这层壳子要怎么封装和之前写的定时器中断整合在一起。

在定时器的驱动头文件中定义函数指针的类型;

typedef void(*Timer0_Callback)(void);
在定时器驱动C文件中定义函数指针的数组,用来注册函数;

static Timer0_Callback s_timer0_callbacks[MAX_CALLBACK_COUNT];
在初始化定时器中将函数指针的数组置空;

// 初始化时函数指针的数组置空
for (i = 0; i < MAX_CALLBACK_COUNT; i++){
   s_timer0_callbacks[i] = NULL;
}
写注册函数的函数,供外部调用

u8 Dri_Timer0_RegisterCallback(Timer0_Callback callback) {
    u8 i;
    for (i = 0; i < MAX_CALLBACK_COUNT; i++) {
        // 注册过,返回
        if (s_timer0_callbacks[i] == callback)  return 1;
    }

    // 没注册过,注册
    for (i = 0; i < MAX_CALLBACK_COUNT; i++) {
        if (s_timer0_callbacks[i] == NULL) {
            s_timer0_callbacks[i] = callback;
            return 1;
        }
    }
       
    return 0;
}
通过定时器执行注册过的函数

void Dri_Timer0_Func() interrupt 1 {
    u8 i;
    // 更新计数器中的数,保证下次还是1ms后触发
    TL0 = T1MS;          // 这个T1MS是宏定义,(65536 - 11059200 / 12 / 1000)
    TH0 = T1MS >> 8;

    // 调用所有的回调函数
    for(i = 0; i<MAX_CALLBACK_COUNT; i++){
        if (s_timer0_callbacks[i]) s_timer0_callbacks[i]();
    }
}
使用时,初始化定时器,调用注册回调函数将我们想实现的逻辑放进去就行了

// 代码略
定时器中断可以用来解决之前的延时问题,使用起来很灵活,可根据实际情况操作,可以代替延时函数实现按键消抖、数码管的计数等,通过回调函数可以对定时器中断作优化,也很灵活,需要多多练习。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

321

主题

2514

帖子

6

粉丝