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

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

  1. #include<reg52.h> //头文件
  2. #define MY_TIMER_MAX (4) //最多四个定时器
  3. #define NULL (0)
  4.  
  5. typedef void (*pFun)(void); //callback 函数指针类型
  6. typedef struct myTimer
  7. {
  8. char on; //开关
  9. char is_period; //是否周期循环
  10. unsigned int time_out; //定时时间,单位ms
  11. unsigned int count; //定时计数用
  12. }
  13. MY_TIMER;
  14.  
  15. pFun callback[MY_TIMER_MAX] = {NULL}; //定时器回调函数数组
  16. MY_TIMER myTimerList[MY_TIMER_MAX] = {}; //定时器结构数组
  17. int gMyTimerMessage[MY_TIMER_MAX] = {}; //定时器消息数组
  18.  
  19. sbit LED1=P2^;
  20. sbit LED2=P2^;
  21. sbit LED3=P2^;
  22. sbit LED4=P2^;
  23. sbit LED5=P2^;
  24.  
  25. #define ALL_ON {LED1=0;LED2=0;LED3=0;LED4=0;LED5=0;} //灯全开
  26.  
  27. //创建定时器,简化版本。
  28. int CreatTimer(int index,unsigned short int time_out,char is_period,pFun callbackFun)
  29. {
  30. if(index >= MY_TIMER_MAX) return -;
  31. myTimerList[index].on = ;
  32. myTimerList[index].is_period = is_period;
  33. myTimerList[index].time_out = time_out;
  34. myTimerList[index].count = ;
  35. callback[index] = callbackFun;
  36. return index;
  37. }
  38.  
  39. //四个LED控制函数,on初始是0,第一次调用on变为1,是关灯。
  40. void led_1_ctrl(void)
  41. {
  42. static char on = ;
  43. on = !on;
  44. LED1 = on;
  45. }
  46. void led_2_ctrl(void)
  47. {
  48. static char on = ;
  49. on = !on;
  50. LED2 = on;
  51. }
  52. void led_3_ctrl(void)
  53. {
  54. static char on = ;
  55. on = !on;
  56. LED3 = on;
  57. }
  58. void led_4_ctrl(void)
  59. {
  60. static char on = ;
  61. on = !on;
  62. LED4 = on;
  63. }
  64.  
  65. void led_5_ctrl(void)
  66. {
  67. static char on = ;
  68. on = !on;
  69. LED5 = on;
  70. }
  71.  
  72. void Init_Timer0(void) //初始化定时器0
  73. {
  74. TMOD=0x01; //定时器0,使用模式1,16位定时器
  75. TH0=(-)/; //给定初值
  76. TL0=(-)%;
  77. EA=; //打开总中断
  78. ET0=; //打开定时器中断
  79. TR0=; //开定时器
  80. }
  81.  
  82. void main(void) //主函数
  83. {
  84. unsigned int i;
  85.  
  86. ALL_ON;
  87.  
  88. CreatTimer(,,,led_1_ctrl);
  89. CreatTimer(,,,led_2_ctrl);
  90. CreatTimer(,,,led_3_ctrl);
  91. CreatTimer(,,,led_4_ctrl);
  92. //CreatTimer(4,4000,1,led_5_ctrl);
  93.  
  94. Init_Timer0(); //初始化定时器0
  95. while()
  96. {
  97. for(i = ; i<MY_TIMER_MAX; ++i)
  98. {
  99. if(gMyTimerMessage[i]) //定时器消息来到,启动。
  100. {
  101. gMyTimerMessage[i] = ; //消息清除
  102. if(callback[i] != NULL)
  103. {
  104. (*callback[i])(); //调用回调函数
  105. }
  106. }
  107. }
  108. }
  109. }
  110.  
  111. //定时器中断函数,1ms 定时。
  112. void Timer0_isr(void) interrupt
  113. {
  114. unsigned int i = ;
  115.  
  116. TH0=(-)/;//重新赋值 1ms
  117. TL0=(-)%;
  118.  
  119. EA = ;
  120. for(i = ; i<MY_TIMER_MAX; ++i)
  121. {
  122. if(myTimerList[i].on) //如果定时开启
  123. {
  124. ++(myTimerList[i].count); //计数++
  125. if(myTimerList[i].count >= myTimerList[i].time_out) //定时到
  126. {
  127. gMyTimerMessage[i] = ; //发消息,在main函数中会用到
  128. if(myTimerList[i].is_period) //是否周期循环
  129. {
  130. myTimerList[i].count = ; //计数重置
  131. }
  132. else
  133. {
  134. myTimerList[i].on = ; //关掉定时器
  135. }
  136. }
  137. }
  138. }
  139. EA = ;
  140. }

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. Excel VBA 复制

    将 Sheet1 复制到 Sheet3 后面时,实现方法如下: Worksheets("Sheet1").Copy After:=Worksheets("Sheet3&q ...

  2. vue v-on 带参事件

    1.js代码 var list=[ //定义一个数组 {title:} ] var box=new Vue({ el:'.box', data:{ list:list }, methods:{ //d ...

  3. NO.004-2018.02.09《离思五首·其四》唐代:元稹

    离思五首·其四_古诗文网 离思五首·其四 唐代:元稹 曾经沧海难为水,除却巫山不是云.曾经到临过沧海,别处的水就不足为顾:除了巫山,别处的云便不称其为云.曾经:曾经到临.经:经临,经过.难为:这里指“ ...

  4. python接口测试-项目实践(七)脚本优化

    七 脚本优化:重复代码的提取成函数:与项目接口相关的都封装到一个类中:添加手工验证脚本,增加输入值的判断逻辑 将所有与该项目接口相关的封装成类 class ProjectApi: #3个数据源接口 d ...

  5. Android(java)学习笔记24:自定义异常类

    1. 自定义异常: 考试成绩必须在0-100之间 很明显java没有对应的异常,需要我们自己来做一个异常 自定义异常 继承自Exception 继承自RuntimeException 下面是一个代码示 ...

  6. Android仿QQ复制昵称效果

    本文同步自http://javaexception.com/archives/76 背景: 这几天做一个复制文本的需求,突然看到QQ上复制昵称跟QQ号的效果,觉得很不错,就想要模仿一波,办法比较简单粗 ...

  7. PowerShell实现英汉互译_并保存

    代码如下:(介于着色 代码在文末下载) 功能简介: 自动识别英汉输入 返回结果 对于词数小于20的会保存在当前目录下temp_table.txt词文件 大于20的会被识别为句子进行互译 不会存于词文件 ...

  8. putty 启动 linux 下的oracle

    没搞过linux ,仅作记录: 1 打开putty.exe 程序 ,选择 连接 2 输入linux 的用户名和密码后,按下图操作: 3  启动监听 4 命令总结: 1.  sudo su - orac ...

  9. SqlSugar批量添加修改问题

    直接InsertRange空集合会报错,如果我们是同时执行多个添加或修改,不要共用一个上下文,最好是在方法里面声明上下文进行区分,不然容易报错 //如果同时执行多个添加,更新 操作不要共用一个上下文, ...

  10. 用HTML写伪类选择器,结构伪类选择器,伪元素选择器样式

    html,css lorem乱序铭文 Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nesciunt, nihil? Lorem ...