程序转载自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. 功能强大的系统配置工具-- Siebel Tools

    Siebel Tools 是Siebel 为其CRM产品开发人员专门提供的系统配置工具,系统的客户化修改以及系统升级控制等都是通过该工具进行配置(Configuration) .该工具直接修改Sieb ...

  2. 【Leetcode】【Easy】Valid Palindrome

    Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignori ...

  3. 如何在SAP CRM里创建和消费Web service

    Created by Wang, Jerry, last modified on Dec 19, 2014 The following steps demonstrates how to expose ...

  4. ubuntu 14.04 64位使用google官方android开发集成工具adt-64位无法使用adb

    在使用ubuntu64位(14.04)时,下载来一个adt-bundle-linux-x86_64-20131030.zip,但是运行时报错: Android: Gradle: Execution f ...

  5. C# .Net Framework4.5中配置和使用managedCUDA及常见问题解决办法

    主要参考英文帖子.我就不翻译了哈.很容易懂的. 先说明我的运行平台: 1.IDE:Visual Studio 2012 C# .Net Framework4.5,使用默认安装路径: 2.显卡类型:NV ...

  6. OsharpNS轻量级.net core快速开发框架简明入门教程-Osharp.Hangfire使用

    OsharpNS轻量级.net core快速开发框架简明入门教程 教程目录 从零开始启动Osharp 1.1. 使用OsharpNS项目模板创建项目 1.2. 配置数据库连接串并启动项目 1.3. O ...

  7. ubuntu14.04下搜狗拼音输入法不正常的解决方法

    在终端输入ibus-daemon –drx命令,可以解决该问题.

  8. Could..... not preload global game manager

    发布PC版后出现这个错误,是没有破解成功,卸载后重新安装破解就可以了 http://www.cocoachina.com/bbs/read.php?tid=84587

  9. android 网络技术基础学习 (七)

    使用httpclient协议访问网络: public class MainActivity extends Activity implements OnClickListener{ public vo ...

  10. python使用sqlalchemy连接mysql数据库

    环境:centos7+python2.7.5+sqlalchemy sqlalchemy是python当中比较出名的orm程序.在python中,使用sqlalchemy连接mysql数据库进行操作非 ...