打印

【编程经验谈2】注重通用!要求写通用定时函数,谁来迎战

[复制链接]
楼主: xlsbz
手机看帖
扫描二维码
随时随地手机跟帖
21
ahuzjh| | 2013-12-7 22:41 | 只看该作者 回帖奖励 |倒序浏览
学习了,开眼界了,论坛大神真是多啊。

使用特权

评论回复
22
周立功GD32| | 2013-12-8 09:56 | 只看该作者
以下我在一个实际项目当中采用的毫秒定时器接口,项目要求可移植性高
void msTimerInit(void);
void msTimerModeConfig(单次定时/周期定时);
void msTimerLoadSet(uint LoadVal);
void msTimerRun(void);
void msTimerStop(void);
uint msTimerCounterGet(void);
bool_t msTimerFlagGet(void);
void msTimerFlagClear(void);
void msTimerIntRegist(pHandler_t UserISR);
void msTimerIntUnregist(void);
接口就是这样,不论采用何种MCU、硬件定时器结构如何,只要在底层实现这个接口,上层应用一个字都不用改!
其中pHandler_t的定义为:
typedef  void(*pHandler_t)(void);       //  C语言特殊语法,pHandler_t将成为新类型名

使用特权

评论回复
23
xlsbz|  楼主 | 2013-12-8 09:59 | 只看该作者
周立功GD32 发表于 2013-12-8 09:56
以下我在一个实际项目当中采用的毫秒定时器接口,项目要求可移植性高
void msTimerInit(void);
void msTime ...

你用了个函数指针


能实现            if(time_assert(100MS) == true){        // TimeUp
                        ...
                }
               if(time_assert(100MS) == true){        // TimeUp
                        ...
                }么?

使用特权

评论回复
24
msblast| | 2013-12-8 10:43 | 只看该作者
本帖最后由 msblast 于 2013-12-8 10:54 编辑

刚好,最近我正好在TI DSP平台上实现了类似的功能。公司的源码就不贴出来了。
说下大概的思路。

至于tick就自己定了,我的是10ms
定时器内存分配,参数分别为延时时间,执行次数,携带的参数地址,要执行的函数,执行完毕(exetimes)之后调用postcb
如果exetimes为0,则表示一直执行,不会停止
Uint32 CtimerCreate(Uint32 delay, Int32 exetimes, void *params, void *cb, void *postcb)
{
  //分配内存
  //初始化
}

void CtimerRelease(Uint32 nHdlr)
{
  //如果定时器没停止,停止定时器
  //释放CtimerCreate分配的内存
}

void CtimerStart(Uint32 nHdlr)
{
  //遍历定时器队列,如果已存在nHdlr,出列,释放内存
  //给定时器队列元素分配内存,入列
}

void CtimerStop(Uint32 nHdlr)
{
  //遍历定时器队列,如果已存在nHdlr,出列,释放内存
}

Int32 CtimerExeTime(Uint32 nHdlr)
{
  //返回exetimes*delay
}

void CtimerExeCB(Uint32 nHdlr)
{
  //执行cb
}
void CtimerExePostCB(Uint32 nHdlr)
{
  //执行postcb
}

void CtimerExe(void)
{
  //遍历定时器队列,如果延时delay,就发消息到task,让task执行CtimerExeCB
  //如果执行了exetimes,就发消息到task,让task CtimerStop,然后CtimerExeCB
}


当然,要说明一下,这并非精确延时。如果有一个优先级更高的task且占用了CPU的大部分时间,时延就很明显。解决办法就是让Timer的task优先级更高。

使用特权

评论回复
25
xlsbz|  楼主 | 2013-12-8 21:50 | 只看该作者
ayb_ice 发表于 2013-12-7 14:01
// 献丑了
// 没有编译,没有测试,可能有错误,BUG,只能当示意代码

你这方法我以前好像见过,原来没在意。现在感觉很好。
多谢回帖各位。

各位大神有好主意 继续啊。。。。

使用特权

评论回复
26
ayb_ice| | 2013-12-9 08:14 | 只看该作者
本帖最后由 ayb_ice 于 2013-12-9 09:53 编辑
xlsbz 发表于 2013-12-8 21:50
你这方法我以前好像见过,原来没在意。现在感觉很好。
多谢回帖各位。


这个方法通用性强,
但效率较低
不过对于现代的芯片,这点效率损失很小的,性价比还是很高的

使用特权

评论回复
27
xhloes大龙| | 2013-12-9 09:37 | 只看该作者
学习。。

使用特权

评论回复
28
hotyong| | 2013-12-12 13:51 | 只看该作者
我喜欢和u-boot里面的,不用定时器中断
ulong get_timer_masked (void)
{
ulong now = READ_TIMER;
if (lastdec >= now) {
  /* normal mode */
  timestamp += lastdec - now;
} else {
  /* we have an overflow ... */
  timestamp += lastdec + TIMER_LOAD_VAL - now;
}
lastdec = now;
return timestamp;
}

使用特权

评论回复
29
xlsbz|  楼主 | 2013-12-14 00:03 | 只看该作者
通用定时器.rar (18.85 KB)



