程序转载自51hei,经过自己的实际验证,多了一种编程的思路技能,回调函数的基本思想也是基于事件机制的,哪个事件来了, 就执行哪个事件。

程序中,最多四个子定时器,说明51的处理速度是不够的,在中断中添加过多的代码会定时不准确。自己实验了5个,第五个想要定时4秒,实际差不多有5秒了,因此中断里面是代码越少越好~~

 #include<reg52.h>        //头文件
#define MY_TIMER_MAX (4) //最多四个定时器
#define NULL (0) typedef void (*pFun)(void); //callback 函数指针类型
typedef struct myTimer
{
char on; //开关
char is_period; //是否周期循环
unsigned int time_out; //定时时间,单位ms
unsigned int count; //定时计数用
}
MY_TIMER; pFun callback[MY_TIMER_MAX] = {NULL}; //定时器回调函数数组
MY_TIMER myTimerList[MY_TIMER_MAX] = {}; //定时器结构数组
int gMyTimerMessage[MY_TIMER_MAX] = {}; //定时器消息数组 sbit LED1=P2^;
sbit LED2=P2^;
sbit LED3=P2^;
sbit LED4=P2^;
sbit LED5=P2^; #define ALL_ON {LED1=0;LED2=0;LED3=0;LED4=0;LED5=0;} //灯全开 //创建定时器,简化版本。
int CreatTimer(int index,unsigned short int time_out,char is_period,pFun callbackFun)
{
if(index >= MY_TIMER_MAX) return -;
myTimerList[index].on = ;
myTimerList[index].is_period = is_period;
myTimerList[index].time_out = time_out;
myTimerList[index].count = ;
callback[index] = callbackFun;
return index;
} //四个LED控制函数,on初始是0,第一次调用on变为1,是关灯。
void led_1_ctrl(void)
{
static char on = ;
on = !on;
LED1 = on;
}
void led_2_ctrl(void)
{
static char on = ;
on = !on;
LED2 = on;
}
void led_3_ctrl(void)
{
static char on = ;
on = !on;
LED3 = on;
}
void led_4_ctrl(void)
{
static char on = ;
on = !on;
LED4 = on;
} void led_5_ctrl(void)
{
static char on = ;
on = !on;
LED5 = on;
} void Init_Timer0(void) //初始化定时器0
{
TMOD=0x01; //定时器0,使用模式1,16位定时器
TH0=(-)/; //给定初值
TL0=(-)%;
EA=; //打开总中断
ET0=; //打开定时器中断
TR0=; //开定时器
} void main(void) //主函数
{
unsigned int i; ALL_ON; CreatTimer(,,,led_1_ctrl);
CreatTimer(,,,led_2_ctrl);
CreatTimer(,,,led_3_ctrl);
CreatTimer(,,,led_4_ctrl);
//CreatTimer(4,4000,1,led_5_ctrl); Init_Timer0(); //初始化定时器0
while()
{
for(i = ; i<MY_TIMER_MAX; ++i)
{
if(gMyTimerMessage[i]) //定时器消息来到,启动。
{
gMyTimerMessage[i] = ; //消息清除
if(callback[i] != NULL)
{
(*callback[i])(); //调用回调函数
}
}
}
}
} //定时器中断函数,1ms 定时。
void Timer0_isr(void) interrupt
{
unsigned int i = ; TH0=(-)/;//重新赋值 1ms
TL0=(-)%; EA = ;
for(i = ; i<MY_TIMER_MAX; ++i)
{
if(myTimerList[i].on) //如果定时开启
{
++(myTimerList[i].count); //计数++
if(myTimerList[i].count >= myTimerList[i].time_out) //定时到
{
gMyTimerMessage[i] = ; //发消息,在main函数中会用到
if(myTimerList[i].is_period) //是否周期循环
{
myTimerList[i].count = ; //计数重置
}
else
{
myTimerList[i].on = ; //关掉定时器
}
}
}
}
EA = ;
}

