OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3939|回复: 8

做一个类似于延时函数的机制,但是不需要CPU等待这个机制。

[复制链接]

7

主题

20

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2022-5-17
在线时间
19 小时
发表于 2023-5-24 10:38:23 | 显示全部楼层 |阅读模式
10金钱
STM32F7 。做一个类似于延时函数的机制,但是不需要CPU等待这个机制。传统的delay延时函数,需要CPU等待。
我现在的方法1是CNT自加加,判断CNT大于某个值,执行满足条件后面的程序,缺点是延时不准确,有时候数据拿不到。
方法2是使用定时器中断,进入中断CNT加1,外面程序需要延时,通过判断这个CNT的数量,来执行程序。缺点是进入中断太频繁了,占用CPU资源。
还有大佬有其他方法吗?,类似延时,不需要CPU等待,时间大概准确可以。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

49

主题

341

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
5259
金钱
5259
注册时间
2012-8-25
在线时间
1025 小时
发表于 2023-5-24 10:38:24 | 显示全部楼层

  1. extern int HAL_GetTick();
  2. #define  HAL_GetTick_int HAL_GetTick

  3. typedef enum
  4. {
  5.   TIMER_RUN,
  6.   TIMER_PUASE,
  7.   TIMER_OUT,
  8. }E_timer_run_t;

  9. typedef union
  10. {
  11.   E_timer_run_t E_timer_run_s;
  12.   uint32_t    data_32;
  13. }E_timer_run_u_t;


  14. typedef struct
  15. {
  16.   int msec;
  17. }timer_msdelay_t;


  18. void           timer_ms_init(timer_msdelay_t * timer_ms_p,int ms);
  19. E_timer_run_t  timer_ms_run(timer_msdelay_t * timer_ms_p);
  20. void           ms_delay(int ms);



  21. typedef struct
  22. {
  23.   int msec;
  24.   int cycle;
  25. }timer_cycle_t;

  26. void          timer_cycle_init(timer_cycle_t * timer_cycle_p,int ms);
  27. E_timer_run_t timer_cycle_run(timer_cycle_t * timer_cycle_p);



  28. void  timer_ms_init( timer_msdelay_t* timer_ms_p, int ms )
  29. {
  30.     timer_ms_p->msec = HAL_GetTick_int() + ms;
  31. }



  32. E_timer_run_t  timer_ms_run( timer_msdelay_t* timer_ms_p )
  33. {
  34.     return ( timer_ms_p->msec - HAL_GetTick_int() <= 0 ) ? TIMER_OUT : TIMER_RUN;
  35. }

  36. void           ms_delay(int ms)
  37. {
  38.   timer_msdelay_t timer_msdelay_s;
  39.   timer_ms_init(&timer_msdelay_s,ms);
  40.    while(TIMER_OUT!= timer_ms_run(&timer_msdelay_s))
  41.    {
  42.      
  43.    }
  44.   
  45. }



  46. void  timer_cycle_init( timer_cycle_t* timer_cycle_p, int ms )
  47. {
  48.     timer_cycle_p->cycle = ms;
  49.     timer_cycle_p->msec = HAL_GetTick_int() + ms;
  50. }

  51. E_timer_run_t timer_cycle_run( timer_cycle_t* timer_cycle_p )
  52. {
  53.     E_timer_run_t ret = TIMER_RUN;
  54.     if( timer_cycle_p->msec - HAL_GetTick_int() <= 0 )
  55.     {
  56.         timer_cycle_p->msec += timer_cycle_p->cycle ;
  57.         ret = TIMER_OUT;
  58.     }
  59.     return ret;
  60. }

复制代码
回复

使用道具 举报

12

主题

3344

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8462
金钱
8462
注册时间
2020-5-11
在线时间
3904 小时
发表于 2023-5-24 11:20:23 | 显示全部楼层
用一个定时器,平时关闭,需要延时的时候,给定时器重新初始化,设置好让它在指定时间后中断,中断里置标志然后停止定时器。
专治疑难杂症
回复

使用道具 举报

5

主题

134

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1389
金钱
1389
注册时间
2019-5-29
在线时间
163 小时
发表于 2023-5-24 11:25:13 | 显示全部楼层
你是想写一个状态机吗,可以参考状态机的实现,用定时器做计时,时间到了 置标志位,根据标志位判断延时是否结束
偷偷摸鱼
回复

使用道具 举报

13

主题

250

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2248
金钱
2248
注册时间
2019-8-7
在线时间
364 小时
发表于 2023-5-24 11:32:31 | 显示全部楼层
我用的就是你的方法2 改慢点不就好了10ms进一次中断 只做CNT+1的操作
回复

使用道具 举报

70

主题

6756

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
12983
金钱
12983
注册时间
2012-11-26
在线时间
3787 小时
发表于 2023-5-24 13:02:14 | 显示全部楼层
直接上RTOS就不纠结了
回复

使用道具 举报

0

主题

24

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2022-4-21
在线时间
19 小时
发表于 2023-5-24 21:11:35 | 显示全部楼层
计时器计时,主程序读CNT,达到延时清零,执行。最好使用32位计数器。
回复

使用道具 举报

28

主题

360

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1028
金钱
1028
注册时间
2021-2-4
在线时间
146 小时
发表于 2023-5-26 15:36:46 | 显示全部楼层
我拿了个基本定时器来做延时。
就是你的方法2而且还是1ms进一次中断
回复

使用道具 举报

0

主题

103

帖子

0

精华

高级会员

Rank: 4

积分
632
金钱
632
注册时间
2016-3-30
在线时间
67 小时
发表于 2023-5-26 20:27:28 | 显示全部楼层
最简单的时间轮询机制,就可以满足你的要求。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-24 11:21

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表