Cortex-M3的SysTick 定时器

news2024/10/5 15:33:46

目录

概述

1 SysTick 定时器

1.1 SysTick 定时器功能介绍

1.2 SysTick 定时器功能实现

1.3 SysTick在系统中的作用

2 SysTick应用的实例

2.1 建立异常服务例程

2.2 使能异常

2.3 闹钟功能

2.4  重定位向量表

2.5 消灭二次触发

3 SysTick在FreeRTOS中的应用

3.1 STM32Cube配置SysTick

3.2 STM32HAL中sysTick接口


概述

本文主要介绍Cortex-M3的SysTick 定时器的相关知识,还介绍了一个使用汇编语言编写的Cortex-M3的SysTick的应用实例。还介绍基于Cortex-M3内核的经典MCU STM32F103中SysTick在实际项目应用的方法。

1 SysTick 定时器

1.1 SysTick 定时器功能介绍

SysTick 是一个 24 位的倒计数定时器,当计到 0 时,将从 RELOAD 寄存器中自动重装载定时初值。只要SysTick 控制及状态寄存器中的使能位被置位, 就永不停息。下图是SysTick的相关寄存器:

CM3 允许为 SysTick 提供两个时钟源以供选择:

1)是内核的“自由运行时钟” FCLK。“自由” 表现在它不来自系统时钟 HCLK, 因此在系统时钟停止时 FCLK 也继续运行。

2)一个外部的参考时钟。但是使用外部时钟时,因为它在内部是通过 FCLK 来采样的,因此其周期必须至少是 FCLK 的两倍(采样定理)。

很多情况下芯片厂商都会忽略此外部参考时钟,因此通常不可用。通过检查校准寄存器的位[31](NOREF), 可以判定是否有可用的外部时钟源,而芯片厂商则必须把该引线连接至正确的电平。

1.2 SysTick 定时器功能实现

当 SysTick 定时器从 1 计到 0 时,它将把 COUNTFLAG 位置位;

下述方法可以清零之:
1)读取 SysTick 控制及状态寄存器(STCSR)
2)往 SysTick 当前值寄存器(STCVR)中写任何数据

1.3 SysTick在系统中的作用

1)SysTick 的最大使命,就是定期地产生异常请求,作为系统的时基。 OS 都需要这种“滴答” 来推动任务和时间的管理。

2)如欲使能 SysTick 异常, 则把 STCSR.TICKINT 置位。 另外, 如果向量表被重定位到 SRAM 中,还需要为 SysTick 异常建立向量,提供其服务例程的入口地址。

2 SysTick应用的实例

2.1 建立异常服务例程

建立SysTick异常服务例程

