STM32 寄存器操作 systick 滴答定时器 与中断

一、什么是 SysTick

SysTick—系统定时器是属于CM3内核中的一个外设,内嵌在NVIC中。系统定时器是一个24bit的向下递减的计数器, 计数器每计数一次的时间为1/SYSCLK,一般我们设置系统时钟SYSCLK等于72M。当重装载数值寄存器的值递减到0的时候,系统定时器就产生一次中断,以此循环往复。

因为SysTick是属于CM3内核的外设,所以所有基于CM3内核的单片机都具有这个系统定时器,使得软件在CM3单片机中可以很容易的移植。 系统定时器一般用于操作系统,用于产生时基,维持操作系统的心跳。

当然更常用的还是在裸机环境下作为延迟函数使用,本篇不介绍rtos相关的 SysTick 使用。

二、SysTick 寄存器描述

SysTick->CTRL,        --控制和状态寄存器

SysTick->LOAD,        --重装载寄存器

SysTick->VAL,          --当前值寄存器

SysTick->CALIB,        --校准值寄存器    (不常用 不做介绍)

2.1 SysTick->CTRL

2.2 SysTick->LOAD

2.3 SysTick->VAL

2.4 SysTick->CALIB

三、如何使用滴答定时器? 

3.1 初始化滴答定时器

通过设置 SysTick->CTRL 的第二位寄存器,我们可以配置滴答定时器使用外部时钟 (STCLK) 或者是 Cortex 内核时钟 (FCLK)。

所谓 Cortex 内核时钟就是如下图所示,AHB 八分频后的时钟。

在此我们配置为使用 Cortex 内核时钟,对 CTRL 第二位置 1 即可。

SysTick->CTRL&=~(1<<2);    //使用 Cortex 内核时钟

SystemCoreClock 是定义了系统时钟 (SYSCLK)频率的宏,即等于AHB 的时钟频率。笔者使用的是STM32F103x系列mcu,SystemCoreClock 被系统库配置成 72Mhz。

因为我们使了 Cortex 内核时钟。所以同样需要除 8 来当作八分频使用。

下面的代码则代表每1秒钟,SysTick会有 72000000/8= 9000000 次的计数周期。

fac_s = SystemCoreClock/8;      //为系统时钟的1/8 代表每个s完成的systick时钟数

 之后我们依次配置每秒,每毫秒,每微秒的滴答定时器周期。

//1s=1000ms=1000000=us
static u32 fac_s=0;     //一秒的滴答定时器计数周期数量
static u32 fac_ms=0;    //一毫秒的滴答定时器计数周期数量
static u32 fac_us=0;    //一微秒的滴答定时器计数周期数量

void delay_init(){
    SysTick->CTRL&=~(1<<2);         //使用 Cortex 内核时钟
	fac_s = SystemCoreClock/8;      //为系统时钟的1/8 代表每个s完成的systick时钟数
	fac_ms = fac_s/1000;            //代表每个ms完成的systick时钟数
    fac_us = fac_ms/1000;           //代表每个us完成的systick时钟数
}

3.2 实现 delay_us() 函数

细看注释配合之前的寄存器描述即可看懂。

void delay_us(u32 nus)
{
	u32 temp;	    	 
	SysTick->LOAD=nus*fac_us; 					//时间加载	  		 
	SysTick->VAL=0x00;        					//清空计数器
	SysTick->CTRL|=1 ;	    //使能计数器  ENABLE位置1
	do
	{
		temp=SysTick->CTRL;
    //检查CTRL的ENABLE位和COUNTFLAG位
    //如果ENABLE位为0或者COUNTFLAG位为1则判断为计数结束 等待时间到达   
	}while((temp&0x01)&&!(temp&(1<<16)));
	SysTick->CTRL&=~1;	    //关闭计数器     ENABLE位置0
	SysTick->VAL =0X00;     //清空计数器	 
}

三、使用 SysTick 的中断

根据 SysTick->CTRL 寄存器表的提示,我们只需要把第一位置高即可开启 SysTick 异常中断。

3.1 使用库函数

在这里我们不再从头写寄存器,而是使用core_cm3.h 的库函数,并且解析其中的原理。

#include "stm32f10x.h"

int main(void)
{	

    if (SysTick_Config(SystemCoreClock / 1000))	// ST3.5.0库版本
	{
		while (1);
	}

	for(;;)
	{
        __NOP();
	}
}


