STM32中,systick具体延时时间怎么计算的?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32中,systick具体延时时间怎么计算的?相关的知识,希望对你有一定的参考价值。

systick定时器有两个可选的时钟源,一个是外部时钟源(STCLK,等于HCLK/8),另一个是内核时钟(FCLK,等于HCLK)。假若你选择内核时钟,并将HCLK频率设置为72MHz的话,系统时钟周期为1/(72M);systick有一个24位的递减计数器,每个系统时钟周期计数器值减一,那么当计数器减到零时,时间经过了:系统时钟周期*计数器初值。当你将计数器初值设为72000时(有些例程里面设为71999,其实没什么影响,误差极小),当计数器值减到0时经过了1/(72M)*72000=0.001s,即1ms。你可以看一下芯达STM32的入门教程和《ARM Cortex-M3权威指南》的相关章节,里面关于systick编程的一章说的比较详细,但是也有个别地方说的比较模糊,总之多看些例程就明白了,刚开始总是很纠结的~ 参考技术A 哈哈哈你太有福气了,刚研究出来的,感觉好就给个好评
/****************************************************************************
* STM32单片机SysTick系统滴答定时器实验程序
*
*
*
*****************************************************************************/
#ifndef _SYSTICK_H
#define _SYSTICK_H
#include "SysTick.h"
#define SYSTICK_CSR (*((volatile unsigned long *) 0xE000E010))//控制寄存器
#define SYSTICK_LOAD (*((volatile unsigned long *) 0xE000E014))//重载寄存器
#define SYSTICK_VAL (*((volatile unsigned long *) 0xE000E018))//当前值寄存器
#define SYSTICK_CALRB (*((volatile unsigned long *) 0xE000E01C)) //校准值寄存器
unsigned long SysTick_Delay;//全局变量
//配置寄存器
void SysTick_InitStructReadCmd(void)

SYSTICK_VAL = 0; //当前值寄存器清零
SYSTICK_LOAD = SystemCoreClock / 1000000; //重要部分就在这里 系统72000000 / 100000
SYSTICK_CSR |= 0x06; //先关闭SysTick使能用的时候在打开

//中断服务程序
void SysTick_Hangler(void)

SYSTICK_VAL = 0; //当前值寄存器清零
if(SysTick_Delay != 0x00)//判断延时SysTick_Delay 是否等于0

SysTick_Delay--;//减到0结束


//延时函数
void Delay_10us(unsigned long Countlinef)

SYSTICK_CSR |= 0x07; //启动SysTick使能
SysTick_Delay = Countlinef; //把延时变量赋值SysTick_Delay全局变量
while(SysTick_Delay != 0); //判断延时时间是否到
SYSTICK_CSR |= 0x06; //时间到关闭 SysTick使能用的时候在打开

int main(void)

SystemInit(); //注意这么是把系统时钟设初始化为 72M主频,这里是必须的
SysTick_InitStructReadCmd();
while(1)

GPIOD->BSRR = 0x00000100;
Delay_10us(1000000) ; //实现1ms延时
GPIOD->BRR = 0x00000100;


//====================================END=============================================//
/* 好了我们开始讲解程序1us是怎么实现的,我们使用时钟源为APB时钟,APB系统频率陪配置为72MHZ
SYSTICK_LOAD = SystemCoreClock / 1000000; SysTick重载初值重要的地方就在这里
1:SystemCoreClock 这个是什么意思,跟踪库函数找到如下:
#ifdef SYSCLK_FREQ_HSE
uint32_t SystemCoreClock = SYSCLK_FREQ_HSE;
#elif defined SYSCLK_FREQ_24MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz;
#elif defined SYSCLK_FREQ_36MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_36MHz;
#elif defined SYSCLK_FREQ_48MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz;
#elif defined SYSCLK_FREQ_56MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz;
#elif defined SYSCLK_FREQ_72MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz;
#else /*!< HSI Selected as System Clock source */
// uint32_t SystemCoreClock = HSI_VALUE;
/*这里不难看出,我们初始化SystemInit(); 是系统已经把SystemCoreClock配置成72M下面就不难理解了,
先看一下计算公式:T = TICKS * (1/f);
T : 为要计时的总时间。
TICKS :为SYSTICK_LOAD 的输入参数。
(1/f)为使用时钟源的时钟周期,f为时钟源的时钟频率
使用时钟源为AHB时钟, 频率被配置72M;
把SYSTICK_LOAD重载寄存器赋值为 SystemCoreClock / 1000000;呵呵呵大家
发现了什么,就是72000000 / 1000000 = 72;大家都应该知道了72个时钟周期
中断一次,大家接着看(1/f)是时钟周期的时间。1/72M = 0.13888888888888888888888888888889;
1us诞生了,0.13888888888888888888888888888889*72 = 1;1us哈哈哈大家明白了吧。
//野火资料出问题的地方 ticks=SystemFrequency / 10 000 =720,相当于:72000000 / 10000 ;这里少了一个0 结果等于 = 7200 不等于720看资料看的纠结哈哈哈。
这个程序折磨我1个星期,没有吃好睡好,搞明白后我就马上做上笔记那给大家分享。

*/
参考技术B

没必要弄得上面那么复杂吧。就三句话:

    systick是个递减计数器,每个时钟周期会把寄存器的值(即重载值)减1,减到0就触发systick中断。

    systick的时钟频率=每秒systick递减操作的次数。

    公式:systick延时时间=重载值/systick时钟频率,单位秒。

以上是关于STM32中,systick具体延时时间怎么计算的?的主要内容,如果未能解决你的问题,请参考以下文章

stm32左转延时

在stm32中利用systick来延时,这阻塞了CPU吗? 执行到延时程序的时候,CPU就一直停在那里等待时间到达么?

STM32 系统定时器(SysTick)

STM32 滴答定时器

STM32怎么用库函数使用滴答定时器?

stm32用SysTick延时