51定时器控制4个led,使用回调函数机制

发布时间:2024-04-15  

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


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


  1 #include        //头文件

  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] = {0};        //定时器结构数组

 17 int gMyTimerMessage[MY_TIMER_MAX] = {0};        //定时器消息数组

 18 

 19 sbit LED1=P2^0;

 20 sbit LED2=P2^1;

 21 sbit LED3=P2^2;

 22 sbit LED4=P2^3;

 23 sbit LED5=P2^4;

 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 -1;

 31     myTimerList[index].on = 1;

 32     myTimerList[index].is_period = is_period;

 33     myTimerList[index].time_out = time_out;

 34     myTimerList[index].count = 0;

 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 = 0;

 43     on = !on;

 44     LED1 = on;

 45 }

 46 void led_2_ctrl(void)

 47 {

 48     static char on = 0;

 49     on = !on;

 50     LED2 = on;

 51 }

 52 void led_3_ctrl(void)

 53 {

 54     static char on = 0;

 55     on = !on;

 56     LED3 = on;

 57 }

 58 void led_4_ctrl(void)

 59 {

 60     static char on = 0;

 61     on = !on;

 62     LED4 = on;

 63 }

 64 

 65 void led_5_ctrl(void)

 66 {

 67     static char on = 0;

 68     on = !on;

 69     LED5 = on;

 70 }

 71 

 72 void Init_Timer0(void)    //初始化定时器0

 73 {

 74     TMOD=0x01;                //定时器0,使用模式1,16位定时器

 75     TH0=(65536-1000)/256;    //给定初值

 76     TL0=(65536-1000)%256;

 77     EA=1;        //打开总中断

 78     ET0=1;        //打开定时器中断

 79     TR0=1;        //开定时器

 80 }

 81 

 82 void main(void)    //主函数

 83 {

 84     unsigned int i;

 85 

 86     ALL_ON;

 87     

 88     CreatTimer(0,250,1,led_1_ctrl);

 89     CreatTimer(1,500,1,led_2_ctrl);

 90     CreatTimer(2,1000,1,led_3_ctrl);

 91     CreatTimer(3,2000,1,led_4_ctrl);

 92     //CreatTimer(4,4000,1,led_5_ctrl);

 93 

 94     Init_Timer0();    //初始化定时器0

 95     while(1)

 96     {

 97         for(i = 0; i

 98         {

 99             if(gMyTimerMessage[i])            //定时器消息来到,启动。

100             {

101                 gMyTimerMessage[i] = 0;        //消息清除

102                 if(callback[i] != NULL)

103                 {

104                     (*callback[i])();        //调用回调函数

105                 }                

106             }

107         }

108     }

109 }

110 

111 //定时器中断函数,1ms 定时。

112 void Timer0_isr(void) interrupt 1

113 {

114     unsigned int i = 0;

115 

116 

117     TH0=(65536-1000)/256;//重新赋值 1ms

118     TL0=(65536-1000)%256;

119 

120     EA = 0;

121     for(i = 0; i

122     {

123         if(myTimerList[i].on)        //如果定时开启

124         {

125             ++(myTimerList[i].count);                                //计数++

126             if(myTimerList[i].count >= myTimerList[i].time_out)        //定时到

127             {

128                 gMyTimerMessage[i] = 1;                                //发消息,在main函数中会用到

129                 if(myTimerList[i].is_period)                        //是否周期循环

130                 {

131                     myTimerList[i].count = 0;                        //计数重置

132                 }

133                 else

134                 {

135                     myTimerList[i].on = 0;                            //关掉定时器

136                 }

137             }

138         }

139     }

140     EA = 1;

141 }


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>