STM32中systick下的CTRL、LOAD 、CALIB、VAL寄存器的功能在哪里设置的

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32中systick下的CTRL、LOAD 、CALIB、VAL寄存器的功能在哪里设置的相关的知识,希望对你有一定的参考价值。

STM32中systick下的CTRL、LOAD 、CALIB、VAL的功能在哪里设置的,在固件库中有CTRL:SysTick控制和状态寄存器
LOAD:SysTick重装载值寄存器
VAL:SysTick当前值寄存器
CALIB:SysTick校准值寄存器
但是我在看不论是固件库或者直接寄存器操作的程序中,都是直接调用这几个寄存器操作,比如systick->CTRL&oxFFFFFFFB,
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL=0x01 ; //开始倒数
这几个寄存器的功能我在STM32参考手册,cortexM3权威指南中都未找到他们这些功能,只有在固件库中提到了一下他们的功能,如果是固件库中的功能,都可以通过直接操作寄存器来设置,但是我找不到systick下着四种寄存器,那么我看到的那些初始化延时函数中使用的计数,清零,是从哪来的,在STM32F10x_MAP.H中通过结构体只是声明这个几个寄存器变量,但是功能没有体现,哪位高手知道哪里有这四个寄存器功能实现的底层代码,学程序想刨根学,所以请高手指教

systick叫做系统滴答时钟,这个不属于是STM32的片内外设,而是cortexM3内核里面自带的一个时钟模块,这个模块一般用于嵌入式系统的系统定时(也就是分时间片段处理定时),所以没有专门的固件库函数,但是对这几个寄存器的操作被封装到core_cm3.h中了,函数原型是:

static __INLINE uint32_t SysTick_Config(uint32_t ticks)

if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */

SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */

具体功能就是初始化系统滴答时钟,然后让时钟产生一个很精确的固定定时中断,一般我们可以把这个功能封装成一个很精确的延时函数.这个模块的使用很简单,就是一个初始化函数和一个中断服务函数,初始化函数就是上面的那个,都是直接对寄存器进行写入的,这个应该就是你想要的底层代码了,我也是一个初学者,所以我的回答不一定是正确的,但是这个是我查阅过资料之后再加上自己的理解,所以如果有大神看到有问题的地方还望指出,谢谢.
参考技术A 这几个寄存器在Cortex-M3权威指南中文翻译版的第8章有介绍的,好像是130多页吧,自己去找找看

STM32 学习9 SysTick 定时器

一、介绍

SysTick定时器,又称为SysTick滴答定时器,它是Cortex-M3内核的一个外设,嵌入在NVIC中。
SysTick是24位向下递减的定时器,计数一次需要的时间是 1/SYSTICK , SYSTICK是系统定时器时钟,取自系统时钟或者系统时钟8分频后值。
定时器计数到0时,会产生一个中断信号,并从LOAD寄存器中自动重装定时器初值,重新计数。
SysTick定时器可服务于操作系统、倒计时等使用。

二、SysTick定时器寄存器

1. CTRL 寄存器

Sys Tick定时器的控制及状态寄存器。

  • 16位段: 名称 COUNTFLAG , 类型 R, 复位值: 0 ,如果上次读取本寄存器后,Sys Tick已经数到了0,则该位为1, 如果读取该位,该位将自动清零。
  • 2 位段: CLKSOURCE , 类型 R/W, 0=外部时钟源,1=内核时钟
  • 1 位段: TICKINT , 类型: R/W, 1=SysTick倒数到0,产生中断; 0 数到0无动作
  • 0位段: ENABLE,类型: R/W, SysTick定时器的使能位。

2. LOAD 寄存器

重装载数值计数器,位段: 23:0 , 类型 R/W。

3. VAL 寄存器

当前数值寄存器,位段: 23:0, 类型 R/Wc, 写值就会清零,同时清除SysTick控制及状态寄存器中的COUNTFLAG状态。

4. CALIB 寄存器

SysTick定时器的校准数值寄存器。

三、SysTick定时器的配置步骤

    1. 设置是时钟源
    1. 设置SysTick定时器的重装载初始值
    1. 清零当前计数器值
    1. 打开SysTick定时器

四、相关函数

1. HAL_SYSICK_Config

设置定时时间,用法:

 /**Configure the Systick interrupt time 
    */
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);// 设置定时时间
 

