STM32学习笔记 -系统时钟Systick

it2022-05-05  174

文章目录

一、SysTick系统时钟滴答定时器的相关概念。1.SysTick的两大作用。1.1 可以产生精确延时。(节省定时器)1.2 可以提供给操作系统一个单独的心跳(时钟)节拍。(主要!) 2.SysTick的定义。3.SysTick运行机制。4.SysTick相关寄存器。SysTick 重装载数值寄存器->LOAD。(24bit)SysTick 当前值寄存器->VAL。(24bit)SysTick控制和状态寄存器->CTRL。SysTick->CALIB。(略) 二、Systick初始化。1.思路:2.库函数版代码使用到的库函数SysTick_CLKSourceConfig():SysTick_Config(): 3.寄存器版代码 三、Systick写延迟函数。1. 回顾:通常实现延时函数的方法。2.Systick定时器延时实现代码。

一、SysTick系统时钟滴答定时器的相关概念。

1.SysTick的两大作用。

1.1 可以产生精确延时。(节省定时器)

1.2 可以提供给操作系统一个单独的心跳(时钟)节拍。(主要!)

2.SysTick的定义。

systick定时器是 24位 的,永不停息 的, 递减计数器。 (2^24 =16M ,永不停息是指:只要不清除 systick 控制及状态寄存器中的 使能位 ,systick定时器永不停息,睡眠模式下也工作.)

3.SysTick运行机制。

运行机制: SysTick设定处置并使能后,每经过一个系统时钟周期,计数值就减1.计数到0时,SysTick计数器自动重装初值并继续计数,同时内部的COUNTFLAG标志会置位,若中断使能就会触发中断。

系统时钟周期:外部晶振为8MHz,9倍频,系统时钟为72MHz,SysTick的最高频率为9MHz(最大为HCLK/8)。 SysTick时钟设置为最大值9MHz(9 000 000), 把SysTick计数值设置为9000,就能够产生1ms的时间基值,即SysTick产生1ms的计数。 把SysTick计数值设置为9,就能够产生1us的时间基值,即SysTick产生1ms的计数. 选择外部时钟时:滴答定时器时钟为9M (意味着 一个us ,值减少9) 要延时1us, 往val装9就可以了

4.SysTick相关寄存器。

下表中的四个寄存器管理了SysTick的运行。

SysTick 重装载数值寄存器->LOAD。(24bit)

这个寄存器是用来装载我们需计数的次数的寄存器。(它给VAL寄存器装作数值)

SysTick 当前值寄存器->VAL。(24bit)

每一个时钟周期,VAL的值自减1。 当VAL值为0时,会重新加载LOAD中的值,并且产生COUNTFLAG标志。(COUNTFLA标志在CTRL寄存器)

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

下表解释的十分详细。 第0位 是定时器使能位。 第1位 是中断使能位,用于决定自减为0后是否执行中断。 第2位 是时钟源选择位 ,可以选择内部时钟或外部时钟作为时钟源。 第16位是计数标志位 ,SysTick自减到0时,该位置1。读取该位后,该位自动清零。 注意点: COUNTFLAG为计数完毕标志,读取后会自动清零。 TICKINT产生SysTick异常请求意思是产生中断。

SysTick->CALIB。(略)

用来校准计数器的,不常用。

二、Systick初始化。

1.思路:

先失能,关闭中断,再装载值,最后再开启。(固件库的直接调用配置函数SysTick_Config()即可)

2.库函数版代码

3.5固件库版本中库函数与中文手册的有所差异。 配置代码

SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); SysTick_Config(72);

使用到的库函数

void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource) static __INLINE uint32_t SysTick_Config(uint32_t ticks)

SysTick_CLKSourceConfig():

功能:选择时钟源 操作:改变SysTick 控制和状态寄存器- CTRL 中 第2位段(0,1,2 即第三个位置)的值 入口参数:1 SysTick_CLKSource_HCLK 内部时钟 HCLK 72M 2 SysTick_CLKSource_HCLK_Div8 外部时钟 HCLK/8 9M 返回值:无