好好写了一把!

使用特权

评论回复
30
dong_abc| | 2013-12-14 01:10 | 只看该作者
本帖最后由 dong_abc 于 2013-12-14 01:14 编辑

#include "systick.h"
#include "NUC1xx.h"
systick_t::systick_t (void)
{
    SysTickInit();
}
void systick_t::SysTickInit(void)
{
    UNLOCKREG();
    SYSCLK->PWRCON.XTL12M_EN = 1;
    SysTick_Config(12000000/(100*2));   //5ms节拍中断
    LOCKREG();
    __disable_irq();
}
/*系统节拍中断不在向量表中,所以将他单独出来*/
extern "C" void __irq SysTick_Handler(void)
{
   volatile static unsigned char SysTickCnt = 0;
   SysTickCnt++;
   if(SysTickCnt%100==0)  
  {
     SysTickCnt=0;
     systick_tt.SysTick_Timer_Flag.T_500ms=1;
  }   

  if(SysTickCnt%20==0)  
  {
     systick_tt.SysTick_Timer_Flag.T_100ms=1;  
  }

  if(SysTickCnt%4==0)
  {      
      systick_tt.SysTick_Timer_Flag.T_20ms=1;
  }
  systick_tt.SysTick_Timer_Flag.T_5ms=1;  
}




#ifndef __NUC1xxSysTick_H__
#define __NUC1xxSysTick_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef volatile struct
{
  unsigned char T_5ms        :1;      
  unsigned char T_20ms     :1;      
  unsigned char T_100ms     :1;      
  unsigned char T_500ms     :1;      
}SysTick_Timer;

class systick_t {//系统类
public:
    systick_t();
private:
    inline void SysTickInit(void);
public:
    SysTick_Timer SysTick_Timer_Flag;
private:
};

extern systick_t systick_tt;
#ifdef __cplusplus
}
#endif
#endif  /* __NUC1xxSysTick_H__ */

使用特权

评论回复
31
dong_abc| | 2013-12-14 01:31 | 只看该作者
3年前的,某本书上的。
main_V1.0 simple.rar (28.4 KB)

使用特权

评论回复
32
dong_abc| | 2013-12-14 01:32 | 只看该作者
本帖最后由 dong_abc 于 2013-12-14 01:39 编辑

3年前,来自某网友。
51_sch_V1.0.rar (27.08 KB)

使用特权

评论回复
33
ayb_ice| | 2013-12-14 11:40 | 只看该作者
LZ有点小家子气了,
搞个代码还是库文件,

这里的大牛多的是,只是很低调,只看不说而已(并非不愿意说,只是没有那么多时间而已)

使用特权

评论回复
34
xlsbz|  楼主 | 2013-12-14 14:07 | 只看该作者
ayb_ice 发表于 2013-12-14 11:40
LZ有点小家子气了,
搞个代码还是库文件,


大虾莫怪。因为要用到公司项目里。所以不公开。个人习惯。
至于你说小家子气,我不想与你理论。

使用特权

评论回复
35
ayb_ice| | 2013-12-14 16:23 | 只看该作者
xlsbz 发表于 2013-12-14 14:07
大虾莫怪。因为要用到公司项目里。所以不公开。个人习惯。
至于你说小家子气,我不想与你理论。 ...

那还算了吧
我看也意义不大,demo项目,编译完后RAM居然有1K多,
兴趣没了

使用特权

评论回复
评论
xlsbz 2013-12-15 21:15 回复TA
dong_abc,明白你却不讲出来。? 客观讲,你并不一定能赶得上楼主。你试着讲讲看。。 
dong_abc 2013-12-14 17:26 回复TA
没什么好看的,不就是个定时器,难道还能逆天不成。 怎么用好定时器,大家都明白。 
36
gyh974| | 2013-12-14 21:37 | 只看该作者
好贴

使用特权

评论回复
37
dong_abc| | 2013-12-16 12:43 | 只看该作者
to 楼主:
定时器10来个寄存器,要怎么管理才通用?
偶目前见过最通用的是MFC里的定时器模块 和 linux里的定时器链表结构,偶在论坛里发过。
虽然PC里的实现机制算比较通用,但对于可怜的51来说,显然太复杂太臃肿了。偶楼上发的3段程序我都用在产品上了,特别是第一段从09年用到现在。

楼主,我的回复你满意吗?
最后再鄙视一下你,你这叫经验谈吗? 你发个帖子喊别人谈经验,靠!

使用特权

评论回复
38
msblast| | 2013-12-16 12:51 | 只看该作者
dong_abc 发表于 2013-12-16 12:43
to 楼主:
定时器10来个寄存器,要怎么管理才通用?
偶目前见过最通用的是MFC里的定时器模块 和 linux里的 ...

:lol套别人的经验谈

使用特权

评论回复
39
dong_abc| | 2013-12-16 12:51 | 只看该作者
看了一下前面的代码,31楼和32楼附件里的程序 跟 ayb_ice发的是一回事,基本上一样的。楼主没看。@ayb_ice   

使用特权

评论回复
40
sunhq02| | 2013-12-16 12:59 | 只看该作者
支持楼上

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则