【SysTick系统时钟的使用】

SysTick(System Timer)是一种系统计时器,它是一个24位只能向下递减的计数器(计数器每计数一次的时间为1/SYSCLK),通常用于嵌入式系统中,用于提供基本的系统定时和时钟服务。SysTick定时器是ARM Cortex-M处理器架构中的一个标准组件,存在于内核中。

一、主要功能

1、延时

SysTick的主要功能:实现简单的延时。
其配置为:
通过配置计数初值,在时钟驱动下,实现计数递减,当计数至0后,又可以重新开始计数。通过这种方式,SysTick可以精准地控制延时时间。

SysTick定时器有两个时钟源可以选择,具体取决于硬件设计和系统需求。这些时钟源通常与系统的主时钟(SYSCLK)有关,经过分频或其他处理后,作为SysTick的时钟输入。选择适当的时钟源对于确保SysTick的准确性和稳定性至关重要。

2、定时中断

此外,SysTick还可以用于生成定时中断,以便执行特定的任务或进行系统级的时间跟踪。当SysTick计数到0时,可以产生一个中断,这个中断可以被处理器捕获并执行相应的中断服务程序。

综上,SysTick是ARM Cortex-M处理器中一个非常重要的组件,它为嵌入式系统提供了基本的时间管理和定时服务。

二、示例说明

SysTick的使用示例会涉及初始化SysTick、配置其参数以及处理SysTick中断。以下是一个简化的SysTick使用示例,展示如何在GD32F350中实现基本的延时和中断处理功能:

1、【使用SysTick中断来实现延时功能,需确SysTick_Handler被正确配置,并且在delay_ms函数中,需设置一个标志来指示延时是否完成。当SysTick中断发生时,可在中断服务程序中检查并更新这个标志。】

#include "gd32f3xx.h"  
  
// 延时完成的标志  
volatile uint32_t delay_finished = 0;  
  
// SysTick中断服务程序  
void SysTick_Handler(void)  
{  
    // 清除SysTick中断标志  
    systick_flag_clear(SYSTICK_FLAG_COUNTFLAG);  
  
    // 检查是否达到了延时结束的条件  
    if (delay_finished > 0) {  
        delay_finished--;  
    }  
}  
  
// 初始化SysTick定时器  
void SysTick_Init(uint32_t ticks)  
{  
    // 配置SysTick时钟源为HCLK(系统时钟)  
    rcu_clock_config_systick(RCU_CKSYSTICK_HCLK);  
  
    // 设置SysTick重载值  
    systick_set_reload(ticks - 1);  
  
    // 配置SysTick中断并启动定时器  
    systick_interrupt_enable();  
    systick_counter_enable();  
  
    // 配置NVIC来使能SysTick中断  
    nvic_irq_enable(SysTick_IRQn, 0, 0);  
}  
  
// 延时函数  
void delay_ms(uint32_t ms)  
{  
    uint32_t ticks = ms * (SystemCoreClock / 1000); // 计算总计数值  
    delay_finished = ticks; // 设置延时完成的次数  
  
    // 等待延时完成  
    while (delay_finished > 0);  
}  
  
int main(void)  
{  
    // 系统初始化代码(时钟、外设等)  
    // ...  
  
    // 初始化SysTick定时器  
    SysTick_Init(SystemCoreClock / 1000); // 假设我们想要每毫秒中断一次  
  
    // 主循环  
    while (1)  
    {  
        // 执行主循环中的任务  
        // ...  
  
        // 使用延时函数  
        delay_ms(1000); // 延时1秒  
    }  
}

以上示例包含了GD32F350相关的头文件gd32f3xx.h。定义了SysTick的中断服务程序SysTick_Handler,在其中处理SysTick中断事件,并清除相应的中断标志。

SysTick_Init函数用于初始化SysTick定时器。它配置了SysTick的时钟源、重载值,并启用了SysTick中断和计数器。同时,通过NVIC(嵌套向量中断控制器)使能了SysTick的中断。

delay_ms函数是一个简单的延时函数,它根据系统时钟和所需的延时时间计算出需要的SysTick计数次数,并在一个循环中等待直到延时结束。

在main函数中,调用了SysTick_Init来初始化SysTick,并在主循环中使用了delay_ms函数来实现延时。

注意:由于delay_finished是一个全局变量,并且在中断服务程序中被修改,因此必须将其声明为volatile,以确保编译器不会对其进行优化,从而导致不正确的行为。

2、SysTick使用轮询方式实现延时的示例如下:

void delay_ms(uint32_t ms)  
{  
    // 计算需要的SysTick重载值,假设SystemCoreClock是以Hz为单位的系统核心时钟  
    uint32_t ticks = (SystemCoreClock / 1000) * ms;  
      
    // 清除当前计数值  
    SysTick->VAL = 0;  
      
    // 设置SysTick重载值,并启用SysTick使用核心时钟,然后开始计数  
    SysTick->LOAD = ticks - 1;  
    SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;  
      
    // 轮询等待SysTick计数完成  
    while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);  
      
    // 停止SysTick计数器  
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;  
}

以上示例中:LOAD寄存器设置为(SystemCoreClock / 1000) * ms - 1,这样SysTick每计数SystemCoreClock / 1000次,就代表过去了1毫秒。

在while循环中,等待SysTick->CTRL寄存器的第16位(COUNTFLAG位)变为0。当SysTick计数器递减到0时,这个位会被自动设置。所以需要等待这个位变为0,以表明计数已经完成。

在函数结束时,关闭SysTick计数器。这是因为在长时间运行的系统中,减少不必要的功耗。

三、中断优先级设置

SysTick中断优先级的配置主要取决于系统的具体需求和设计考虑。不同的优先级设置会影响到SysTick中断的响应速度和系统中其他中断的处理。

所以在配置时,需要综合考虑实时性用户中断的响应速度中断优先级分组以及实时操作系统的要求等因素。

1、实时操作系统中的配置:
为提高系统的实时性,可考虑将SysTick中断优先级设置为高。高优先级的SysTick中断可以确保系统心跳的准确性,从而保证实时性。

注意,如果系统中存在很多频繁的用户中断,高优先级的SysTick可能会不断打断用户中断,影响用户中断的实时性。

2、用户中断的响应:
如果系统中有大量且频繁的用户中断,且希望这些用户中断能够得到快速响应,可考虑将SysTick中断优先级设置为低。这样,用户中断能够抢占SysTick中断,确保用户中断的实时性。

3、配置方法:
具体配置SysTick中断优先级的方法依赖于使用的微控制器和开发环境。一般来说,可以通过配置NVIC(嵌套向量中断控制器)来实现。

例如,在STM32系列微控制器中,可以使用NVIC_SetPriority函数来设置SysTick中断的优先级。

4、中断优先级分组:
在配置SysTick中断优先级时,注意中断优先级分组。很多微控制器支持抢占优先级和子优先级的设置。抢占优先级高的中断可以打断正在执行的抢占优先级低的中断,而子优先级则用于处理具有相同抢占优先级的多个中断。

5、FreeRTOS等实时操作系统的考虑:
如果在FreeRTOS等实时操作系统中使用SysTick,需注意SysTick中断的优先级与FreeRTOS API函数调用的关系。通常,低于某个特定优先级的中断才允许调用FreeRTOS的API函数。

  • 20
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大山很山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值