当前位置: 首页 > article >正文

三、精准计时:滴答定时器探秘与应用

文章目录

  1. 滴答定时器简介
    • 滴答定时器(SysTick)是Cortex - M4内核中的一个24位的倒计数定时器。它的主要作用是为操作系统或其他需要定时功能的应用提供一个简单的定时基准。它具有以下特点:
      • 简单易用,集成在处理器内核中,不需要额外的外部硬件。
      • 可以产生周期性的中断,方便用于任务调度等操作。
      • 其时钟源可以是处理器的内部时钟或者外部时钟,通过配置可以灵活选择。
  2. 滴答定时器寄存器
    • 控制和状态寄存器(SysTick_CTRL)
      • 位0(ENABLE):用于使能或禁用SysTick定时器。当该位为1时,定时器开始计数;为0时,定时器停止计数。
      • 位1(TICKINT):用于使能SysTick定时器中断。当该位为1时,定时器计数到0时会产生中断请求;为0时,不会产生中断。
      • 位2(CLKSOURCE):用于选择时钟源。为0时,选择外部时钟源(一般是处理器的AHB时钟除以8);为1时,选择处理器的核心时钟。
      • 位16(COUNTFLAG):这是一个状态位,当定时器计数到0时,该位会被置1,读取该位后会自动清零。
    • 重装载值寄存器(SysTick_LOAD):这是一个24位的寄存器,用于设置定时器的初始计数值。当定时器启动后,会从这个设置的值开始向下计数。例如,如果要设置定时器每1000个时钟周期产生一次中断(假设时钟频率为1kHz,即1ms的定时周期),则可以将此寄存器的值设置为999(因为是从设置的值开始计数,到0结束,总共是1000个周期)。
    • 当前值寄存器(SysTick_VAL):这是一个24位的寄存器,用于读取当前定时器的计数值。在定时器运行过程中,可以通过读取这个寄存器来获取定时器的当前状态。不过,读取这个寄存器可能会影响定时器的正常计数,因为它是一个硬件计数器。
  3. 滴答定时器函数(以GD32F450ZG标准库为例)
    • 通常会有初始化函数来设置定时器的参数,如SysTick_Config()函数。这个函数会自动完成SysTick定时器的基本配置,包括设置重装载值、选择时钟源、使能定时器和中断等。其函数原型大概如下:
    static __INLINE uint32_t SysTick_Config(uint32_t ticks)
    {
        if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
        SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */
        NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
        SysTick->VAL   = 0; /* Load the SysTick Counter Value */
        SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                         SysTick_CTRL_TICKINT_Msk   |
                         SysTick_CTRL_ENABLE_Msk;   /* Enable SysTick IRQ and SysTick Timer */
        return (0); /* Function successful */
    }
    
    • 中断服务函数,当SysTick定时器计数到0并且使能了中断时,会进入中断服务函数。用户需要在中断服务函数中编写自己的定时任务代码。在GD32F450ZG中,中断服务函数的名称通常是SysTick_Handler()
  4. 配置滴答定时器
    • 步骤如下:
      • 首先确定定时周期。假设系统时钟频率为SystemCoreClock,要实现1s的定时周期,需要计算出SysTick定时器的重装载值。如果选择内部时钟源(即SysTick_CTRL_CLKSOURCE_Msk位为1),计算公式为:重装载值=(SystemCoreClock/1000)-1(这里假设要实现1ms的定时周期,1s需要1000个这样的周期)。
      • 然后调用SysTick_Config()函数来配置定时器。例如:
      #define TICK_PER_SECOND 1000
      uint32_t sysTickCounter = 0;
      void SysTick_Configuration(void)
      {
          if (SysTick_Config(SystemCoreClock/TICK_PER_SECOND - 1))
          {
              // 配置出错处理
              while (1);
          }
      }
      
  5. 使用滴答定时器
    • GD32 官方也给我们写好了延时 1ms 的函数,void delay_1ms(uint32_t count),有一个参数 count,这个就是我们要延时的时间的 ms 数,延时 1ms 就是 delay_1ms(1),延时 1s 就是 delay_1ms(1000)。需要注意的是这个延时是阻塞延时,在延时的时间里一直在等待,比较浪费系统资源,慎用。
/*
  \brief    delay a time in milliseconds
  \param[in]  count: count in milliseconds
  \param[out] none
  \retval     none
*/
void delay_1ms(uint32_t count)
{
  delay = count;

  while(0U != delay) {
  }
}
  1. 完整的实验代码示例(包含必要的头文件和初始化部分)
    • 首先包含必要的头文件:
#include "gd32f4xx.h"
#include "systick.h"
#include "gd32f4xx_gpio.h"
#include "gd32f4xx_rcu.h"
  • 然后进行GPIO和SysTick的初始化:
void GPIO_Configuration(void)
{
    rcu_periph_clock_enable(RCU_GPIOD);
    gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_7);
    gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
}

int main(void)
{
    GPIO_Configuration();
    SysTick_Config();
    while (1)
    {
 gpio_bit_toggle(LED2,GPIO_PIN_7);
 delay_1ms(1000);//间隔1s
    }
}

上述代码初始化了PD7引脚为输出模式,在main函数中,通过一个无限循环来等待定时器中断的发生并执行相应的操作。注意,实际应用中可能需要根据具体的开发环境和芯片库版本进行适当的调整。


http://www.kler.cn/a/429602.html

相关文章:

  • vue 与 vue-json-viewer 实现 JSON 数据可视化
  • v-bind操作class
  • 从零搭建一个Vue3 + Typescript的脚手架——day1
  • EasyExcel - 行合并策略(二级列表)
  • WebScoket-服务器客户端双向通信
  • 每天五分钟深度学习框架pytorch:快速搭建VGG网络的基础模块VGG块
  • Cherno C++学习笔记 P33 字符串的字面量
  • Java版-图论-拓扑排序与有向无环图
  • spring boot 同一个redis 操作不同的库
  • 数据类型转换在自然语言处理中的应用
  • 计算机组成原理(一):计算机指令
  • SparkSQL编程实践
  • ollama-webui - Ollama的ChatGPT 风格的 Web 界面
  • 从零开始的使用SpringBoot和WebSocket打造实时共享文本应用
  • Rust 内置数据结构——BTreeMap应用教程
  • 【教学类-82-01】20241209涂色手表制作1.0(表盘、表带)
  • 基于STM32的手势电视机遥控器设计
  • 使用pyspark完成wordcount案例
  • Flutter 图片编辑板(二) 拖动位置和对齐线应用
  • 封闭式论文写作--全面掌握ChatGPT-4o的写作技能,掌握提示词使用技巧、文献检索与分析方法,帮助您选定研究方向,提炼学术论文题目
  • 软件漏洞印象
  • 网络安全 - Cross-site scripting
  • 刷leetcodehot100-7动态规划
  • 【RBF SBN READ】hadoop社区基于RBF的SBN READ请求流转
  • 产品经理的财会知识课:资产的减值测试
  • X推出新AI图像生成器Aurora:更接近真实的创作效果