STM32 系统定时器--SysTick

2023-11-07

目录

一、结构图与寄存器

二、SysTick定时时间计算

三、Systick-系统定时器配置程序

 如何更改systick中断优先级:

四、实验设计

(1) 通过查询标志位来写延时函数

 (2)通过使能中断来写延时函数


SysTick:系统定时器,24位,只能递减,存在于内核,嵌套在NVIC中。

所有的Cortex-M内核的单片机都具有这个定时器。通过系统定时器,我们可以实现精准的软件延时(毫秒、微秒级)。

一、结构图与寄存器

重装载寄存器:存放初始值   STK_CLK:时钟

counter在时钟的驱动下,从reload初值开始往下递减计数到0(这样为一个循环),产生中断和置位COUNTFLAG标志。然后又从reload值开始重新递减计数,如此循环。

其相关寄存器在M3编程手册里面:

1.STK_CTRL寄存器(控制及状态寄存器):第2位:AHB指的是高速总线时钟—HCLK,为72M,这一位置0,时钟就是9M,这一位置1,时钟就是72M。第1位:置0,不产生中断;置1,产生中断。

2. STK_LOAD寄存器(重装载数值寄存器),存放一个24位的初始值。

3. STK_VAL寄存器(当前数值寄存器)。

二、SysTick定时时间计算

首先,我们要确定3个变量。

  1-t:一个计数循环的时间(从初始值递减到0所用的时间),跟reload(存放初始值的寄存器)和CLK有关

  2-CLK:72M或者9M,由STK_CTRL寄存器配置

  3-RELOAD(初始值):24位,用户自己配置

t = reload * ( 1/clk )

Clk = 72M时,t = (72) *(1/ 72 M )= 1US

Clk = 72M时,t = (72000) *(1/ 72 M )= 1MS

三、Systick-系统定时器配置程序

SysTick寄存器结构体:在固件库文件:core_cm3.h中定义

SysTick配置库函数:在固件库文件:core_cm3.h中定义

SysTick配置中断优先级:在固件库文件:core_cm3.h中定义

SysTick配置的过程(此程序已经写好):

步骤如下:

 1.判断自己规定的初始值是否超过了最大值。

 2.初始化reload寄存器的值(确定初始值)。

 3.配置systick的中断优先级。

