STM32F1xx -- Systick 系统滴答定时器

news2024/12/23 17:32:05

1. SysTick 是一个向 CPU 提供定时中断信号的计数器,其计数速率是由 Cortex-M 系列处理器的系统时钟频率和 SysTick 计数器的重载值共同决定的。

1.1 Systick 时钟来源之一,Systick 一般设置为1ms 中断一次,为系统任务调度提供服务,24-bit reload寄存器,只能向下计数 Download

在这里插入图片描述

2. 查阅Cortex-M3/M4权威指南手册第138 页,表8.9 ,Systick的三个主要寄存器介绍,没列出来的bit位是保留位 reserve

在这里插入图片描述

3. Systick的地址、定义

core_cm3.h

/*
 * CMSIS_CM3_SysTick
 * memory mapped structure for SysTick
 */
typedef struct
{
  __IO uint32_t CTRL;                         /*!< Offset: 0x00  SysTick Control and Status Register */
  __IO uint32_t LOAD;                         /*!< Offset: 0x04  SysTick Reload Value Register       */
  __IO uint32_t VAL;                          /*!< Offset: 0x08  SysTick Current Value Register      */
  __I  uint32_t CALIB;                        /*!< Offset: 0x0C  SysTick Calibration Register        */
} SysTick_Type;

#define SCS_BASE            (0xE000E000)                              /*!< System Control Space Base Address */
#define SysTick_BASE        (SCS_BASE +  0x0010)                      /*!< SysTick Base Address              */
#define SysTick             ((SysTick_Type *)       SysTick_BASE)     /*!< SysTick configuration struct      */

4. Systick 初始化,1ms一个Systick 中断

static u8  fac_us = 0; // us延时倍乘数, 即1us数了多少个数 (1us对应多少个时钟周期)
static u16 fac_ms = 0; // ms延时倍乘数, 在FreeRTOS下, 代表每个节拍的ms数, 即:1ms数了多少个数 (1ms 对应多少个时钟周期)

/*
 * System Clock Source Config
 */
#ifdef SYSCLK_FREQ_HSE
    uint32_t SystemCoreClock = SYSCLK_FREQ_HSE;    // HSE
#elif defined SYSCLK_FREQ_24MHz
    uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz; // PLL - 24Mhz
#elif defined SYSCLK_FREQ_36MHz
    uint32_t SystemCoreClock = SYSCLK_FREQ_36MHz; // PLL - 36Mhz
#elif defined SYSCLK_FREQ_48MHz
    uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz; // PLL - 48Mhz
#elif defined SYSCLK_FREQ_56MHz
    uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz; // PLL - 56Mhz
#elif defined SYSCLK_FREQ_72MHz
    uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; // PLL - 72Mhz
#else
    uint32_t SystemCoreClock = HSI_VALUE; // HSI
#endif
/*

#define SysTick_CTRL_TICKINT_Pos    1
#define SysTick_CTRL_TICKINT_Msk    (1ul << SysTick_CTRL_TICKINT_Pos) // Enable Systick interrupt
#define SysTick_CTRL_ENABLE_Pos    0
#define SysTick_CTRL_ENABLE_Msk    (1ul << SysTick_CTRL_ENABLE_Pos) // Enable Systick

#define configTICK_RATE_HZ    (1000)    // 时钟节拍频率,这里设置为1000,周期就是1ms

 * SYSTICK 的时钟配置为 AHB 时钟
 * 这里为了兼容 FreeRTOS, 所以将 SYSTICK 的时钟频率改为 AHB 的频率!
 * SYSCLK: 系统时钟频率
 * reload 为 24-bit 寄存器, 最大值: 16777216 (0xFF FFFF + 1), 在72M下, 约合 0.233s左右 (1 / 72M * 16777216)
 * 延时时间 T = reload / systick_clock (s) = 72000 / 72000 000 (s) = 0.001s = 1ms
 */
