程序转载自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. Mantis查看问题列表的列名修改_"P","#"两列

    在使用mantis的时候,点击菜单上的“查看问题”进去,就会罗列出当前的bug列表,可是列表的标题上存在着“P”和“#”的显示,个人觉得这两列在这里完全没有意义,或者说现有的显示使人觉得疑惑,究竟代表 ...

  2. jvm 的性能调优

    一个描述的比较生动的博客:JVM内存区域划分Eden Space.Survivor Space.Tenured Gen,Perm Gen解释 地址:https://www.cnblogs.com/sg ...

  3. Python类三种方法,函数传参,类与实例变量(一)

    1 Python的函数传递: 首先所有的变量都可以理解为内存中一个对象的'引用' a = 1 def func(a): a = 2 func(a) print(a) # 1 a = 1 def fun ...

  4. apache-实战(二)

    Apache 虚拟主机 --用apache或nginx就可以做 一台服务器跑多台web服务 VPS virtual private server 虚拟专用服务器 --使用虚拟化技术来做 云服务器 虚拟 ...

  5. shell中和RDA中的alert日志中文乱码

    客户端字符集无法识别中文,只能下载到本机使用nodepad++查看

  6. VMware,win7与linux centos6.4文件互传,linux下挂载windows共享文件夹,vmware tools安装方法

    本方法是以win7,VMware9.0.1 ,centos6.4为基础实验的. 对于linux的初级使用阶段,都会Windows中使用linux虚拟机VMWare或者其它的.在Windows与linu ...

  7. bzoj1965 [Ahoi2005]洗牌

    Description 为了表彰小联为Samuel星球的探险所做出的贡献,小联被邀请参加Samuel星球近距离载人探险活动. 由于Samuel星球相当遥远,科学家们要在飞船中度过相当长的一段时间,小联 ...

  8. 2018.11.25 struts2与OGNL表达式的结合(高级)

    两者的结合原理 底层源码分析 栈原理 先进后出 我们的valuestack其实是一个接口 在实现类中有这个参数 CompoundRoot的类继承的是ArrayList,具体实现弹栈和压栈的方法具体实现 ...

  9. Android学习笔记_71_Android 多个项目之间如何引用 项目怎样打jar包

    一.将整个项目作为资源文件 1.需要将被应用的项目设置为库项目. 2.将该项目的配置文件中的四大组件清空,例如下面代码: <?xml version="1.0" encodi ...

  10. [转]Matlab2012b安装详解

    matlab2012b安装文件下载: http://yunpan.cn/cVY5VsSeUXzai (提取码:ec84) 1.双击setup.exe进行安装.安装中选择“不使用Internet安装” ...