static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{ 
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */
  /*ticks;自己规定的初始值       
 	  SysTick_LOAD_RELOAD_Msk:2的24次方  初始值超过了最大值,肯定是不行的
	*/
	/*初始化reload寄存器的值*/
  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */
  
	/*配置systick的中断优先级*/
	NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */
  
	/*读取当前计数的值,计数器值清0*/
	SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
	
	/*配置systick的时钟为AHB时钟,使能systick的中断,使能systick*/
  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中断优先级配置的是scb->shprx寄存器(内核的);而外设的中断优先级配置的是nvic->iprx,有优先级分组,有抢占优先级和子优先级的说法。

 如何更改systick中断优先级

我们看一下中断优先级的第二个形参;:__NVIC_PRIO_BITS,官网给的备注是:STM32使用4位作为优先级,所以这个形参的官网给的值是4。在这个函数中,1左移4位,就是16,16-1=15。总共有4个位来表示优先级,15就是“1111”,也就是说,systick中断这个优先级永远是最低的。

比较内核和外设的中断优先级:自己先确定好外设的NVIC分组,systick就套用相同的分组方法。内核外设的中断优先级的四个位按照外设的中断优先级来分组来解析,即人为的分出抢占优先级和子优先级。例如:前面这个15,解析成4个位就为:1111。如果NVIC分组选择的是组1,即第一个1代表着主优先级,后面三个1代表着子优先级。这个时候,如果你想提高systick中断的优先级的话,就更改/子优先级的大小,比外设的主/子优先级高就行(也就是上面4位2进制的数变低)。

所以:我们只需要更改“__NVIC_PRIO_BITS”这个变量的大小即可。

4.读取当前计数的值,计数器值清0(VAL寄存器)。

5.配置systick的时钟为AHB时钟,使能systick的中断,使能systick。

四、实验设计

1-编写一个微秒延时函数  2-编写一个毫秒延时函数

方法有两种:通过查询标志位来写延时函数,通过使能中断来写延时函数

(1) 通过查询标志位来写延时函数

  先定义一个变量,循环一轮(1ms/us),然后在for循环里面等待到了我们规定的延时的时间(CTRL寄存器寄存器第16位为1),就完成了延时。

/*通过查询标志位来写延时函数*/
void SysTick_Delayms(uint32_t ms)//1毫秒延时函数,延时多少毫秒更改形参即可
{
	uint32_t i;
	
	SysTick_Config(72000);//循环1轮就是1毫秒
	
	for(i=0;i<ms;i++)
	{
		while(((SysTick->CTRL) & (1<<16)) != 1);
		//判断CTRL这个寄存器的16位不为1,就继续在while循环里面等待
	}
	
	SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;//把这位清0,失能systick
}

void SysTick_Delayus(uint32_t us)//1微秒延时函数,延时多少微秒更改形参即可
{
	uint32_t i;
	
	SysTick_Config(72);//循环1轮就是1微秒
	
	for(i=0;i<us;i++)
	{
		while(((SysTick->CTRL) & (1<<16)) != 1);
		//判断CTRL这个寄存器的16位不为1,就继续在while循环里面等待
	}
	
	SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;//把这位清0,失能systick
}

 (2)通过使能中断来写延时函数

  定义一个全局变量(毫秒和微秒要分开用),先把我们要延时的这个数值赋给这个全局变量,然后走一轮循环;在中断服务函数里面,找到systick的中断服务函数,每进一次中断这个全局变量就减一;建立while循环,减到了0之后失能systick。

中断函数文件内:

extern volatile uint32_t isr_ms;//这个全局变量在bsp_systick.c文件中
extern volatile uint32_t isr_us;//这个全局变量在bsp_systick.c文件中

void SysTick_Handler(void)//systick 的中断服务函数
{
	isr_ms--;
	isr_us--;
}

延时函数文件内:

/*通过使能中断来写延时函数*/
volatile uint32_t isr_ms;//定义一个全局变量

void SysTick_Delayms_INT(uint32_t ms)//1毫秒延时函数,延时多少毫秒更改形参即可
{
	isr_ms = ms;
	SysTick_Config(72000);//循环1轮就是1毫秒
	
	while(isr_ms);
	
	//把这位清0,失能systick
	SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}

volatile uint32_t isr_us;//定义一个全局变量

void SysTick_Delayus_INT(uint32_t us)//1毫秒延时函数,延时多少毫秒更改形参即可
{
	isr_us = us;
	SysTick_Config(72);//循环1轮就是1毫秒
	
	while(isr_us);
	
	//把这位清0,失能systick
	SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32 系统定时器--SysTick 的相关文章

  • 哪些变量类型/大小在 STM32 微控制器上是原子的?

    以下是 STM32 微控制器上的数据类型 http www keil com support man docs armcc armcc chr1359125009502 htm http www keil com support man d
  • GCC ARM 汇编预处理器宏

    我正在尝试使用汇编 ARM 宏进行定点乘法 define MULT a b asm volatile SMULL r2 r3 0 1 n t ADD r2 r2 0x8000 n t ADC r3 r3 0 n t MOV 0 r2 ASR
  • C 嵌入式应用程序中 time() 函数的问题

    我在用time 在 ARM 微控制器上 处理器一到达此函数就会重新启动 奇怪的是 当我处于调试模式时 代码运行得很好 但一旦我想将其应用到独立模式 我就会遇到重置 我是否忽略了什么 这个功能有替代品吗 代码部分是这样的 include
  • 读取和打印手臂组件中的字符串

    我正在使用 ARMSim 刚刚开始学习汇编 所以如果我看起来一无所知 请原谅我 但我正在尝试从输入文件中读取字符串 然后将其打印到输出屏幕 到目前为止我有 equ SWI Open 0x66 open a file equ SWI Clos
  • Linux malloc() 在 ARM 和 x86 上的行为是否不同?

    这个网站上有很多关于内存分配的问题 但是我 找不到专门解决我的问题的人 这 问题 https stackoverflow com questions 19148296 linux memory overcommit details似乎最接近
  • 为 ARM 交叉编译 zlib

    我尝试为arm poky linux gnueabi交叉编译zlib 但启动 make 时出现错误 zlib 1 2 11 AR HOST ar CC HOST gcc RANLIB HOST ranlib configure prefix
  • 如何在 Android 设备上运行 VS Code [重复]

    这个问题在这里已经有答案了 我有 Galaxy Tab S6 它具有替代笔记本电脑的很酷的功能 例如连接鼠标和键盘 但不幸的是它运行 Android 操作系统 并且没有很多开发应用程序可用于 Android 所以我想是否有一个选项可以在至少
  • arm-thumb指令集的blx指令如何支持4MB范围

    读自https www keil com support man docs armasm armasm dom1361289866046 htm https www keil com support man docs armasm arma
  • 有没有办法在 Xcode 4 中为 ARM 而不是 Thumb 进行编译?

    如果有很多浮点运算正在进行 Apple 建议针对 ARM 进行编译 而不是针对拇指进行编译 我的整个应用程序几乎是一个大型浮点运算 iOS 应用程序开发工作流程指南中是这样说的 iOS 设备支持两种指令集 ARM 和 Thumb Xcode
  • STM32 传输结束时,循环 DMA 外设到存储器的行为如何?

    我想问一下 在以下情况下 STM32 中的 DMA SPI rx 会如何表现 我有一个指定的 例如 96 字节数组 名为 A 用于存储从 SPI 接收到的数据 我打开循环 SPI DMA 它对每个字节进行操作 配置为 96 字节 是否有可能
  • 在linux x86平台上学习ARM所需的工具[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有一个 x86 linux 机器 在阅读一些关于 ARM 的各种信息时 我很好奇 现在我想花一些时间学
  • 在 Intel 机器上构建 Apple Silicon 二进制文件

    如何在 macOS 11 Intel 上编译 C 项目以在 Silicon 上运行 我当前的构建脚本很简单 configure make sudo make install 我尝试过使用 host and target标志与aarch64
  • ARM Chromebook 上的 Android 开发环境?

    我尝试了多次安装和使用安卓工作室 https developer android com studio index html on an ARM Chromebook C100P https archlinuxarm org platfor
  • 什么是遗留中断?

    我正在开发一个项目 试图弄清楚 ARM 架构的全局中断控制器中如何处理中断 我正在使用 pl390 中断控制器 我看到有一条线被称为传统中断 它绕过了分配器逻辑 假设有 2 个中断可以被编程为传统中断 任何人都可以帮助解释一下什么是遗留中断
  • 英特尔的最后分支记录功能是英特尔处理器独有的吗?

    最后分支记录是指存储与最近执行的分支相关的源地址和目标地址的寄存器对 MSR 的集合 它们受英特尔酷睿 2 英特尔至强和英特尔凌动处理器系列的支持 http css csail mit edu 6 858 2012 readings ia3
  • ARM Cortex-M3 启动代码

    我试图了解 STM32 微控制器的 Keil realview v4 附带的初始化代码是如何工作的 具体来说 我试图了解堆栈是如何初始化的 In the 文档 http infocenter arm com help index jsp t
  • 你好世界,裸机 Beagleboard

    我正在尝试在我的 Beagleboard xm rev 上运行 hello world 类型的程序 C 通过调用 Cputs功能来自装配 到目前为止 我一直使用这个作为参考 http wiki osdev org ARM Beagleboa
  • GCC 变量映射和 MISRA-C

    我主要知道两种使用 GCC 声明内存映射寄存器的方法 有许多变体 使用双字段 每个外设的数据结构等 要么使用初始化为正确地址的指针 例如volatile uint32 t pMyRegister uint32 t 0xDEADBEEFUL
  • 2022年Android CPU架构分布(armeabi-v7a vs arm64-v8a)

    有没有关于 2022 年 Android 设备上的架构使用情况的官方信息 我有一个支持armeabi v7a 和arm64 v8a 的应用程序 我想要放弃对armeabi v7a的支持并且仅支持 64 位设备 arm64 v8a 但我找不到
  • 支持 ARM 上的 Windows 10 桌面应用程序 - MFC 和 COM 以及 OPOS 可以工作吗?

    我试图了解将在 x86 Windows 10 上运行的 C MFC 应用程序移植到具有 Qualcomm Snapdragon 处理器的 ARM Windows 10 设备的障碍 32位应用程序具有以下特点 MFC 与 C 用于用户界面 C

随机推荐

  • Element UI更改下拉菜单el-dropdown-menu样式

    Element UI更改下拉菜单el dropdown menu样式 源代码
  • [网络安全自学篇] 八十一.WHUCTF之WEB类解题思路WP(文件上传漏洞、冰蝎蚁剑、反序列化phar)

    这是作者网络安全自学教程系列 主要是关于安全工具和实践操作的在线笔记 特分享出来与博友们学习 希望您喜欢 一起进步 前文分享了WHUCTF部分题目 包括代码审计 文件包含 过滤绕过 SQL注入 这篇文章将讲解Easy unserialize
  • 接口文档生成工具ApiPost挺好用

    作为一名程序员我深知一款好用的软件工具对工作效率的提升意味着什么 相信不少程序员还在依靠老外们做的软件处理手头工作 曾经我也是其中一员 不过现在我已经开始迷上了国产软件 国外的自然后他的优势 但国产软件工具也吸引了不少程序员开始尝试 虽然他
  • tensorflow2学习笔记

    目录 Tensorflow2 0特性 构架 TensorflowDemo AlexNet 过拟合 卷积后矩阵尺寸大小的计算 代码地址 VGG 感受野 网络结构 代码地址 GoogLeNet GoogLeNet网络结构 参数 Inceptio
  • [机器学习笔记-3]识别服饰图像的神经网络

    目录 1 安装tensorflow数据集 命令行输入 导入依赖 2 导入Fasion MINST数据集 3 处理数据 4 构建模型 5 训练模型 6 评估准确度 7 预测数据 8 图表显示数据 jupyter notebook中运行注意事项
  • 2020年最新的PHP面试题(附答案)

    684 PHP究竟是不是最好的语言 一直以来是程序员最大的 争议 但毋庸置疑的是 PHP绝对是最有前途和力量的变成语言 也是你入门最值得学习的语言 为什么这么说呢 不妨来了解一下 为什么学PHP 语言入门简单 容易掌握 程序建设性好 开发者
  • javaWeb的项目路径问题(对servlet路径和form表单请求路径的一些归纳)

    javaWeb项目的路径问题 这篇文章大神将路径问题讲的很透彻 我想说的是几点小细节 博主说的很清楚 如果这里的deployment下面的application context中不单单仅是一个 后面加的有其他字符的话 在form表单中我们填
  • 深聊测开领域之:Testcase中资源泄露

    1 引言 2 何为资源泄露 2 1 资源泄露定义 2 2 TestCase 中资源泄露 3 避免资源泄露 3 1 如何避免资源泄露 3 2 自动化执行顺序 1 引言 执行测试时离不开测试用例 测试用例辅佐执行测试 这就好比皇帝与宰相 需要的
  • jekyll网站上传服务器,jekyll 高效搭建个人博客之完整流程

    jekyll png 原创精选来自我的博客文章 目录 说在前面的话 作为一个和电脑 代码打交道的我 一直都想拥有自己的博客 一切都显得那么高 zhuang 大 bi 上 yong 在下定决心之后就在网上到处查找资料 最终发现一般用的就三种
  • 定时任务之Springboot整合Quartz详解

    文章目录 一 什么是Quartz 二 为什么使用Quartz 1 为什么要用定时任务 2 为什么使用Quartz 三 常见开源定时任务的框架的异同 四 Quartz的组件 五 Quartz持久化 1 为什么要持久化 2 Quartz提供了两
  • 解决openwrt ipk missing dependencies libpthread librt

    新版本的trunk有在ipk打包的过程中的bug 他不能自动识别SDK中已经变异的动态链接库 比如libpthread libboost这些 解决方案是修改与pakage里同级的makefile的内容 可以修改如下 主要是添加DEPENDS
  • JavaScprit---基础代码

    var text Hello World document write p text indexOf Hello p document write p text indexOf World p document write p text i
  • MySQL中Select+Update并发的更新问题

    小知识补充 首先 我们要知道在mysql中update操作都是线程安全的 mysql引擎会update的行加上 排他锁 其他对该行的update操作需要等到第一个update操作提交成功或者回滚 才能获取这个 排他锁 从而对该行进行操作 例
  • 程序员如何进行职业规划?

    本文来自作者 王俊生 在 GitChat 上分享 程序员如何进行职业规划 阅读原文 查看交流实录 文末高能 编辑 哈比 一直以来程序员这一职业都给人高薪资的印象 近年来随着互联网行业的快速发展 程序员更是人满为患 然而很多人关注的却是程序员
  • MOS管电源开关电路的软启动

    https mp weixin qq com s 5W8rveh69XVzJoRX XrSfgbeizhu 仅用于标注 适用于我这样的硬件小白
  • React你应该学会的开发技巧【总结】!

    关注公众号 前端人 回复 加群 添加无广告优质学习群 干净的代码不仅仅是工作代码 简洁的代码易于阅读 易于理解并且井井有条 在本文中 我们将研究六种编写更简洁的React代码的方法 在阅读这些建议时 请务必记住它们的实质 相信这些实践对我们
  • 链表两数相和 (2)--Leetcode

    题目描述 给出两个 非空 的链表用来表示两个非负的整数 其中 它们各自的位数是按照 逆序 的方式存储的 并且它们的每个节点只能存储 一位 数字 如果 我们将这两个数相加起来 则会返回一个新的链表来表示它们的和 您可以假设除了数字 0 之外
  • 通过在线游戏练习flex布局和各种css选择器

    懒是一个很好的托辞 说的好像你勤奋了就能干成大事一样 序言 不知道身为后端程序员的你写不写前端代码 反正我是经常写 调布局和样式着实有点费劲 一般像我这样的后端开发都不会系统的去学一些前端知识 都是遇到了就百度 然后复制粘贴一下 再不停的让
  • MyBatis七:自定义映射resultMap

    自定义映射resultMap 一 resultMap处理字段和属性的映射关系 为字段设置别名 是别名和属性名一致 方式一
  • STM32 系统定时器--SysTick

    目录 一 结构图与寄存器 二 SysTick定时时间计算 三 Systick 系统定时器配置程序 如何更改systick中断优先级 四 实验设计 1 通过查询标志位来写延时函数 2 通过使能中断来写延时函数 SysTick 系统定时器 24