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中通过结构体只是声明这个几个寄存器变量,但是功能没有体现,哪位高手知道哪里有这四个寄存器功能实现的底层代码,学程序想刨根学,所以请高手指教
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 定时器
STM32 学习8 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定时器的配置步骤
-
- 设置是时钟源
-
- 设置SysTick定时器的重装载初始值
-
- 清零当前计数器值
-
- 打开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寄存器的功能在哪里设置的的主要内容,如果未能解决你的问题,请参考以下文章
STM32 的系统滴答定时器( Systick) 彻底研究解读
STM32中 Systick问题 while(SysTick_Config(SystemFrequency / 1000)); 是啥意思,实现啥功能,求大神