void SysTick_Handler(void)
{
    //每1ms中断一次
}

在下列代码中,我们的程序可以每隔 1ms 调用一次滴答定时器回调函数。

3.2 源码解析

static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* 值超过0xFFFFFF直接退出 */
                                                               
  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* 设置重载寄存器 与运算防止越界 */
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* 设置Cortex-M0系统中断的优先级 */
  SysTick->VAL   = 0;                                          /* 加载SysTick计数器值 */
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                   SysTick_CTRL_TICKINT_Msk   |
                   SysTick_CTRL_ENABLE_Msk;                    /* 使能 SysTick IRQ 和 SysTick Timer */
  return (0);                                                  /* 函数成功 */
}

方便阅读代码,我将下边的几个宏定义也粘贴过来: 

#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk         (1ul << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */

#define SysTick_CTRL_TICKINT_Pos            1                                             /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk           (1ul << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */

#define SysTick_CTRL_ENABLE_Pos             0                                             /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk            (1ul << SysTick_CTRL_ENABLE_Pos)               /*!< SysTick CTRL: ENABLE Mask */

/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos             0                                             /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)        /*!< SysTick LOAD: RELOAD Mask */

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

云原生介绍与容器的基本概念

云原生介绍 1、云原生的定义 云原生为用户指定了一条低心智负担的、敏捷的、能够以可扩展、可复制的方式最大化地利用云的能力、发挥云的价值的最佳路径。 2、云原生思想两个理论 第一个理论基础是&#xff1a;不可变基础设施。 第二个理论基础是&#xff1a;云应用编排理…

【牛客面试必刷TOP101】Day20.BM18 二维数组中的查找和BM19 寻找峰值

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;牛客面试必刷TOP101 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01;&…

Java学习第十三节之三种初始化和内存分析