`void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource) { /* Check the parameters */ assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource)); if (SysTick_CLKSource == SysTick_CLKSource_HCLK) { SysTick->CTRL |= SysTick_CLKSource_HCLK; } else { SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8; } } //SysTick_CLKSource_HCLK_Div8,SysTick_CLKSource_HCLK 的宏定义如下 //#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB) //#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004)

SysTick_Config():

功能:1、初始化systick 2、打开systick 3、打开systick的中断并设置优先级 操作:略 入口参数:Uint32_t ticks 即为重装值, 返回值:返回一个0代表成功或1代表失败

//此函数在core_cm3.h定义 //如果参数ticks是 72 的话,1us计数完毕,即1us置COUNTFLAG为1一次。 //如果参数ticks是 72000 的话,1ms计数完毕,即1ms置COUNTFLAG为1一次。 static __INLINE uint32_t SysTick_Config(uint32_t ticks)//static 表示只能在此头文件中实验 { //判断tick的值是否大于 2^24 ,如果大于,则不符合规则 if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ //配置 reload 寄存器的初始值 SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ //配置中断优先值,1<<4-1 = 15 v 配置为15,默认为最低的优先级 NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */ //配置 counter 计数器的值 SysTick->VAL = 0; /* Load the SysTick Counter Value */ //配置systick时钟为72M //使能中断 //使能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 */ }

3.寄存器版代码

void Systick_us_Config(u16 delay_us) { SysTick->CTRL &= ~(0x3);//失能Systick,关闭Systick中断 SysTick->CTRL &= ~(1<<2);//选择时钟,选用外部时钟,HCLK/8 //systemClock*1000/8 = 9000000 = 9MHz;1s 9M,1us 9K SysTick->LOAD = 9000*delay_us;//装载值 SysTick->VAL = 0x00; SysTick->CTRL |= 0x1;//使能Systick } void Systick_ms_Config(u16 delay_ms) { SysTick->CTRL &= ~(0x3);//失能Systick,关闭Systick中断 SysTick->CTRL &= ~(1<<2);//选择时钟,选用外部时钟,HCLK/8 //systemClock*1000/8 = 9000000 = 9MHz;1s 9M,1us 9K SysTick->LOAD = 9000*delay_us;//装载值 SysTick->VAL = 0x00; SysTick->CTRL |= 0x1;//使能Systick }

三、Systick写延迟函数。

1. 回顾:通常实现延时函数的方法。

通常实现延迟函数的方法为:

void delay_ms(int x ) { int i; while(x--) for(i=0;i<x;i++); }

x - - 对应于N毫秒的循环值。 缺陷:1占用cpu,浪费cpu资源.2中断会打断即时,易出错。

2.Systick定时器延时实现代码。

该代码还是占用了cpu资源。。。待续

//bsp_systick.h文件 #ifndef BSP_SYSTICK_H #define BSP_SYSTICK_H #include "stm32f10x.h"//stm32f10x.h定义了 core_cm3.h 中的IRQn_Type #include "core_cm3.h"//systick在内核,stm32f10x.h是外设的库,core_cm3.h是定义内核中的外设 void SysTick_Delay_us(uint32_t us); void SysTick_Delay_ms(uint32_t ms); #endif //bsp_systick.c文件 #include "bsp_systick.h" void SysTick_Delay_us(uint32_t us) { uint32_t i; SysTick_Config(72); for(i=0;i<us;i++) while(!(SysTick->CTRL&(1<<16)) ); SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; } void SysTick_Delay_ms(uint32_t ms) { uint32_t i; SysTick_Config(72000); for(i=0;i<ms;i++) while(!(SysTick->CTRL&(1<<16)) ); SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; }

最新回复(0)