搜索

[程序源码] 真正的单片机程序框架------->小巧的软件定时器....O(∩_∩)O

[复制链接]
25096|101
 楼主 | 2021-2-25 09:23 | 显示全部楼层 |阅读模式
本帖最后由 misra 于 2021-3-11 20:13 编辑

#申请原创#

还在用各种标志位 全局变量搞定时器,换种更优雅的方式吧
好了首先搞个需求引入 软件定时器的这个话题吧。

需求1:让4个任务分别以1000ms、500ms、500ms、800ms周期性执行。怎么弄
直接给出需求1的代码:
/*-----------------------------------------------------*/
void test1(void)
{
    MLPeriod.init();
    while (1) {
        MLPeriod.run();
        if (MLPeriod.check(1000)) {
            //task1
        }
        if (MLPeriod.check(500)) {
            //task2
        }
        if (MLPeriod.check(500)) {
            //task3
        }
        if (MLPeriod.check(800)) {
            //task4
        }
    }
}

/*-----------------------------------------------------*/
需求2让20个变量,分别以111,111,123,127,118,99,88,58,58,47,33,38,29,1111,2456,678,6789,457,451,20毫秒 周期性变化
                怎么弄?
直接给出应用代码:
/*-----------------------------------------------------*/
ml_u32_t var[20] = {0}; //20个变量
ml_u32_t init_period[20] = {111, 111, 123, 127, 118, 99, 88, 58, 58, 47, 33, 38, 29, 1111, 2456, 678, 6789, 457, 451, 20}; //20个变量的周期值
void test (void)
{
    ml_u32_t j;
    MLPeriod.init();
    while (1) {
        MLPeriod.run();
        for (j = 0; j < 20; j++) {
            if (MLPeriod.check(init_period[j])) {
                var[j]++;
            }
        }
    }
}

/*-----------------------------------------------------*/


代码是不是看起来很简单 没错!使用起来就是这么简单。

源码在1楼
有疑问或者建议请跟帖回复。

使用特权

评论回复

相关帖子

 楼主 | 2021-2-25 09:41 | 显示全部楼层
本帖最后由 misra 于 2021-3-13 19:42 编辑

1楼占个位
源码链接(21IC这个超链接似乎不好用,大家费点事,复制粘贴吧):
https://github.com/steven-lyan/microLite_timer/blob/main/src/microLite_timer.h
https://github.com/steven-lyan/microLite_timer/blob/main/src/microLite_timer.c




移植到51单片机的视频电脑浏览器 单击鼠标全屏):
keil51_Simulator.gif

更多内容可关注微信公众号:microLite裸机系统
无标题.png

如果有空的话 ,可以去50楼逛一逛。



使用特权

评论回复
| 2021-2-25 09:48 | 显示全部楼层
  1. //1ms定时中断
  2. u16 g_usTick;
  3. void ISR_1ms(void)
  4. {
  5.         g_usTick++;
  6. }

  7. u16 GetCurTick(void)
  8. {
  9.         u16 ulTmp;
  10.         __disable_int();
  11.         ulTmp = g_usTick;
  12.         __enable_int();
  13.         return ulTmp;
  14. }



  15. u16 g_TaskVal[20];
  16. u16 g_TaskBase[20] = {0};
  17. const u16 TASK_IVL[20] = {111,456,123,127,118,99,88,77,58,47,33,38,29,1111,2456,678,6789,457,451,20};



  18. void main(void)
  19. {
  20.         Init();
  21.        
  22.         while (1)
  23.         {
  24.                 u8 i;
  25.                
  26.                 for (i=0; i<20; i++)
  27.                 {
  28.                         if (GetCurTick() - g_TaskBase[i] >= TASK_IVL[i])
  29.                         {
  30.                                 g_TaskVal[i]++;
  31.                                 g_TaskBase[i] += TASK_IVL[i];
  32.                         }
  33.                 }
  34.                
  35.         }
  36. }
复制代码

使用特权

评论回复
 楼主 | 2021-2-25 10:02 | 显示全部楼层

一看就是很牛的了

再给你来个

一个灯  亮3秒后 灭,111ms后亮,88ms后灭,999ms后亮

使用特权

评论回复
| 2021-2-25 10:11 | 显示全部楼层
misra 发表于 2021-2-25 10:02
一看就是很牛的了