三种初始化 package array;public class ArrayDemo02 {public static void main(String[] args) {//静态初始化&#xff1b;创建赋值int[] a {1, 2, 3, 4, 5, 6, 7, 8};System.out.println(a[0]);for (int i 0; i <a.length; i) {System.out.println(a[i]);}//动态初始化…

Java实现中学生家校互联系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 学生管理模块2.2 课堂表现模块2.3 考试成绩模块2.4 家校留言模块2.5 校园通知模块 三、系统设计3.1 用例设计3.2 实体类设计3.2.1 课堂表现实体类设计3.2.2 考试成绩实体类设计3.2.3 家校留言实体类设计3.2.4 校园通知实…

Netty应用(十二) 之 Netty相关参数 Http协议 IO多路复用回顾

目录 28.netty的相关参数 29.HTTP1.0、HTTP1.1 和 HTTP2.0 的区别 30.如何理解IO多路复用&#xff1f; 28.netty的相关参数 1.netty的参数设置体系 客户端&#xff1a; bootstrap.option(); //在这里配置客户端一些配置信息 服务端&#xff1a; serverBootstrap.option(…

【ES6】Promise

Promise 回调地狱 const fs require(fs);fs.readFile(./a.txt, utf-8, (err, data) > {if(err) throw err;console.log(data);fs.readFile(./b.txt, utf-8, (err, data) > {if(err) throw err;console.log(data);fs.readFile(./c.txt, utf-8, (err, data) > {if(er…

二叉树-------前,中,后序遍历 + 前,中,后序查找+删除节点 (java详解)

目录 提要&#xff1a; 创建一个简单的二叉树&#xff1a; 二叉树的前中后序遍历&#xff1a; 二叉树的前序遍历&#xff1a; 二叉树的中序遍历&#xff1a; 二叉树的后续遍历&#xff1a; 小结&#xff1a; 二叉树的前中后续查找&#xff1a; 二叉树的前序查找&#…

双链表简介

一.双链表 这里简单的介绍一下双链表&#xff0c;双链表也是和单链表是一种类型的结构&#xff0c;但是也有些许不同&#xff0c;其中不同的地方在于&#xff0c;双链表多了一个可以存储上一个单元的地址&#xff0c;并且是循环的链表&#xff0c;而且还增加了一个哨兵位&…

【linux内核调试及根文件系统】

linux内核分成两个部分&#xff0c;一个是逻辑代码存于驱动代码&#xff0c;一个是硬件信息存于设备树 linux内核分成两个部分一部分为逻辑代码放在uimage&#xff0c;另一部分硬件信息放在设备树

【STM32 CubeMX】HAL库的本质读写寄存器

文章目录 前言一、HAL库的本质1.1 HAL库的本质是操作寄存器1.2 自己实现HAL_GPIO_WritePin寄存器通过寄存器的操作点灯代码概况Port bit set/reset register寄存器 总结 前言 在嵌入式系统开发中&#xff0c;HAL&#xff08;Hardware Abstraction Layer&#xff09;库是一个重…

Kotlin和Java 单例模式

Java 和Kotlin的单例模式其实很像&#xff0c;只是Kotlin一部分单例可以用对象类和委托lazy来实现 Java /*** 懒汉式&#xff0c;线程不安全*/ class Singleton {private static Singleton instance;private Singleton() {}public static Singleton getInstance() {if (insta…

肯尼斯·里科《C和指针》第13章 高级指针话题(2)函数指针

我们不会每天都使用函数指针。但是&#xff0c;它们的确有用武之地&#xff0c;最常见的两个用途是转换表(jump table)和作为参数传递给另一个函数。本节将探索这两方面的一些技巧。但是&#xff0c;首先容我指出一个常见的错误&#xff0c;这是非常重要的。 简单声明一个函数指…

静态时序分析:SDC约束命令set_clock_uncertainty

相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 set_clock_uncertainty是用来指定设计中时钟周期的不确定性&#xff0c;不确定性指的是对那些会对时钟周期造成的负面影响。这些不确定性可能来源于时钟抖动(clo…

【JavaEE】_JavaScript(Web API)

目录 1. DOM 1.1 DOM基本概念 1.2 DOM树 2. 选中页面元素 2.1 querySelector 2.2 querySelectorAll 3. 事件 3.1 基本概念 3.2 事件的三要素 3.3 示例 4.操作元素 4.1 获取/修改元素内容 4.2 获取/修改元素属性 4.3 获取/修改表单元素属性 4.3.1 value&#xf…

HotCoin Global: 澳洲双牌照持有平台,坚守全球合规之路

前言&#xff1a; 加密交易平台的合规性不仅是相关法规遵守的问题&#xff0c;更是市场透明度和用户公平性的关键。为促使加密市场的交易活动有规范、有秩序地进行&#xff0c;确保加密投资者的资产与交易安全&#xff0c;部分国家明确对加密资产的交易和经营活动进行监督及管…

SNMP 简单网络管理协议、网络管理

目录 1 网络管理 1.1 网络管理的五大功能 1.2 网络管理的一般模型 1.3 网络管理模型中的主要构件 1.4 被管对象 (Managed Object) 1.5 代理 (agent) 1.6 网络管理协议 1.6.1 简单网络管理协议 SNMP 1.6.2 SNMP 的指导思想 1.6.3 SNMP 的管理站和委托代理 1.6.4 SNMP…

博客系统-SpringBoot版本

相比于之前使用Servlet来完成的博客系统&#xff0c;SpringBoot版本的博客系统功能更完善&#xff0c;使用到的技术更接近企业级&#xff0c;快来看看吧~ 目录 1.项目介绍 2.数据库准备 3.实体化类 4.返回格式 5.登录和注册功能 6.登出&#xff08;注销&#xff09;功能…

【Python】Python代码的单元测试

Python代码的单元测试 单元测试的概念 定义&#xff1a;是指对软件中的最小可测试单元进行检查和验证。 作用&#xff1a;可以确保程序模块是否否和我们规范的输出&#xff0c;保证该模块经过修改后仍然是满足我们的需求。 单元测试的策略 如果要创建单元测试&#xff0c;…

C语言-----用二维数组解决菱形的打印问题

1.打印菱形&#xff0c;多组输入&#xff0c;一个整数&#xff08;2~20&#xff09;&#xff0c;表示输出的行数&#xff0c;也表示组成“X”的反斜线和正斜线的长度。 #include <stdio.h>int main() {int n0;while(scanf("%d",&n)! EOF){int i0;int j0;f…

初识webpack(二)解析resolve、插件plugins、dev-server

目录 (一)webpack的解析(resolve) 1.resovle.alias 2.resolve.extensions 3.resolve.mainFiles (二) plugin插件 1.CleanWebpackPlugin 2.HtmlWebpackPlugin 3.DefinePlugin (三)webpack-dev-server 1.开启本地服务器 2.HMR模块热替换 3.devServer的更多配置项 (…