17、STM32——SysTick详解

1、简介

Cortex‐M3 处理器内部包含了一个简单的定时器。因为所有的 CM3 芯片都带有这个定时器,软件在不同 CM3 器件间的移植工作得以化简。该定时器的时钟源可以是内部时钟,或者是外部时钟。不过,STCLK 的具体来源则由芯片设计者决定,因此不同产品之间的时钟频率可能会大不相同,你需要查找芯片的器件手册来决定选择什么作为时钟源。

Cortex-M3 的内核中包含一个 SysTick 时钟。SysTick 为一个 24 位递减计数器,SysTick 设定初值并使能后,每经过 1 个系统时钟周期,计数值就减 1。计数到 0 时,SysTick 计数器自动重装初值并继续计数,同时内部的 COUNTFLAG 标志会置位,触发中断 (如果中断使能情况下)。


2、SysTick 包含的寄存器

STM32 中的 Systick 部分内容属于 NVIC 控制部分,一共有 4 个寄存器,名称和地址分别是:

STK_CSR      0xE000E010  --  控制寄存器	
STK_LOAD     0xE000E014  --  重载寄存器	
STK_VAL      0xE000E018  --  当前值寄存器	
STK_CALRB    0xE000E01C  --  校准值寄存器

STK_CSR 控制寄存器:寄存器内有 4 个位具有意义

第 0 位:ENABLE,Systick 使能位(0:关闭 Systick 功能;1:开启 Systick 功能)
第 1 位:TICKINT,Systick 中断使能位(0:关闭 Systick 中断;1:开启 Systick 中断)
第 2 位:CLKSOURCE,Systick 时钟源选择(0:使用 HCLK/8 作为 Systick 时钟;1:使用 HCLK 作为 Systick 时钟)
第 16 位:COUNTFLAG,Systick 计数比较标志,如果在上次读取本寄存器后,SysTick 已经数到了0,则该位为1。如果读取该位,该位将自动清零。
  • STK_LOAD 重载寄存器
    Systick 是一个递减的定时器,当定时器递减至0 时,重载寄存器中的值就会被重装载,继续开始递减。STK_LOAD 重载寄存器是个24 位的寄存器最大计数0xFFFFFF。
  • STK_VAL 当前值寄存器
    也是个24 位的寄存器,读取时返回当前倒计数的值,写它则使之清零,同
    时还会清除在 SysTick 控制及状态寄存器中的 COUNTFLAG 标志。
  • STK_CALRB 校准值寄存器
    位31 NOREF:= 1 没有外部参考时钟(STCLK 不可用),= 0 外部参考时钟可用
    位30 SKEW:= 1 校准值不是准确的1ms,= 0校准值是准确的1ms

3、代码:

那基于 STM32F10x V3.5.0 库如何操作 Systick 定时器呢?

STM32 的内核库已经提供了这个功能,只要配置 SysTick_Config() 即可实现。SysTick_Config 的参数,其实就是一个时钟次数,叫 systick 重装寄存器的值。意思就是我要多少个1/fosc 时间后中断一下。

#include "bsp_cpu.h"

static void BSP_CoreClockInit(void);
 
void BSP_CPUInit(void)
{
	BSP_CoreClockInit();
}

static void BSP_CoreClockInit(void)
{ 
	SysTick_Config(SystemCoreClock / 100);      //10ms
	//SysTick_Config(720000);    				//10ms
}

void SysTick_Handler(void)
{
	static uint8_t i=0;
	i++;
	if(i > 50)
	{
		i = 0;
		BSP_LedTurn();
	}
}

SystemCoreClock / 100 代表的是时钟次数,即放入重装载寄存器中的值,每计时一个数需要 1/72000000s 的时间,那么计SystemCoreClock / 100 (SystemCoreClock 为 72M)个数的时间就是 10ms,通过在中断中设置标志位达到 systick 定时中断的功能。

void delay_us(u32 nus)
{	 
	u32 temp;
	SysTick->LOAD = 9*nus;
	SysTick->VAL=0X00;//清空计数器
	SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
	do
	{
		temp=SysTick->CTRL;//读取当前倒计数值
	}while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
	SysTick->CTRL=0x00; //关闭计数器
	SysTick->VAL =0X00; //清空计数器
}
void delay_ms(u16 nms)
{
	u32 temp; 
	SysTick->LOAD = 9000*nms;
	SysTick->VAL=0X00;//清空计数器
	SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
	do
	{ 
		temp=SysTick->CTRL;//读取当前倒计数值
	}while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
	SysTick->CTRL=0x00; //关闭计数器
	SysTick->VAL =0X00; //清空计数器
}

分析:delay_us9*nus 的意义
假设外设频率为 9M,也就是经过 8 分频,那么计数 9 次是 1us,乘以 9 的意义就是参数的时间对应的次数,也就是重装载值,delay_ms同理。

  • 12
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值