void delay_init()
{
    u32 reload;

    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);

    fac_us = SystemCoreClock / 1000000;

    reload = SystemCoreClock / 1000000;
    reload *= 1000000 / configTICK_RATE_HZ;

    fac_ms = 1000 / configTICK_RATE_HZ;

    SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;
    SysTick->LOAD = reload;
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
}

5. 延时 n us

/*
 * decription: delay n (us)
 * @para nus: delay n us, n[0 ~ 204522252], max: 2^32 / fac_us @fac_us = 168
 * return value: none
 * Blocking function, occupying CPU
 */
void delay_us(u32 nus)
{
    u32 ticks;
    u32 told = 0;
    u32 tnow = 0;
    u32 tcnt = 0; // 统计Systick 数了多少个数
    u32 reload = 0;
    
    reload = SysTick->LOAD; // Systick 计数的当前值,数到哪了
    ticks = nus * fac_us; // 延时n us需要数 ticks 次
    told = SysTick->VAL; // 从哪个数开始数,起始值

    while (1)
    {
        tnow = SysTick->VAL; // 数到哪了,一直算数到了哪了,然后下面再统计数了多少次了
        if (tnow != told)
        {
            if (tnow < told)
            {
                tcnt += told - tnow; // 统计Systick 数了多个数了, 这里注意一下 SYSTICK 是一个只能递减的计数器就可以了
            }
            else
            {
                tcnt += (reload - tnow) + (told - 0); // 统计Systick 数了多个数了
            }
            told = tnow;
            if (tcnt >= ticks) // 当Systick 数了ticks 个数后,延时时间到,表示延时了 n us 时间
            {
                break;
            }
        }
    }
}

6. 延时n ms

6.1 跑实时操作系统FreeRTOS

/*
 * decription: delay n (ms)
 * @para nus: delay n ms, n[0 ~ 65535]
 * return value: none
 * Blocking function, occupying CPU
 * 会引起系统任务调度
 */
void delay_ms(u32 nms)
{
    if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) // 系统已经运行
    {
        if (nms >= fac_ms) // 延时的时间大于OS的最少时间周期
        {
            vTaskDelay(nms / fac_ms); // FreeRTOS延时
        }
        nms %= fac_ms; // OS已经无法提供这么小的延时了, 采用普通方式延时
    }
    delay_us((u32)(nms * 1000)); // 普通方式延时
}

6.2 没有跑操作系统,nuo奔

/*
 * decription: delay n (ms)
 * @para nus: delay n ms
 * return value: none
 * Blocking function, occupying CPU
 * 不会引起任务调度
 */
void delay_xms(u32 nms)
{
	  u32 i = 0;
    for (i = 0; i < nms; i++)
    {
        delay_us(1000);
    }
}

7.在 ARM Cortex-M 系列处理器中,SysTick 中断的入口地址是由 NVIC(Nested Vectored Interrupt Controller,嵌套式向量中断控制器)模块自动进行管理和保存的,因此我们无法直接跳转到 SysTick 中断的入口地址。

当 SysTick 计数器减到 0 时,会自动触发 SysTick 中断,并将控制权交给 NVIC 模块,由 NVIC 根据优先级和其他相关配置信息,自动切换到 SysTick 中断服务程序。

在编写代码时,我们只需要提供一个 SysTick 中断服务程序的函数,名称为 SysTick_Handler。当 SysTick 中断被触发时,CPU 会自动跳转到该函数的入口地址,并执行相应的中断处理代码。因此,我们可以在 SysTick_Handler 函数中编写处理中断的代码,例如更新计时器、控制 I/O 口、执行任务等。

需要注意的是,在 Cortex-M 处理器中,中断服务程序的入口地址必须对齐 4 个字节,即地址的最低两位必须为 0。因此,在定义 SysTick_Handler 函数时,需要确保其函数属性或链接器脚本中指定的起始地址符合对齐要求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/595499.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

R语言:集卡活动概率测算模拟