再给你来个
  1. void main(void)
  2. {
  3.         Init();
  4.        
  5.         while (1)
  6.         {
  7.                 u8 i;
  8.                
  9.                 for (i=0; i<20; i++)
  10.                 {
  11.                         if (GetCurTick() - g_TaskBase[i] >= TASK_IVL[i])
  12.                         {
  13.                                 g_TaskVal[i]++;
  14.                                 g_TaskBase[i] += TASK_IVL[i];
  15.                         }
  16.                 }
  17.                
  18.                 if (1)
  19.                 {
  20.                         void LED_Ctrl(void);
  21.                         LED_Ctrl();
  22.                 }
  23.         }
  24. }


  25. //一个灯  亮3秒后 灭,111ms后亮,88ms后灭,999ms后亮
  26. void LED_Ctrl(void)
  27. {
  28.         static u8 s_ucLedStage = 0;
  29.         static u16 s_ulBase;
  30.         static bLed;
  31.        
  32.         switch(s_ucLedStage)
  33.         {
  34.                 case 0:
  35.                 bLed = 1;
  36.                 if (GetCurTick() - s_ulBase >= 3000)
  37.                 {
  38.                         bLed = 0;
  39.                         s_ucLedStage++;
  40.                         s_ulBase = GetCurTick();
  41.                 }
  42.                 break;
  43.                
  44.                 case 1:
  45.                 if (GetCurTick() - s_ulBase >= 111)
  46.                 {
  47.                         bLed = 1;
  48.                         s_ucLedStage++;
  49.                         s_ulBase = GetCurTick();
  50.                 }
  51.                 break;
  52.                
  53.                 case 2:
  54.                 if (GetCurTick() - s_ulBase >= 88)
  55.                 {
  56.                         bLed = 0;
  57.                         s_ucLedStage++;
  58.                         s_ulBase = GetCurTick();
  59.                 }
  60.                 break;
  61.                
  62.                 case 3:
  63.                 if (GetCurTick() - s_ulBase >= 999)
  64.                 {
  65.                         bLed = 1;
  66.                         s_ucLedStage++;
  67.                         s_ulBase = GetCurTick();
  68.                 }
  69.                 break;
  70.                
  71.                 case 4:
  72.                 //完成
  73.                 break;
  74.                
  75.                 if (bLed)
  76.                 {
  77.                         LED_ON();
  78.                 }
  79.                 else
  80.                 {
  81.                         LED_OFF();
  82.                 }
  83.         }
  84. }
复制代码

使用特权

评论回复
| 2021-2-25 10:15 | 显示全部楼层
misra 发表于 2021-2-25 10:02
一看就是很牛的了

再给你来个

针对这个问题,实际上我有专门的驱动来实现,但不是一两句代码能说的清楚的,分两步调用,第 一步
3000+111,完成后再调用88+999

使用特权

评论回复
| 2021-2-25 10:23 | 显示全部楼层
就这,你十年功力,就玩这个。你就这个东西是很普通的软件定时器,到处都是源码,linux,和一些开源软件都有。
很多RTOS都有。
是定时器任务,不是什么框架。
看看下面这个才叫做framwork
http://www.state-machine.com/

使用特权

评论回复

评论