MOV R0, #0xF                ; 异常号: 15
LDR R1, =systick_handler    ; 加载服务例程的入口地址
LDR R2, =0xE000ED08         ; 加载向量表偏移量寄存器的地址
LDR R2, [R2]                ; 读取向量表的首地址
STR R1, [R2, R0, LSL #2]    ; 写入向量

2.2 使能异常

LDR R0, =0xE000E010       ; 加载STCSR的地址
MOV R1, #0
STR R1, [R0]              ; 先停止SysTick,以防意外产生异常请求
LDR R1, =0x3FF            ; 让SysTick每1024周期计完一次。因为是从1023数到
                          ; 0,总共数了1024个周期,所以加载值为0x3FF
STR R1, [R0,#4]           ; 写入重装载的值
STR R1, [R0,#8]           ; 往STCVR中写任意的数,以确保清除COUNTFLAG标志
MOV R1, #0x7              ; 选择FCLK作为时钟源,并使能SysTick及其异常请求
STR R1, [R0]              ; 写入数值,开启定时器

除此之外, SysTick 定时器还提供了走完 10ms 所需要的格数(TENMS 位段),作为时间校准的参考信息。在 CM3 处理器的顶层有一个 24 位的输入,芯片厂商可以写入一个 10ms 的加载值,写程序时就可以读取 STCR 寄存器中的 TENMS 位段来获取此信息。不一定每个芯片都实现了此功能,因此在使用时还需查阅芯片的数据手册。

2.3 闹钟功能

SysTick 定时器还可以用作闹钟,作为启动一个特定任务的时间依据。例如,如果需要在 300 周期后执行一段代码,就可以在 SysTick 异常服务例程中设置执行那段代码的软件标志。使用 SysTick 时,清零 CURRENT 再编程 RELOAD 寄存器,以使它在 300 周期后产生异常,如下述代码所演示:

    LDR r0, =15
    LDR r1, =SysTickAlarm  ; SysTick异常服务例程为SetupExcpHanler
    BL SetupExcpHandler    ; 调用前面章节讲到的子程来建立向量
    LDR R0, =0xE000E010    ; SysTick寄存器组的基地址
    MOV R1, #0             ; 编程前先除能SysTick
    STR R1, [R0]
    STR R1, [R0,#0x8]      ; 清零CURRENT
    LDR R1, =(300-12)      ; 设置装载值。减去12是为了补偿中延迟
    STR R1, [R0,#0x4]      ; 写入RELOAD
    LDR R4, =SysTickFired  ; 在RAM中的一个变量,指示是计时到期
    MOV R5, #0             ; 初始为0
    STR R5, [R4]
    MOV R1, #0x7           ; 使用FCLK,使能SysTick,使能SysTick异常
    STR R1, [R0]           ; 启动计时
    LDR R4, =SysTickFired
WaitLoop
    LDR R5, [R4]           ; 循环查询软件标志

    CMP R5, #0
    BEQ WaitLoop
    ...                    ; SysTickFired在服务例程中被置位,主程序可以继续执行

2.4  重定位向量表

因为计数器是从 0 开始计数的,所以它会立即把 300‐12 加载入 CURRENT。 12 是中断响应的最短延时,因此减去它用以补偿。但是如果有更高优先级的异常抢占或者阻塞了它,则中断延迟还是会有的。

SetupExcpHandler 来建立向量表,但注意:必须重定位向量表到RAM 中才行。

SetupExcpHandler
                            ; 入口条件: R0 = 异常号
                            ; 入口条件: R1 = 异常服务例程
    PUSH {R0, R2, LR}
    LDR R2, =NVIC_VECTTBL
    LDR R2, [R2]                ; 读取向量表的地址
    STR.W R1, [R2, R0, LSL #2]  ; 表中[R2+R0<<2]的位置就是为该向量的
    POP {R0, R2, PC}            ; 快速返回

2.5 消灭二次触发

2.4节 重定位向量表时,减去12 只适用于一次性(one shot)的闹钟操作,必须在 SysTick 服务例程中按停这个 SysTick。进一步地,如果其它异常把它延迟得太久,就有可能会使 SysTick异常被悬起两次。因此,对于单次处理时,还需要其它一些步骤来消灭二次触发:

SysTickAlarm                ; SYSTICK exception handler
    PUSH {LR}
    LDR R0, =0xE000E010     ; SYSTICK寄存器组的基地址
    MOV R1, #0
    STR R1, [R0]            ; 除能SysTick,因为只使用一次
    LDR R0, =0xE000ED04
    LDR R1, =0x02000000     ; 手工清除NVIC中的SysTick悬起位
    STR R1, [R0]
    ...                     ; 执行所需的处理工作
    LDR R2, = SysTickFired
    LDR R1, [R2]
    ORR R1, #1
    STR R1, [R2]            ; 设置软件标志,与主程序同步,以执行任务
    POP {PC}                ; 异常返回

在服务例程的末尾处,通过设置 SysTickFired 标志,通知主程序定时已经到期,可以结束循环等待了。
 

3 SysTick在FreeRTOS中的应用

3.1 STM32Cube配置SysTick

笔者以STM32103RTB芯片作为平台配置SysTick和FreeRTOS

1) 配置FreeRTOS的系统时钟为SysTick

2)使能FreeRTOS

3.2 STM32HAL中sysTick接口

在STM32HAL库中定义在core_cm3.h中,这部分代码在实际项目应用中,不建议修改,用户可以重新stm32f1xx_hal.c中和sysTick相关的应用接口。在这个文件中,和sysTick相关的应用接口被定义为__weak类型,意味着其可以被重写。

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

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

相关文章

(完全解决)Python字典dict如何由键key索引转化为点.dot索引

文章目录 背景解决方案基础版升级版 背景 For example, instead of writing mydict[‘val’], I’d like to write mydict.val. 解决方案 基础版 I’ve always kept this around in a util file. You can use it as a mixin on your own classes too. class dotdict(dict)…

如何进行异地多地兼容组网设置?

跨地区工作、远程办公和异地合作已成为常态。由于网络限制和安全性要求&#xff0c;远程连接仍然是一个具有挑战性的问题。为了解决这一难题&#xff0c;各行各业都在寻找一种能在异地多地兼容的组网设置方案。本文将着重介绍基于【天联】的组网解决方案&#xff0c;探讨其操作…

SpringBoot——整合Thymeleaf模板

目录 模板引擎 新建一个SpringBoot项目 pom.xml application.properties Book BookController bookList.html ​编辑 项目总结 模板引擎 模板引擎是为了用户界面与业务数据分离而产生的&#xff0c;可以生成特定格式的页面在Java中&#xff0c;主要的模板引擎有JSP&…

如何评价刘强东说“业绩不好的人不是我兄弟”

在近日的一次京东管理层会议上&#xff0c;创始人刘强东以不容置疑的口吻表明了对公司文化的坚定态度&#xff1a;“凡是长期业绩不好&#xff0c;从来不拼搏的人&#xff0c;不是我的兄弟。”这句话不仅是对那些工作表现不佳的员工的直接警告&#xff0c;也透露出京东在追求业…

C++语法|多重继承详解(一)|理解虚基类和虚继承

系列汇总讲解&#xff0c;请移步&#xff1a; C语法&#xff5c;虚函数与多态详细讲解系列&#xff08;包含多重继承内容&#xff09; 虚基类是多重继承知识上的铺垫。 首先我们需要明确抽象类和虚基类的区别&#xff1a; 抽象类&#xff1a;有纯虚函数的类 虚基类是什么呢&a…

阿里云的域名购买和备案(一)

前言 本篇文章主要讲阿里云的域名购买和备案。 大家好&#xff0c;我是小荣&#xff0c;我又开始做自己的产品迷途dev了。这里详细记录一下域名购买的流程和备案流程。视频教学 购买流程 1.阿里云官网搜索域名注册 2.搜索你想注册的域名 3.将想要注册的域名加入域名清单 4.点…

[Linux]网络原理与配置

一.NAT模式网路配置 虚拟系统的IP地址处于随机网段&#xff0c;同时在母机上会额外有一个与虚拟IP地址网段相同的IP地址&#xff0c;可以实现母机与虚拟机的通信。虚拟系统的IP地址可以通过主机实际的IP地址作为代理IP&#xff0c;与外部系统进行通信。 优点&#xff1a;不造…

2024.05.25学习记录

1、面经复习&#xff1a; JS异步进阶、vue-react-diff、vue-router模式、requestldleCallback、React Fiber 2、代码随想录刷题、动态规划 3、组件库使用storybook

【C++】牛客——JZ38 字符串的排列

✨题目链接&#xff1a; JZ38 字符串的排列 ✨题目描述 输入一个长度为 n 字符串&#xff0c;打印出该字符串中字符的所有排列&#xff0c;你可以以任意顺序返回这个字符串数组。 例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。 数…

结合时间复杂度浅谈二分法的好处(将持续更新,绝对值你一个收藏)

前言 笔者虽然刷的算法题不多,但是笔者也敢说,二分法真的是一种很优越的算法,使用上限极高的那种,正因如此,笔者才想浅谈一下二分法. 封面是我很喜欢的一个游戏角色,不知道有没有老gal玩家知道! 什么是二分法? 枚举查找即顺序查找&#xff0c;实现原理是逐个比较数组 a[0:…

【C++】详解二叉搜索树

目录 树概述 二叉搜索树概述 概念 特性 元素操作 插入 删除 模拟实现 框架 查找 插入 删除 树概述 树——在计算机中是一种很常见的数据结构。 树是一种很强大的数据结构&#xff0c;数据库&#xff0c;linux操作系统管理和windows操作系统管理所有文件的结构就是…

【基础详解】快速入门入门 SQLite数据可

简介 SQLite 是一个开源的嵌入式关系数据库&#xff0c;实现了自给自足的、无服务器的、配置无需的、事务性的 SQL 数据库引擎。它是一个零配置的数据库&#xff0c;这意味着与其他数据库系统不同&#xff0c;比如 MySQL、PostgreSQL 等&#xff0c;SQLite 不需要在系统中设置…

golang中的字节序 binary BigEndian 大端 , LittleEndian 小端 理解与write写入注意事项

在golang的binary包中有2个字节系的变量定义BigEndian和LittleEndian 这个东西是go里面很有特点的玩意&#xff0c;我们在java, php等语言中是基本看不到&#xff0c;因为大部分的语言默认使用的是BigEndian 大端模式&#xff0c; 而go语言里面是你自己可选的。 这个字节系大小…

Java的类和对象

Java的类和对象 前言一、面向过程和面向对象初步认识C语言Java 二、类和类的实例化基本语法示例注意事项 类的实例化 三、类的成员字段/属性/成员变量注意事项默认值规则字段就地初始化 方法static 关键字修饰属性代码内存解析 修饰方法注意事项静态方法和实例无关, 而是和类相…

@Async详解,为什么生产环境不推荐直接使用@Async?

一、Async 注解介绍&#xff1a; Async 注解用于声明一个方法是异步的。当在方法上加上这个注解时&#xff0c;Spring 将会在一个新的线程中执行该方法&#xff0c;而不会阻塞原始线程。这对于需要进行一些异步操作的场景非常有用&#xff0c;比如在后台执行一些耗时的任务而不…

ssms用户登陆失败,服务器处于单用户模式。目前只有一位管理员能够连接。解决方案

文章目录 问题解决方案单用户模式什么是单用户模式&#xff1f;为什么使用单用户模式&#xff1f;实现步骤 问题 连接smss的时候发现无法连接&#xff0c;显示 服务器处于单用户模式。目前只有一位管理员能够连接 解决方案 打开SQL Server配置管理器 右键属性 在启动参数的最…

Python 之 日志巡检脚本

脚本说明 使用Paramiko库进行SSH连接的自动化脚本&#xff0c;用于检查、配置和排除设备故障。说明如下&#xff1a; 导入所需的库&#xff1a;paramiko、json、logging和concurrent.futures。定义配置文件路径&#xff08;devices.json&#xff09;和日志文件路径&#xff0…

Unity射击游戏开发教程:(26)创建绕圈跑的效果

unity游戏 在本文中,我将介绍如何为敌人创建圆周运动。gif 中显示的确切行为是敌人沿着屏幕向下移动,直到到达某个点,一旦到达该点,它就会绕圈移动。

c语言:摆脱对指针的恐惧【4】

在上一期指针我们讲到了二级指针是的作用是存放一级指针的地址&#xff0c;还讲了指针数组是一个可以存放若干个指针变量的数组&#xff0c;这里我们再复习一下&#xff0c;下面指针数组是什么意思&#xff1f; int* arr1[10]; //整形指针的数组 char *arr2[4]; //一级字符指针…

JavaSE——集合框架二(1/6)-前置知识-可变参数、Collections工具类

目录 可变参数 Collections工具类 Collections的常用静态方法 实例演示 可变参数 可变参数 就是一种特殊形参&#xff0c;定义在方法、构造器的形参列表里&#xff0c;格式是&#xff1a;数据类型...参数名称 可变参数的特点和好处 特点&#xff1a;可以不传数据给它&am…