背景&#xff1a;以支付宝集五福活动为代表的集卡类营销活动背后&#xff0c;每张卡出现的概率测算是非常重要的&#xff0c;假设我们可以预估有多少人参与活动以及大致每人能抽多少次&#xff0c;且限定一共有多少人能够集齐&#xff0c;在这些限定条件下&#xff0c;每张卡出…

CentOS 系统上安装 Jenkins

#######################注意我这里安装jenkins版本要求实际是要安装jdk11版本的~~~我一开始弄错了 您可以按照以下步骤在 CentOS 上安装 JDK&#xff1a; 1. 首先&#xff0c;打开终端并使用 yum 命令更新系统软件包列表。输入以下命令来执行此操作&#xff1a; sudo yu…

chatgpt赋能python:Python为什么闪退?

Python为什么闪退&#xff1f; Python作为一种高级编程语言&#xff0c;已经赢得了世界各地许多开发者的青睐。但是&#xff0c;有时候Python会因为各种原因而突然闪退&#xff0c;给开发者带来极大的困扰。那么&#xff0c;Python为什么会闪退呢&#xff1f; 1. 内存泄漏 内…

环境感知算法——2.CenterNet基于KITTI数据集训练

1. CenterNet简介 CenterNet采用了一种新的检测思路&#xff0c;即以目标中心点为基础&#xff0c;直接回归出目标的位置和大小。而传统的目标检测算法通常会先产生大量候选框&#xff08;Anchor&#xff09;&#xff0c;再通过分类器进行筛选&#xff0c;这种方法比较复杂。C…

selenium浏览器自动化测试

Selenium是一个用于Web应用程序的自动化测试工具。它直接运行在浏览器中&#xff0c;可以模拟用户在浏览器上面的行为操作。 Selenium入门 下载驱动 查看谷歌浏览器版本 谷歌浏览器输入网址的地方输入&#xff1a;chrome://version 下载与浏览器对应&#xff08;或相近&#x…