andy520520 2021-3-20 15:12 回复TA
我挺你。。。 
misra 2021-2-26 09:10 回复TA
@菜鸟同学 :况且这个内容并不水啊,还是有真正的干货的。可移植性超级好 可靠性 易用性都不错。尤其对初学者十分友好。像你说的那种linux那种实现 不是一般人能看的懂得吧 
misra 2021-2-26 09:06 回复TA
@菜鸟同学 :不搞点标题 怎么吸引眼球。你有更好的标题让帖子盖到100楼? 
菜鸟同学 2021-2-26 08:59 回复TA
@misra :我就不服你写的 这个标题,“真正的框架”,太狂了,必须打压下,哈哈,你有什么本事,全部拿出来。比划比划。 
misra 2021-2-26 08:56 回复TA
@菜鸟同学 :程序框架一般讲就是对某个功能或者部件的封装,让他成为一个标准件,达到拿来即用的目的。 我觉得把这个叫框架没问题。 这个肯定不是一无是处,还是有用的,尽管对你不一定有用。你看看后面网友的回复就行,还是不少人想知道其内部实现的。 另外提醒你: Talk is cheap. Show me your code 
菜鸟同学 2021-2-25 18:01 回复TA
@科技猎人 :哈哈,兄弟提醒的是,他标题 《真正的程序框架》 是不是有点过了,以为别人连软时钟这个东西都不知道。 
科技猎人 2021-2-25 16:39 回复TA
老兄,好不好的其实你心里清楚就好,没必要贬低别人。 
菜鸟同学 2021-2-25 13:22 回复TA
@misra :别激动,仔细看看我的发的这个东西,我的确不会写,你用windows开发,你自己要写windows吗,你用Linux开发,意思就是LInux源码都需要你自己写,自己实现? 真的很简单的一个软件定时器,普通不能再普通。你要是你能搞一个能像 本站农民讲习所和凤舞九天的MSOS那样的整套东西,你还可以秀一下,说成框架。 很多做MCU都悄悄的把这个软件定时器当成祖传。 
misra 2021-2-25 12:36 回复TA
Talk is cheap. Show me your code 
misra 2021-2-25 12:29 回复TA
是你写的算你牛!不是你写的 那和你有什么关系啊 
| 2021-2-25 10:35 | 显示全部楼层
来个通用版的
  1. typedef struct{
  2.         u8 ucMax;
  3.         u8 ucCur;
  4.         bool bStart;
  5.         bool bOut;
  6.         u16 ausTick[8];        //最大8个状态
  7.         u16 usBase;
  8. }LED_Typedef;

  9. LED_Typedef g_stLed;


  10. void LED_Init(u16* pTick, bool bOut, u8 ucMax)
  11. {
  12.         u8 i;
  13.        
  14.         g_stLed.ucMax = ucMax;
  15.         g_stLed.bOut = bOut;
  16.         for (i=0; i<ucMax; i++)
  17.         {
  18.                 g_stLed.ausTick[i] = pTick[i];
  19.         }
  20.         g_stLed.ucCur = 0;
  21.         g_stLed.usBase = GetCurTick();
  22.         g_stLed.bStart = 1;
  23. }

  24. void LED_Ctrl(void)
  25. {
  26.         if (g_stLed.bStart)
  27.         {
  28.                 if (GetCurTick() - g_stLed.usBase >= g_stLed.ausTick[g_stLed.ucCur])
  29.                 {
  30.                         g_stLed.bOut = !g_stLed.bOut;
  31.                         g_stLed.usBase = GetCurTick();
  32.                         g_stLed.ucCur++;
  33.                         if (g_stLed.ucCur >= g_stLed.ucMax)
  34.                         {
  35.                                 g_stLed.bStart = 0;
  36.                         }
  37.                 }
  38.                
  39.                 if (g_stLed.bOut)
  40.                 {
  41.                         LED_ON();
  42.                 }
  43.                 else
  44.                 {
  45.                         LED_OFF();
  46.                 }
  47.         }
  48.        
  49. }


  50. void main(void)
  51. {
  52.         Init();
  53.        
  54.         if (1)
  55.         {
  56.                 //一个灯  亮3秒后 灭,111ms后亮,88ms后灭,999ms后亮
  57.                 const u16 LED_TABLE[] = {3000,111,88,999};
  58.                 LED_Init(LED_TABLE, 1, 4);
  59.         }
  60.        
  61.         while (1)
  62.         {
  63.                 u8 i;
  64.                
  65.                 for (i=0; i<20; i++)
  66.                 {
  67.                         if (GetCurTick() - g_TaskBase[i] >= TASK_IVL[i])
  68.                         {
  69.                                 g_TaskVal[i]++;
  70.                                 g_TaskBase[i] += TASK_IVL[i];
  71.                         }
  72.                 }
  73.                
  74.                 if (1)
  75.                 {
  76.                         void LED_Ctrl(void);
  77.                         LED_Ctrl();
  78.                 }
  79.         }
  80. }
复制代码

使用特权

评论回复
| 2021-2-25 11:10 | 显示全部楼层
支持百家争鸣,百花齐放

使用特权

评论回复
| 2021-2-25 11:28 | 显示全部楼层
都来发下吧,

使用特权

评论回复
| 2021-2-25 11:31 | 显示全部楼层
非常简单的一个定时呀,一个计数器就可以分别产生

使用特权

评论回复

评论

misra 2021-2-25 12:31 回复TA
有句老话叫 请百度 “Talk is cheap. Show me your code.” 
| 2021-2-25 12:23 | 显示全部楼层
非常棒。

使用特权

评论回复
| 2021-2-25 12:26 | 显示全部楼层
20楼,早就有了

使用特权

评论回复

评论

zlf1208 2021-2-25 12:46 回复TA
哥,你在13楼 
| 2021-2-25 13:58 | 显示全部楼层
+1=14

使用特权

评论回复
| 2021-2-25 15:35 | 显示全部楼层
用RTOS不就可以了,创建4个任务,各干各的。

使用特权

评论回复
| 2021-2-25 17:07 | 显示全部楼层
进来看看。

使用特权

评论回复
| 2021-2-25 18:07 | 显示全部楼层
凑楼数

使用特权

评论回复
| 2021-2-25 20:56 | 显示全部楼层
八仙过海,各显神通。。。。

使用特权

评论回复
| 2021-2-25 21:13 | 显示全部楼层
看看楼主怎么实现的?

使用特权

评论回复
| 2021-2-25 21:40 | 显示全部楼层
这个可以学习下

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 我要提问 投诉建议 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表