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

[复制链接]
6452|46
ahuzjh 发表于 2013-12-7 22:41 | 显示全部楼层
学习了,开眼界了,论坛大神真是多啊。
周立功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将成为新类型名
 楼主| 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
                        ...
                }么?
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优先级更高。
 楼主| xlsbz 发表于 2013-12-8 21:50 | 显示全部楼层
ayb_ice 发表于 2013-12-7 14:01
// 献丑了
// 没有编译,没有测试,可能有错误,BUG,只能当示意代码

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

各位大神有好主意 继续啊。。。。
ayb_ice 发表于 2013-12-9 08:14 | 显示全部楼层
本帖最后由 ayb_ice 于 2013-12-9 09:53 编辑
xlsbz 发表于 2013-12-8 21:50
你这方法我以前好像见过,原来没在意。现在感觉很好。
多谢回帖各位。


这个方法通用性强,
但效率较低
不过对于现代的芯片,这点效率损失很小的,性价比还是很高的
xhloes大龙 发表于 2013-12-9 09:37 | 显示全部楼层
学习。。
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;
}
 楼主| xlsbz 发表于 2013-12-14 00:03 | 显示全部楼层




好好写了一把!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
dong_abc 发表于 2013-12-14 01:10 | 显示全部楼层
本帖最后由 dong_abc 于 2013-12-14 01:14 编辑

  1. #include "systick.h"
  2. #include "NUC1xx.h"
  3. systick_t::systick_t (void)
  4. {
  5.     SysTickInit();
  6. }
  7. void systick_t::SysTickInit(void)
  8. {
  9.     UNLOCKREG();
  10.     SYSCLK->PWRCON.XTL12M_EN = 1;
  11.     SysTick_Config(12000000/(100*2));   //5ms节拍中断
  12.     LOCKREG();
  13.     __disable_irq();
  14. }
  15. /*系统节拍中断不在向量表中,所以将他单独出来*/
  16. extern "C" void __irq SysTick_Handler(void)
  17. {
  18.    volatile static unsigned char SysTickCnt = 0;
  19.    SysTickCnt++;
  20.    if(SysTickCnt%100==0)  
  21.   {
  22.      SysTickCnt=0;
  23.      systick_tt.SysTick_Timer_Flag.T_500ms=1;
  24.   }   

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

  29.   if(SysTickCnt%4==0)
  30.   {      
  31.       systick_tt.SysTick_Timer_Flag.T_20ms=1;
  32.   }
  33.   systick_tt.SysTick_Timer_Flag.T_5ms=1;  
  34. }




  1. #ifndef __NUC1xxSysTick_H__
  2. #define __NUC1xxSysTick_H__
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. typedef volatile struct
  7. {
  8.   unsigned char T_5ms        :1;      
  9.   unsigned char T_20ms     :1;      
  10.   unsigned char T_100ms     :1;      
  11.   unsigned char T_500ms     :1;      
  12. }SysTick_Timer;

  13. class systick_t {//系统类
  14. public:
  15.     systick_t();
  16. private:
  17.     inline void SysTickInit(void);
  18. public:
  19.     SysTick_Timer SysTick_Timer_Flag;
  20. private:
  21. };

  22. extern systick_t systick_tt;
  23. #ifdef __cplusplus
  24. }
  25. #endif
  26. #endif  /* __NUC1xxSysTick_H__ */

dong_abc 发表于 2013-12-14 01:31 | 显示全部楼层
3年前的,某本书上的。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
dong_abc 发表于 2013-12-14 01:32 | 显示全部楼层
本帖最后由 dong_abc 于 2013-12-14 01:39 编辑

3年前,来自某网友。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
ayb_ice 发表于 2013-12-14 11:40 | 显示全部楼层
LZ有点小家子气了,
搞个代码还是库文件,

这里的大牛多的是,只是很低调,只看不说而已(并非不愿意说,只是没有那么多时间而已)
 楼主| xlsbz 发表于 2013-12-14 14:07 来自手机 | 显示全部楼层
ayb_ice 发表于 2013-12-14 11:40
LZ有点小家子气了,
搞个代码还是库文件,


大虾莫怪。因为要用到公司项目里。所以不公开。个人习惯。
至于你说小家子气,我不想与你理论。
ayb_ice 发表于 2013-12-14 16:23 | 显示全部楼层
xlsbz 发表于 2013-12-14 14:07
大虾莫怪。因为要用到公司项目里。所以不公开。个人习惯。
至于你说小家子气,我不想与你理论。 ...

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

评论

dong_abc,明白你却不讲出来。? 客观讲,你并不一定能赶得上楼主。你试着讲讲看。。  发表于 2013-12-15 21:15
没什么好看的,不就是个定时器,难道还能逆天不成。 怎么用好定时器,大家都明白。  发表于 2013-12-14 17:26
gyh974 发表于 2013-12-14 21:37 | 显示全部楼层
dong_abc 发表于 2013-12-16 12:43 | 显示全部楼层
to 楼主:
定时器10来个寄存器,要怎么管理才通用?
偶目前见过最通用的是MFC里的定时器模块 和 linux里的定时器链表结构,偶在论坛里发过。
虽然PC里的实现机制算比较通用,但对于可怜的51来说,显然太复杂太臃肿了。偶楼上发的3段程序我都用在产品上了,特别是第一段从09年用到现在。

楼主,我的回复你满意吗?
最后再鄙视一下你,你这叫经验谈吗? 你发个帖子喊别人谈经验,靠!
msblast 发表于 2013-12-16 12:51 | 显示全部楼层
dong_abc 发表于 2013-12-16 12:43
to 楼主:
定时器10来个寄存器,要怎么管理才通用?
偶目前见过最通用的是MFC里的定时器模块 和 linux里的 ...

:lol套别人的经验谈
dong_abc 发表于 2013-12-16 12:51 | 显示全部楼层
看了一下前面的代码,31楼和32楼附件里的程序 跟 ayb_ice发的是一回事,基本上一样的。楼主没看。@ayb_ice   
sunhq02 发表于 2013-12-16 12:59 | 显示全部楼层
支持楼上
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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