RK3588平台开发系列讲解(驱动基础篇)驱动模块传参

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、驱动模块传参简介二、驱动模块传普通参数三、驱动模块传数组沉淀、分享、成长,让自己和他人都能有所收获!😄 📢在编写应用程序的时候,我们可以给 main 函数传递参数,比如 void main(int argc,char *argv[]…

【ChatGPT】如何利用ChatGPT来快速统计Excel数据?

系列文章目录 老板让你写个PPT没有头绪&#xff1f;没事&#xff0c;ChatGPT来帮你&#xff01;传送门 文章目录 系列文章目录前言一、不会公式&#xff1f;帮你生成二、不会处理数据&#xff1f;帮你处理写在最后 前言 自从人工智能横空而出&#xff0c;它在人们的生活中产生…

Apache配置与应用与网页安全优化

Apache配置与应用与网页安全优化 构建虚拟Web主机httpd服务支持的三种虚拟机类型基于域名的虚拟主机Options指令解释AllowOverride指令解析 基于IP地址的虚拟主机基于端口的虚拟主机Apache连接保持构建Web虚拟目录与用户授权限制Apache 日志分割AWStats分析系统 网页压缩网页缓…

研发工程师玩转Kubernetes——多Worker Node部署

在之前的系列中&#xff0c;我们都是在单Node上“玩转”kubernetes&#xff0c;熟悉了它很多指令和特性。从本节开始&#xff0c;我们开始探索多Worker Node的相关特性。 部署虚拟机 因为desktop版ubuntu非常占用内存&#xff0c;而且我们已经熟悉了一些基本操作&#xff0c;…

电能质量监测装置在半导体公司“大放异彩”

摘 要&#xff1a;半导体生产制造业在国民经济中起着举足轻重的作用&#xff0c;相关企业的规模也越来越大。其供配电系统稳定、可靠的运维不仅是其安全生产的基本保证&#xff0c;还关系到产品质量和生产的顺利进行。而半导体行业中大部分工艺设备对电能质量比较敏感&#xff…

kafka 的内部结构和 kafka 的工作原理

基本设置 让我们开始安装kafka。下载最新的 Kafka 版本并解压缩。打开终端并启动 kafka 和 zookeeper。 $ cd $HOME $ tar -xzf kafka_<version>.tgz $ cd kafka_<version> $ bin/zookeeper-server-start.sh config/zookeeper.properties # open another termina…

Web安全之常见攻防

前言&#xff1a; 在当下&#xff0c;数据安全与个人隐私受到了前所未有的挑战。如何才能更好地保护我们的数据&#xff1f;接下来分析几种常见的攻击的类型以及防御的方法。 一、XSS&#xff08;Cross Site Script&#xff09; 首先了解最常见的 XSS 漏洞&#xff0c;XSS (Cr…

Nginx的网站服务

Nginx网站服务 一、Nginx与apache的差异二、编译安装Nginx服务三、Nginx命令四、向系统添加nginx服务五、nginx配置文件六、http块的配置 一、Nginx与apache的差异 nginx相对于apache的优点&#xff1a; 轻量级&#xff0c;同样是web服务&#xff0c;比apache占用内存更少及资…

chatgpt赋能python:Python为什么运行不出结果?

Python为什么运行不出结果&#xff1f; 简介 Python是一种高级编程语言&#xff0c;可以帮助程序员快速开发软件应用。不过&#xff0c;在使用Python的过程中&#xff0c;你可能会遇到一些麻烦。其中一个常见的问题是Python运行不出结果。 如果你正在遇到这个问题&#xff0…

DAY18_基础加强-XMLDTDschema注解单元测试

目录 1 xml1.1 概述1.2 标签的规则1.3 语法规则1.4 xml解析1.5 DTD约束1.6 schema约束 2 注解2.1 概述2.2 自定义注解2.3 元注解 3 单元测试3.1 概述3.2 特点3.3 使用步骤3.4 相关注解 1 xml 1.1 概述 万维网联盟(W3C)官网&#xff1a;https://www.w3school.com.cn 万维网联盟…

解释公有云、私有云、混合云、边缘云、分布式云

Author:skate Time:2023/06/01 云计算是一种基于互联网的计算模式&#xff0c;它通过网络提供IT资源和服务&#xff0c;包括计算、存储、网络、应用等&#xff0c;以服务的形式向用户提供&#xff0c;用户可以按需获取和使用这些资源和服务&#xff0c;而无需拥有和管理这些资…

chatgpt赋能python:Python主类:一个强大的编程工具

Python主类&#xff1a;一个强大的编程工具 介绍 Python是一种高级编程语言&#xff0c;它已经成为了世界上最流行和广泛使用的编程语言之一。Python在各种领域都有着广泛的应用&#xff0c;包括科学计算、数据分析、网络编程、机器学习等等。 虽然Python具有许多有用的功能…

iPhone技巧之「合并PDF文档」

有时候我们在手机上需要将多个PDF文档合并为一个&#xff0c;方便发送或者观看。 如果电脑不在身边&#xff0c;或只想直接在手机上合并PDF&#xff0c;是不是需要下载什么新的app或者工具呢&#xff1f;答案是不需要的&#xff0c;如果你用的是苹果手机&#xff0c;用苹果自带…

点云数据处理方法的应用PCL函数库为例的设计与实现_kaic

摘 要 在计算机视觉和虚拟现实技术的发展过程中&#xff0c;点云数据已成为主要的三维数据表达形式。将点云数据转换成灰值图时&#xff0c;测算每一个像素点周边领域的点云&#xff0c;但是其效率精密度比较低。文中探讨了点云数据的多视图拼凑和滤波处理&#xff0c;明确提出…

网络编程知识点总结(1)

TCP/UDP对比 1.TCP面向连接 (如打电话要先拨号建立连接);UDP是无连接的&#xff0c;即发送数据之前不需要建立连接 2.TCP提供可靠的服务。也就是说&#xff0c;通过TCP连接传送的数据&#xff0c;无差错&#xff0c;不丢失&#xff0c;不重复&#xff0c;且按序到达;UDP尽最大…