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 的相关文章

  • HAL_Delay() 陷入无限循环

    我被 HAL Delay 函数困住了 当我调用此函数 HAL Delay 时 控制陷入无限循环 在寻找问题的过程中 我发现了这个 http www openstm32 org forumthread2145 threadId2146 htt
  • ARM 汇编分支到寄存器或内存内部的地址

    我想知道在 ARM 汇编中我可以使用哪条指令分支到存储在某个内存地址中的地址或标签 例如 我们可以使用B LABEL来跳转到LABEL 但现在目的地只能在运行时知道 并且它存储在某个已知的内存位置 是否有类似 B 地址 的东西 Thanks
  • 使用 ARM NEON 内在函数添加 alpha 和排列

    我正在开发一个 iOS 应用程序 需要相当快地将图像从 RGB gt BGRA 转换 如果可能的话 我想使用 NEON 内在函数 有没有比简单分配组件更快的方法 void neonPermuteRGBtoBGRA unsigned char
  • 用于 RHEL 的 gdb-multiarch

    我正在尝试寻找方法来运行gdb 多架构RHEL 中的命令 我已经安装了用于 ARM 处理的 QEMU 模拟器 我想安装GDB进行调试 我能够安装GDB 多体系结构在 Ubuntu 中运行命令成功 sudo apt get GDB multi
  • 可以使用Visual Studio 2012构建ARM桌面程序吗?

    我正在使用 Visual Studio 2012 beta 我的桌面 win32 程序在 ARM 架构中编译得很好 升级到 Visual Studio 2012 RC 后 编译器无法工作并出现以下错误 不支持为 ARM 平台编译桌面应用程序
  • ARM + gcc:不要使用一大块 .rodata 部分

    我想使用 gcc 编译一个程序 并针对 ARM 处理器进行链接时间优化 当我在没有 LTO 的情况下编译时 系统会被编译 当我启用 LTO 时 使用 flto 我收到以下汇编错误 错误 无效的文字常量 池需要更近 环顾网络 我发现这与我系统
  • 分析 Cortex-M7 (stm32f7) 上的 memcpy 性能

    简洁版本 从 GNU ARM 工具链中提取的 memcpy 的性能指标在 ARM Cortex M7 上对于不同的副本大小似乎差异很大 即使复制数据的代码始终保持不变 这可能是什么原因造成的 长版 我是使用 GNU Arm 工具链 11 2
  • 使用 Android NDK 使用 -fsigned-char 进行构建安全吗?

    为了与其他平台保持一致 我需要使用signed char在我正在处理的一些本机代码中 但默认情况下在Android NDK上char类型是unsigned 我尝试明确使用signed char类型 但它生成太多警告differ in sig
  • 了解 ctags 文件格式

    我使用 Exhuberant ctags 来索引我的 c 项目中的所有标签 c project 是 Cortex M7 微控制器的嵌入式软件 结果是一个标签文件 我正在尝试阅读该文件并理解所写的内容 根据我找到的 ctags 和 Exhub
  • 在linux x86平台上学习ARM所需的工具[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有一个 x86 linux 机器 在阅读一些关于 ARM 的各种信息时 我很好奇 现在我想花一些时间学
  • 为什么当大小大于 50 时,该程序花费的时间会呈指数级增长?

    所以我正在为类编写一个 ARM 汇编快速排序方法 我对大部分内容都有了解 除了复杂性没有意义 我们将其与我们制作的另一种冒泡排序方法进行比较 它对于具有 1 个参数和 10 个参数的示例表现更好 然而 我什至无法比较 100 个参数测试 因
  • Qemu flash 启动不起作用

    我有一本相当旧的 2009 年出版 嵌入式 ARM Linux 书 其中使用u boot and qemu 的用法qemu与u boot书中对二进制的解释如下 qemu system arm M connex pflash u boot b
  • 使用 NEON 内在函数除以浮点数

    我当时正在处理四个像素的图像 这是在armv7对于 Android 应用程序 我想分一个float32x4 t向量由另一个向量组成 但其中的数字与大约不同0 7 to 3 85 在我看来 除法的唯一方法是使用右移 但这是针对一个数字2 n
  • stm32l0: 执行MI命令失败。使用 vFlashErase 数据包擦除闪存时出错

    我正在使用 Nucleo STM32L031 和 AC6 STM32 工作台 eclipse 我编写应用程序并进入调试模式 一切正常 直到我在应用程序中添加另一个功能 我注意到当我删除 评论 新函数 软件可以再次进入调试模式 但是当我添加
  • arm64和armhf有什么区别?

    Raspberry Pi Type 3 具有 64 位 CPU 但其架构不是arm64 but armhf 有什么区别arm64 and armhf armhf代表 arm hard float 是给定的名称Debian 端口 https
  • ARM Cortex-M3 启动代码

    我试图了解 STM32 微控制器的 Keil realview v4 附带的初始化代码是如何工作的 具体来说 我试图了解堆栈是如何初始化的 In the 文档 http infocenter arm com help index jsp t
  • 让 TensorFlow 在 ARM Mac 上使用 GPU

    我已经安装了TensorFlow在 M1 上 ARM Mac 根据这些说明 https github com apple tensorflow macos issues 153 一切正常 然而 模型训练正在进行CPU 如何将培训切换到GPU
  • .ko 文件是如何构建的

    我正在尝试将我自己的驱动程序移植到Beagle 板 xm arm cortex A8 在移植时我试图弄清楚如何 ko文件实际构建 在我们的Makefile我们只有一个命令来构建 o file 怎样是一个 ko文件已建立 使用Linux 2
  • A64 Neon SIMD - 256 位比较

    我想将两个小端 256 位值与 A64 Neon 指令 asm 进行有效比较 平等 为了平等 我已经有了解决方案 bool eq256 const UInt256 lhs const UInt256 rhs bool result 首先 将
  • ARM 的内核 Oops 页面错误错误代码

    Oops 之后的错误代码给出了有关 ARM EX 中的恐慌的信息 Oops 17 1 PREEMPT SMP在这种情况下 17 给出了信息 在 x86 中它代表 bit 0 0 no page found 1 protection faul

随机推荐

  • 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