51定时器控制4各led,使用回调函数机制的更多相关文章

  1. 定时器控制单只LED灯

    点击查看代码 #include <reg51.h> #define uchar unsigned char #define uint unsigned int sbit LED=P0^0; ...

  2. android中回调函数机制完全解析

    1.在要调用的业务操作中,创建一个接口,在接口中创建方法,这个方法表示的是我们原先要在业务类中执行的操作 public interface BackUpSmsListener { /** * 设置总进 ...

  3. 浅谈js回调函数

    回调函数原理: 我现在出发,到了通知你”这是一个异步的流程,“我出发”这个过程中(函数执行),“你”可以去做任何事,“到了”(函数执行完毕)“通知你”(回调)进行之后的流程 例子 1.基本方法 ? 1 ...

  4. js中的回调函数 和promise解决异步操作中的回调地狱问题。

    回调函数 : 函数作为参数传递到另外一个函数中.简单数据类型和引入数据类型中的数组和对象作为参数传递大家肯定都不陌生,其实引用数据类型中的函数也是可以的. 事实上大家见到的很多,用到的也很多,比如jQ ...

  5. C++ 回调函数的定义与用法

    一回调函数 我们经常在C++设计时通过使用回调函数可以使有些应用(如定时器事件回调处理.用回调函数记录某操作进度等)变得非常方便和符合逻辑,那么它的内在机制如何呢,怎么定义呢?它和其它函数(比如钩子函 ...

  6. C++回调函数的应用<转自:http://blog.csdn.net/wubin1124/article/details/4386269>

    一回调函数 我们经常在C++设计时通过使用回调函数可以使有些应用(如定时器事件回调处理.用回调函数记录某操作进度等)变得非常方便和符合逻辑,那么它的内在机制如何呢,怎么定义呢?它和其它函数(比如钩子函 ...

  7. JS之回调函数(callback)

    1.什么是回调函数? -- 简单点说,一个函数被作为参数传递给另一个函数(在这里我们把另一个函数叫做"otherFunction"),回调函数在otherFunction中被调用. ...

  8. 回调函数的原理及PHP实例

    背景:在最近的一个开发项目中,用户要先调用服务才能开始进行一系列的查询活动,想了好久,经同事提醒, 用回调函数即可解决该问题.在这里,对PHP下回调函数的原理及实现分别做一下讲解. 1 什么是回调 软 ...

  9. C++回调函数的理解与使用

    一.回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数.回调函数不是由该函数的实现方直接调用,而是在 ...

随机推荐

  1. js常用函数汇总(不定期更新)

    1.图片按比例压缩 function setImgSize(){ var outbox_w=imgbox.width(), outbox_h=imgbox.height(); imgbox.find( ...

  2. Kubernetes API server工作原理

    作为Kubernetes的使用者,每天用得最多的命令就是kubectl XXX了. kubectl其实就是一个控制台,主要提供的功能: 1. 提供Kubernetes集群管理的REST API接口,包 ...

  3. 从并发和索引说说innodb和myisam的区别

    一.引言 这个问题看似是个很俗气的问题,但是在面试中也是个经常被问到的问题.我想很多人都能说出几条,比如事物,外键,等等.但是我想这样想起一点说一句这么回答的话,知识其实都是分散的,这样就显得不是很高 ...

  4. datatable Left and right fixed columns

    $(document).ready(function() { var table = $('#example').DataTable( { scrollY: "300px", sc ...

  5. ZOJ 3379 Master Spark

    计算出中轴能覆盖到某个点的极角范围,最大覆盖次数即是答案. 首先把中轴和点重合,此时中轴的角度为theta = atan(y/x), 然后以原点为圆心旋转点和抛物线相交求出之间的夹角, 把x = a* ...

  6. 2019年5月训练记录(更新ing)

    前言 \(ZJOI\)正式结束了. 但期中考试只考了年级\(216\),退役既视感... 于是就被抓回去补文化课了. 下半个学期可能要以文化课为主了吧! 但周三.周日应该还是会正常参加训练的,但其他时 ...

  7. 利用firebug 查看JS方法, JS 调试

    “DOM” 可以查看变量和方法. “脚本”可以用来调试js方法. 有空总结一下白鹤堂老师的最牛JavaScript.

  8. 【luogu P2324 [SCOI2005]骑士精神】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2324 不懂怎么剪枝,所以说,,我需要氧气.. 第一道A* // luogu-judger-enable-o2 ...

  9. C#位数不足补零

    C#位数不足补零:int i=10;方法1:Console.WriteLine(i.ToString("D5"));方法2:Console.WriteLine(i.ToString ...

  10. Xcode DeviceSupport

    问题:Could not locate device support files. This iPhone 6s is running iOS 12.1 (16B5059d), which may n ...