| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 嵌入式 -> STM32——SysTick系统定时器 -> 正文阅读 |
|
[嵌入式]STM32——SysTick系统定时器 |
目录 一、SysTick简介SysTick——系统定时器是属于CM3内核中的一个外设,内嵌在NVIC中。系统定时器是一个24bits的向下递减的计数器。计数器每计数一次的时间为1/SYSTICK,一般我们设置系统时钟SYSTICK等于72M。当重装载数值寄存器的值递减到0的时候,系统定时器就产生一次中断,以此循环往复。 因为SysTick是属于CM3内核的外设,所以所有基于CM3内核的单片机都具有这个系统定时器,使得软件在CM3单片机中可以很容易的移植。系统定时器一般用于操作系统,用于产生时基,维持操作系统的心跳。 二、SysTick寄存器介绍SysTick——系统定时器有4个寄存器,简要介绍如下。在使用SysTick产生定时的时候,只需要配置前三个寄存器,最后一个校准寄存器不需要使用。
三、SysTick定时实验利用产生1S的时基,LED以1S的频率闪烁。 编程要点
代码分析 SysTick属于内核的外设,有关寄存器的配置和定义以及库函数都在内核相关的库文件core_cm3.h中。 SysTick配置函数
用固件库编程的时候我们只需要调用库函数SysTick_Config()即可,形参ticks用来设置重装载寄存器的值,最大不能超过重装载寄存器的值2^24,当重装载寄存器的值递减到0的时候产生中断,然后重装载寄存器的值又重新装在往下递减计数,以此循环往复。紧随其后设置后中断优先级,最后配置好系统定时器的时钟等于AHBCLK=72M,使能定时器和定时器中断,这样系统定时器就配置好了,一个库函数就搞定。 SysTick_Config()库函数主要配置了SysTick中的三个寄存器:LOAD、VAL和CTRL,有关具体的部分看代码注释即可。 配置SysTick中断优先级在SysTick_Config()库函数还调用了固件库函数NVIC_SetPriority()来配置系统定时器的中断优先级,该库函数也在core_m3.h中定义,原型如下:
函数首先先判断形参IRQn的大小,如果是小于0,则表示这个系统是异常的,系统异常的优先级由内核外设SCB的寄存器SHPRx控制,如果大于0则是外部中断,外部中断的优先级由内核外设NVIC中的IPx寄存器控制。 因为SysTick属于内核外设,跟普通的外设的中断优先级有些区别,并没有抢占优先级和子优先级的说法。在STM32F103中,内核外设的中断优先级由内核SCB这个外设的寄存器:SHPRx(x=1,2,3)来配置。有关SHPRx寄存器的详细描述可以参考《Coretex-M3内核编程手册》。 下面简单介绍下这个寄存器。 SPRH1-SPRH3是一个32位的寄存器,但是只能通过字节访问,每8个字段控制着一个内核外设的中断优先级的配置。在STM32F103中,只有位7:4这高4位有效,低四位没有用到,所以内核外设的中断优先级可编程为0-15,只有16个可编程的优先级,数值越小,优先级越高。如果软件优先级配置相同,那就根据它们所在的中断向量表的位置编号来决定优先级大小,编号越小,优先级越高。 系统异常优先级字段
如果要修改内核外设的优先级,只需要修改下面三个寄存器对应的某个字段即可。 SysTick初始化函数
SysTick初始化函数由用户编写,里面调用了SysTick_Config()函数,通过设置该固件库函数的形参,就决定了系统定时器经过多少时间就产生一次中断。 SysTick中断时间的计算
SysTick
定时器的计数器是向下递减计数的,计数一次的时间
T
DEC
=1/CLK
AHB
,当重装载寄存器 中的值 VALUE
LOAD
减到
0
的时候,产生中断,可知中断一次的时间
T
INT
=VALUE
LOAD *
T
DEC
= VALUELOAD
/CLK
AHB
,其中
CLK
AHB
=72MHZ
。如果设置
VALUE
LOAD
为
72
,那中断一次的时间 TINT
=72/72M=1us
。不过
1us
的中断没啥意义,整个程序的重心都花在进出中断上了,根本没有 时间处理其他的任务。
SysTick_Confifig
()的形我们配置为
SystemCoreClock / 100000=72M/100000=720
,从刚刚分析我们 知道这个形参的值最终是写到重装载寄存器 LOAD
中的,从而可知我们现在把
SysTick
定时器中断一次的时间 T
INT
=720/72M=10us
。
SysTick定时时间的计算
当设置好中断时间
T
INT
后,我们可以设置一个变量
t
,用来记录进入中断的次数,那么变量
t
乘
以中断的时间
T
INT
就可以计算出需要定时的时间。
SysTick定时函数
现在我们定义一个微秒级别的延时函数,形参为
nTime
,当用这个形参乘以中断时间
T
INT
就得出
我们需要的延时时间,其中
T
INT
我们已经设置好为
10us
。关于这个函数的具体调用看注释即可。
函数
Delay_us()
中我们等待
TimingDelay
为
0
,当
TimingDelay
为
0
的时候表示延时时间到。变量 TimingDelay 在中断函数中递减,即
SysTick
每进一次中断即
10us
的时间
TimingDelay
递减一次。
SysTick 中断服务函数
中断复位函数调用了另外一个函数
TimingDelay_Decrement()
,原型如下:
TimingDelay
的值等于延时函数中传进去的
nTime
的值,比如
nTime=100000
,则延时的时间等于
100000*10us=1s
。
主函数代码:
主函数中初始化了
LED
和
SysTick
,然后在一个
while
循环中以
1s
的频率让
LED
闪烁。
另外一种更简洁的定时编程 上面的实验,我们是使用了中断,而且经过多个函数的调用,还使用了全局变量,理解起来挺费 劲的,其实还有另外一种更简洁的写法。我们知道,systick
的
counter
从
reload
值往下递减到
0
的 时候,CTRL
寄存器的位
16:countflflag
会置
1
,且读取该位的值可清
0
,所有我们可以使用软件查 询的方法来实现延时。
在这里我们是调用了SysTick_Config这个固件库函数,有关这个函数的说明见下面的代码。其中SystemCoreClock是一个宏,大小为72000000,如果你不想用这个宏,也可以直接用数字。
|
|
嵌入式 最新文章 |
基于高精度单片机开发红外测温仪方案 |
89C51单片机与DAC0832 |
基于51单片机宠物自动投料喂食器控制系统仿 |
《痞子衡嵌入式半月刊》 第 68 期 |
多思计组实验实验七 简单模型机实验 |
CSC7720 |
启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
STM32初探 |
STM32 总结 |
【STM32】CubeMX例程四---定时器中断(附工 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 | -2025/1/9 3:24:12- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |