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位置1do{temp=SysTick->CTRL;//检查CTRL的ENABLE位和COUNTFLAG位//如果ENABLE位为0或者COUNTFLAG位为1则判断为计数结束 等待时间到达   }while((temp&0x01)&&!(temp&(1<<16)));SysTick->CTRL&=~1;	    //关闭计数器     ENABLE位置0SysTick->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 */

 

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

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

相关文章

ES6中的数组解构赋值【详解】

文章目录 1.数组的解构赋值1.1 基本用法1.2 默认值1.3更多对象解构赋值 1.数组的解构赋值 1.1 基本用法 ES6允许按照一定的模式&#xff0c;从数组和对象中提取值&#xff0c;对变量进行赋值&#xff0c;这被称为结构。 let [a, b, c] [1, 2, 3];如果解构不成功&#xff0c…

python学习(三):pip安装及如何加速安装第三方组件

pip全称Package Installer for Python&#xff0c;即用来安装第三方组件的工具 一.安装pip Python3中setuptools、Pip安装详解 1、安装setuptools 命令如下&#xff1a; wget --no-check-certificate https://pypi.python.org/packages/source/s/setuptools/setuptools-19.…

不确定性、先验概率_后验概率、概率密度、贝叶斯法则、朴素贝叶斯_、最大似然估计

【人工智能】— 不确定性、先验概率/后验概率、概率密度、贝叶斯法则、朴素贝叶斯 文章目录 【人工智能】— 不确定性、先验概率/后验概率、概率密度、贝叶斯法则、朴素贝叶斯不确定性不确定性与理性决策基本概率符号先验概率(无条件概率)/后验概率(条件概率)随机变量概率密度联…

【web | CTF】BUUCTF [网鼎杯 2020 青龙组]AreUSerialz

天命&#xff1a;php的序列化题目简直是玄学&#xff0c;既不能本地复现&#xff0c;也不能求证靶场环境 天命&#xff1a;本地php是复现不了反序列化漏洞的&#xff0c;都不知道是版本问题还是其他问题 天命&#xff1a;这题也是有点奇怪的&#xff0c;明明用字符串2也应该是可…

优雅地用eruda在移动端上调试网页

eruda简介 github开源项目网址:eruda Eruda 是一个专为手机网页前端设计的调试面板,类似 DevTools 的迷你版,其主要功能包括:捕获 console 日志、检查元素状态、捕获XHR请求、显示本地存储和 Cookie 信息等等。 其有以下功能: Console面板:捕获Console日志,支持log、…

C语言—指针

碎碎念:做指针题的时候我仿佛回到了原点&#xff0c;总觉得目的是为了把框架搭建起来&#xff0c;我胡说的哈31 1.利用指针变量将一个数组中的数据反向输出。 /*1.利用指针变量将一个数组中的数据反向输出。*/#include <stdio.h> #include <time.h> #include <…

phpstrom创建thinkphp项目

安装php和composer 参考 安装phpstrom 创建项目 查看thinkphp版本 https://packagist.org/packages/topthink/think 打开所在项目编辑配置 即可调试运行

二维码的颜色怎么改变?轻松3步修改二维码样式

怎么修改二维码的颜色呢&#xff1f;一般我们制作的二维码或者经过系统生成的二维码大多都是黑白颜色的&#xff0c;有些小伙伴会觉得不太美观无法满足自己的使用需求。那么对于想要修改二维码样式的小伙伴&#xff0c;可以使用二维码生成器的二维码美化功能来处理&#xff0c;…

小红书种草笔记是什么?小红书种草什么意思?

小红书种草笔记是指在小红书这个平台上&#xff0c;用户发布的关于生活方式、消费经验、美妆、时尚、旅行等方面的分享和推荐。这种笔记通常以第一人称叙述&#xff0c;以个人体验和感受为基础&#xff0c;向其他用户推荐自己喜欢或认为值得尝试的产品、服务或体验。种草一词源…

07 按键控制 LED

按键简介 按键开关是一种电子开关&#xff0c;属于电子元器件类。常见的按键开关有两种&#xff0c;第一种是轻触式按键开关&#xff08;简称轻触开关&#xff09;&#xff0c;使用时以向开关的操作方向施加压力使内部电路闭合接通&#xff0c;当撤销压力时开关断开&#xff0…

git分布式版本控制工具基本操作

Windows操作 1.1 git基本操作 1.设置用户签名 git config user.name xx git config user.email xxb163.com2.初始化本地库 git init3.查看本地库状态 git status4.添加暂存区 git add 文件名称 git add *5.提交本地库 git commit -m "描述信息" 文件6.查看版本…

《富爸爸:巴比伦最富有的人》读书笔记

目录 作者简介 感悟 经典摘录 观点&#xff1a; 支付给自己(理解是投资自己) 观点&#xff1a;源源不断地放入金币 观点&#xff1a; 把收入的一部分留给我自己 观点&#xff1a; 从专业的人士得到建议 观点&#xff1a;一旦为自己规定了任务&#xff0c;就一定要完成 …

虚拟环境(二)venv

1、创建虚拟环境 python3 -m venv fastapi_test2、激活虚拟环境 source <环境名称>/bin/activate3、关闭虚拟环境 deactivate4、从虚拟环境生成 requirement.txt 在激活虚拟环境下敲pip freeze > requirement.txt 5、安装依赖包 在激活虚拟环境下敲使用pip inst…

微波炉维修笔记

微波主要是靠2.45GHz 左右的微波(12.2cm 波长)加热水分子实现食物加热 所有不要使用金属器皿进行加热&#xff0c;要么因为电磁屏蔽&#xff0c;起不到加热效果&#xff0c;要么火光四射 微波炉基本组成 借鉴姜师傅的视频 碰到不加热其它都正常的问题 1.检查高压电容 使用万…

自动驾驶中的 DCU、MCU、MPU、SOC 和汽车电子架构

自动驾驶中的 DCU、MCU、MPU 1. 分布式电子电气架构2. 域集中电子电气架构架构2.1 通用硬件定义 3. 车辆集中电子电气架构4. ADAS/AD系统方案演变进程梳理4.1 L0-L2级别的ADAS方案4.2 L2以上级别的ADAS方案 5. MCU和MPU区别5.1 MCU和MPU的区别5.2 CPU与SoC的区别5.3 举个例子 R…

算法:柠檬水找零

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、问题描述 二、解法分析 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#xff1a;随着人工智能的不断发展&#xff0…

【STM32】软件SPI读写W25Q64芯片

目录 W25Q64模块 W25Q64芯片简介 硬件电路 W25Q64框图 Flash操作注意事项 状态寄存器 ​编辑 指令集 INSTRUCTIONS​编辑 ​编辑 SPI读写W25Q64代码 硬件接线图 MySPI.c MySPI.h W25Q64 W25Q64.c W25Q64.h main.c 测试 SPI通信&#xff08;W25Q64芯片简介&am…

关于CDN

CDN&#xff08;内容分发网络&#xff09;是一种分布式的服务器系统&#xff0c;旨在有效地提供互联网上的内容&#xff0c;特别是静态资源&#xff0c;如图片、样式表、脚本文件等。CDN的主要目标是提高网站的性能、降低加载时间&#xff0c;并减轻原始服务器的负载。 CDN的工…

12-输入/输出项目构建命令行程序

上一篇&#xff1a; 11-编写自动化测试 本章是对迄今为止所学到的许多技能的回顾&#xff0c;也是对一些标准库特性的探索。我们将创建一个与文件和命令行输入/输出交互的命令行工具&#xff0c;以练习你现在掌握的一些 Rust 概念。 Rust 的速度、安全性、单一二进制输出和跨平…

说说对BOM的理解(常见的BOM对象了解哪些)

文章目录 一、是什么二、window三、location四、navigator五、screen六、history 一、是什么 BOM (Browser Object Model)&#xff0c;浏览器对象模型&#xff0c;提供了独立于内容与浏览器窗口进行交互的对象 其作用就是跟浏览器做一些交互效果,比如如何进行页面的后退&…