找回密码
 注册

QQ登录

只需一步,快速开始

搜索

利用stm32 systic定时器用作时钟基线实现多个定时器定时

[复制链接]
路漫漫 发表于 2020-5-20 23:52:54 | 显示全部楼层 |阅读模式
systick时钟基线运用,充分利用cpu性能,拒绝延时等浪费cpu时间行为
完整源码: systick时钟基线运用.7z (453.11 KB, 售价: 1 E币)
代码片段:
  1. /*****************************************************************************************************/

  2. SOFT_TMR g_Tmr[COUNT_TIM];

  3. /* cpu运行时间,单位ms */
  4. __IO uint32_t g_iRunTime = 0;

  5. static void Soft_TimerDec(SOFT_TMR *_tmr);

  6. /*
  7. *********************************************************************************************************
  8. *    函 数 名:Systick_Init
  9. *    功能说明:初始化Systick定时器
  10. *    形    参:无
  11. *    返 回 值:无
  12. *********************************************************************************************************
  13. */
  14. void Systick_Init(void)
  15. {   
  16.     /* 清零所有的软件定时器 */
  17.     memset(g_Tmr,0,COUNT_TIM * sizeof(g_Tmr));

  18.     /*
  19.         配置systic中断周期,并启动systick中断。
  20.         这个函数在 \Libraries\CMSIS\CM3\CoreSupport\core_cm3.h
  21.         
  22.         Systick中断向量在(\Libraries\CMSIS\CM3\DeviceSupport\ST\STM32F10x\startup\arm\
  23.             startup_stm32f10x_hd.s 文件中定义为 SysTick_Handler。
  24.         SysTick_Handler函数的实现在stm32f10x_it.c 文件。
  25.         SysTick_Handler函数调用了SysTick_ISR()函数,在本文件末尾。
  26.     */   
  27.     SysTick_Config(SystemCoreClock / 1000 * Systick_tim);
  28. }

  29. /*
  30. *********************************************************************************************************
  31. *    函 数 名: SysTick_ISR
  32. *    功能说明:SysTick中断服务程序,在SysTick_Handler中调用
  33. *    形    参:无
  34. *    返 回 值: 无
  35. *********************************************************************************************************
  36. */
  37. void SysTick_ISR(void)
  38. {
  39.     static uint8_t s_count = 0;
  40.     uint8_t i;

  41.     for (i = 0; i < COUNT_TIM; i++)
  42.     {
  43.         Soft_TimerDec(&g_Tmr[ i]);
  44.     }

  45.     g_iRunTime += Systick_tim;        /* cpu运行时间增Systick_tim*/
  46.     if (g_iRunTime >= 0x9A7EC800)    /* 30天清零 */
  47.     {
  48.         g_iRunTime = 0;
  49.     }
  50.         
  51.     s_count += Systick_tim;
  52.     if (s_count >= 10)
  53.     {
  54.         s_count = 0;

  55.         /*
  56.             此处可加入按键的检测。按键检测每隔10ms一次就行了,一般做40ms的滤波处理就可以
  57.             有效过滤掉机械动作造成的按键抖动。
  58.         */
  59. //        Key_Scan();
  60.     }
  61. }
  62. /*
  63. *********************************************************************************************************
  64. *    函 数 名: delay_ms
  65. *    功能说明: ms级延迟,延迟精度为正负1ms
  66. *    形    参:n : 延迟长度,单位 ms。
  67. *    返 回 值: 无
  68. *********************************************************************************************************
  69. */
  70. void Delay_Ms(int32_t n)
  71. {
  72. //    /* 避免 n = 1 出现主程序死锁 */
  73. //    if (n <= 1)
  74. //    {
  75. //        n = 2;
  76. //    }
  77.    
  78.     __set_PRIMASK(1);          /* 关中断 */
  79.     g_Tmr[DELAY_TIM].count = n;
  80.     g_Tmr[DELAY_TIM].flag = 0 ;
  81.     __set_PRIMASK(0);          /* 开中断 */

  82.     while (1)
  83.     {
  84.         CPU_IDLE();    /* 此处是空操作。用户可以定义,让CPU进入IDLE状态,以降低功耗;或实现喂狗 */

  85.         /* 等待延迟时间到 */
  86.         if (g_Tmr[DELAY_TIM].flag == 1)
  87.         {
  88.             return;
  89.         }
  90.     }
  91. }

  92. systick.h中的代码
  93. /*********************************************************************************************/
  94. #define SYSTICK_MODE    0    //0中断模式,1查询模式

  95. /* 软件延时 */
  96. void SoftDelay_Ms(uint16_t nms);
  97. void SoftDelay_Us(uint16_t nus);

  98. /**********************************************中断模式**********************************************/
  99. #if SYSTICK_MODE == 0   

  100. /* 目前是空操作,用户可以定义让CPU进入IDLE状态的函数和喂狗函数 */
  101. #define CPU_IDLE()

  102. #define Systick_tim        1        //Systic中断时间(时钟基线),单位:ms

  103. /*
  104.     可在此处枚举中增加若干个软件定时器
  105.     注意:变量在中断和主程序中同时被访问,有可能造成编译器错误优化,必须增加__IO 即 volatile。
  106. */
  107. enum enum_tim_id{
  108.     DELAY_TIM = 0,    //第1个保留给Delay_Ms()使用
  109.     USER_TIM1,
  110.     USER_TIM2,
  111.     USER_TIM3,
  112.     COUNT_TIM        //软件定时器的个数
  113. };

  114. /* 定时器结构体 */
  115. typedef struct
  116. {
  117.     volatile int32_t count;    //计数器
  118.     volatile uint8_t flag;    //定时到达标志
  119. }SOFT_TMR;


  120. /* 供外部调用的函数声明 */
  121. void Systick_Init(void);
  122. void SysTick_ISR(void);
复制代码


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

本版积分规则

QQ|手机版|小黑屋|ELEOK |网站地图

GMT+8, 2024-11-23 17:59

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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