重 装 载 值 = s y s t i c k 时 钟 频 率 ( H z ) ∗ 想 要 的 定 时 时 间 ( S ) 重装载值=systick 时钟频率(Hz) * 想要的定时时间(S) =systick(Hz)S
如:时钟频率为:AHB的8分频;AHB=72MHz
那么systick的时钟频率为72/8MHz=9MHz;
要定时1秒,则重装载值=9000000*1=9000000;
定时10毫秒,重装载状态值=9000000X0.01=90000

2. HAL_SYSTICK_CLKSourceConfig

选择时钟源,用法:


    /**Configure the Systick 
    */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);//选择SYSTICK时钟源,
  /* SysTick_IRQn interrupt configuration */

可选值:

#define SYSTICK_CLKSOURCE_HCLK_DIV8    (0x00000000U)
#define SYSTICK_CLKSOURCE_HCLK         (0x00000004U)

3. HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

作用:设定优先级

五、延时函数SysTick.c

1. SysTick_Init 初始化

#include "SysTick.h"

static u8  fac_us=0;							//us延时倍乘数			   
static u16 fac_ms=0;							//ms延时倍乘数

void SysTick_Init(u8 SYSCLK){
   // 选择时钟源
   SysTick_CLKSourceCOnfig(SysTick_CLKSource_HCLK_Div8);
   // 微秒,定义公用变量
   fac_us=SYSCLK/8;
   // 计算毫秒重装载值
   fac_ms=(u16)fac_us*1000;
}

2. delay_us() 函数

/*******************************************************************************
* 函 数 名         : delay_us
* 函数功能		   : us延时,
* 输    入         : nus:要延时的us数
					注意:nus的值,不要大于798915us(最大值即2^24/fac_us@fac_us=21)
* 输    出         : 无
*******************************************************************************/		    								   
void delay_us(u32 nus)
{		
	u32 temp;
	// 装载初值	    	 
	SysTick->LOAD=nus*fac_us; 					//时间加载	  		 
	SysTick->VAL=0x00;        					//清空计数器
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;	//开启定时器,开始倒数	  
	do
	{
		temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(1<<16)));		//等待时间到达   
	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;	//关闭计数器
	SysTick->VAL =0X00;      					 //清空计数器	 
}

3. delay_ms


/*******************************************************************************
* 函 数 名         : delay_ms
* 函数功能		   : ms延时,
* 输    入         : nms:要延时的ms数
					注意:nms的值,SysTick->LOAD为24位寄存器,
					不要大于0xffffff*8*1000/SYSCLK
					对72M条件下,nms<=1864ms 
* 输    出         : 无
*******************************************************************************/
void delay_ms(u16 nms)
{	 		  	  
	u32 temp;		   
	SysTick->LOAD=(u32)nms*fac_ms;				//时间加载(SysTick->LOAD为24bit)
	SysTick->VAL =0x00;							//清空计数器
	SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;	//开始倒数  
	do
	{
		temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(1<<16)));		//等待时间到达   
	SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;	//关闭计数器
	SysTick->VAL =0X00;       					//清空计数器	  	    
} 


4. 头文件定义

#ifndef _SysTick_H
#define _SysTick_H

#include "system.h"

void SysTick_Init(u8 SYSCLK);
void delay_ms(u16 nms);
void delay_us(u32 nus);



#endif

5. 使用 main.c


#include "SysTick.h"
#include "led.h"



int main()
{
	SysTick_Init(72);
	// 这里使用了位绑定,后面章节会介绍。
	LED_Init();
	while(1)
	{
		led1=0;
		led2=1;
		delay_ms(500);  //精确延时500ms
		led1=1;
		led2=0;
		delay_ms(500);  //精确延时500ms
	}
}

以上是关于STM32中systick下的CTRL、LOAD 、CALIB、VAL寄存器的功能在哪里设置的的主要内容,如果未能解决你的问题,请参考以下文章

STM32F4SysTick记录

STM32 学习9 SysTick 定时器

stm32用SysTick延时

STM32 的系统滴答定时器( Systick) 彻底研究解读

STM32中 Systick问题 while(SysTick_Config(SystemFrequency / 1000)); 是啥意思,实现啥功能,求大神

STM32 滴答定时器