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

systemtick使用详解章

下面我将详细解释如何配置 SysTick 定时器为 1ms 中断,并提供完整的实现代码。这里以 ARM Cortex-M 系列处理器为例,但概念适用于大多数微控制器。

在这里插入图片描述


1. 计算重装载值
系统时钟为 106MHz,要产生 1ms 中断:
重装载值 = (系统时钟频率 / 1000) - 1= (106,000,000 / 1000) - 1= 106,000 - 1 = 105,999
  1. 初始化 SysTick 定时器
#include <stdint.h>// 系统时钟频率定义
#define SYS_CLOCK_HZ 106000000u// 定义 SysTick 寄存器
#define SYSTICK_BASE 0xE000E010
typedef struct {volatile uint32_t CTRL;    // 控制状态寄存器volatile uint32_t LOAD;    // 重装载值寄存器volatile uint32_t VAL;     // 当前值寄存器volatile uint32_t CALIB;   // 校准值寄存器
} SysTick_Type;#define SysTick ((SysTick_Type *)SYSTICK_BASE)// 初始化 SysTick
void SysTick_Init(void) {// 计算1ms中断的重装载值uint32_t reload_value = (SYS_CLOCK_HZ / 1000) - 1;// 禁用SysTickSysTick->CTRL = 0;// 设置重装载值SysTick->LOAD = reload_value;// 清除当前值计数器SysTick->VAL = 0;// 启用SysTick,使用处理器时钟,启用中断SysTick->CTRL = (1 << 2) |  // CLKSOURCE = 处理器时钟(1 << 1) |  // TICKINT  = 启用中断(1 << 0);   // ENABLE   = 启用SysTick
}
  1. 实现 SysTick 中断处理函数
// 系统tick计数器(volatile确保编译器不优化)
volatile uint32_t system_tick = 0;// SysTick中断处理函数
void SysTick_Handler(void) {// 每次中断增加tick计数(增加每毫秒的时钟周期数)system_tick += (SYS_CLOCK_HZ / 1000);
}
  1. 实现获取当前tick的函数
// 获取当前系统tick
uint32_t Get_Current_Tick(void) {return system_tick;
}
  1. 在启动文件中配置中断向量
; 中断向量表
g_pfnVectors:.word   _estack.word   Reset_Handler....word   SysTick_Handler    ; SysTick中断...
  1. 启用全局中断
// 启用全局中断的函数(具体实现取决于MCU)
void Enable_Global_IRQ(void) {__asm volatile ("cpsie i");  // 对于ARM Cortex-M
}

完整示例代码

#include <stdint.h>// 系统时钟频率定义
#define SYS_CLOCK_HZ 106000000u// 定义 SysTick 寄存器
#define SYSTICK_BASE 0xE000E010
typedef struct {volatile uint32_t CTRL;volatile uint32_t LOAD;volatile uint32_t VAL;volatile uint32_t CALIB;
} SysTick_Type;#define SysTick ((SysTick_Type *)SYSTICK_BASE)// 系统tick计数器
volatile uint32_t system_tick = 0;// 初始化 SysTick
void SysTick_Init(void) {// 计算1ms中断的重装载值uint32_t reload_value = (SYS_CLOCK_HZ / 1000) - 1;// 禁用SysTickSysTick->CTRL = 0;// 设置重装载值SysTick->LOAD = reload_value;// 清除当前值计数器SysTick->VAL = 0;// 启用SysTick,使用处理器时钟,启用中断SysTick->CTRL = (1 << 2) | (1 << 1) | (1 << 0);
}// SysTick中断处理函数
void SysTick_Handler(void) {// 增加每毫秒的时钟周期数system_tick += (SYS_CLOCK_HZ / 1000);
}// 获取当前系统tick
uint32_t Get_Current_Tick(void) {return system_tick;
}// 启用全局中断
void Enable_Global_IRQ(void) {__asm volatile ("cpsie i");
}// 主程序
int main(void) {// 初始化SysTick定时器SysTick_Init();// 启用全局中断Enable_Global_IRQ();// 其他初始化代码...while(1) {// 主循环代码...}
}

关键注意事项
中断优先级:SysTick 通常具有可配置的中断优先级,确保它不会被其他中断长时间阻塞
32位计数器溢出:
106MHz 下,system_tick 每 1ms 增加 106,000
32位计数器溢出周期 = 2³² / 106,000 ≈ 40秒
在时间比较中,使用 (current_time - last_feed_time) >= interval 可以正确处理溢出
中断延迟:
实际中断间隔可能有微小变化(通常 < 1%)
对于喂狗操作,这种精度通常足够
初始化顺序:
先初始化 SysTick,再启用全局中断
确保在调用 Get_Current_Tick() 前已初始化
功耗考虑:
SysTick 中断会定期唤醒 CPU
在低功耗应用中,可能需要调整策略

http://www.dtcms.com/a/300395.html

相关文章:

  • 计数dp(基础)
  • 【AI】联网模式
  • 【micro:bit】从入门到放弃(六):示例蜂鸣器音乐、摇色子、光照强度、串口调试、麦克风
  • vulhub Earth靶场攻略
  • Scrapy分布式爬虫数据统计全栈方案:构建企业级监控分析系统
  • 慧星云新增大模型服务:多款大模型轻松调用
  • 【leetGPU】1. Vector Addition
  • LChot100--128. 最长连续序列
  • 7月26日京东秋招第一场第一题
  • 资产负债表及其数据获取
  • earth靶场
  • 【408二轮强化】数据结构——线性表
  • Pspice仿真电路:(三十四)如何使用Pspcie进行仿真
  • mount: /mnt/sd: wrong fs type, bad option, bad superblock on /dev/mmcblk1
  • 两个USB-CAN-A收发测试
  • Item14:在资源管理类中小心拷贝行为
  • 小白成长之路-部署Zabbix7(二)
  • 每日一题【删除有序数组中的重复项 II】
  • linux shell从入门到精通(二)——变量操作
  • 深度学习损失函数的设计哲学:从交叉熵到Huber损失的深入探索
  • java--JDBC
  • OSPF路由协议之多区域划分
  • nuphy新键盘快捷键
  • 智慧工业缺陷检测准确率↑32%:陌讯多模态融合算法实战解析
  • 英语听力口语词汇-8.美食类
  • docker安装问题汇总
  • ETE_Voice:端到端C++智能语音对话系统
  • 用unity开发教学辅助软件---幼儿绘本英语拼读
  • 相机标定相关原理
  • 【高等数学】第五章 定积分——第五节 反常积分的审敛法 Γ函数