SysTick 原理简介以及中断进不去的原因

一、SysTick 简介

SysTick ——系统定时器是属于 CM3 内核的一个外设,内嵌在 NVIC 中。系统定时器是一个 24 位的向下递减的计数器,计数器每计数一次的时间为 1/SYSCLK,一般我们设置系统时钟 SYSCLK 为 72MHz。当重装载数值寄存器的值递减到 0 时,系统寄存器就产生一次中断,循环往复。

二、SysTick 寄存器介绍

SysTick 系统定时器有 4 个寄存器,如下表,在配置 SysTick 产生定时的时候,只需要配置前 3 个寄存器,最后一个校准寄存器一般不需要使用

1、SysTick 控制及状态寄存器

COUNTFLAG:在上次读取此寄存器后,SysTick 如果计数到 0,则该位为 1。如果读取该位,该位将自动清 0

CLKSOURCE:时钟选择位,0=AHB/8,1=AHB

TICKINT: 1 代表 SysTick 计数到 0 时,产生异常请求,0 代表 SysTick 计数到 0 时,无动作

ENABLE:系统定时器使能位,用来使能定时器

2、SysTick 重装载数值寄存器

RELOAD: 当计数到 0 时,这个值将会被放到系统定时器上,开始计数

3、SysTick 校准数值寄存器

CURRENT:读取时,会返回当前倒计数的值,写它则使之清 0,同时还会清除在 SysTick 控制及状态寄存器中的 COUNTFLAG 标志

三、例程思路:

用系统定时器,每隔 100ms 产生一个中断,同时在中断函数中,设置一个变量 num,每进一次中断,该变量+1,并在 OLED 显示屏上显示出这个变量的值

#include "OLED7.h"
#include "Delay.h"
#include "stm32f10x_it.h"

uint32_t num = 0;// 设置全局变量,用来计数 SysTick 进入中断的次数	

int main(void)
{
	uint8_t i = 0;

	OLED7_Init();// 初始化 OLED 显示屏
    SysTick_Config(720000);//这个函数,下面会详细讲解

	for (; ;)
	{
		OLED7_ShowNum(2, 1, num, 5);// 在显示屏的 2 行 1 列显示全局变量 num

	}
    return 0;
}

void SysTick_Handler(void)// SysTick 中断处理函数
{
	num++;
}

SysTick _Config( ) 说明:

static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{ 

     //设置重装载值,和 2^24-1 进行比较,只有小于 2^24 代码才可以继续往下走,这是因为系统定时器 
     //是 24 位的计数器,超过这个数值的话,肯定是没有意义的
     if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);              
      
     // 将 Ticks 写入到 SysTick 的 LOAD 中,等计数为 0,这个值会放入到 24 位计数器里面                                                         
     SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; 

     // 设置中断优先级为 15,内核中断和外设中断配置 NVIC 不一样
     NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  
     
     // 设置计数器为 0
     SysTick->VAL   = 0; 

     // 设置 CTRL 寄存器                                      
     SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | //设置时钟源为 AHB
                      SysTick_CTRL_TICKINT_Msk   | //设置中断开启
                      SysTick_CTRL_ENABLE_Msk;     //ENABLE 定时器               
  return (0);                                                  
}

四、中断进不去的原因

因为我是用软件 SPI 来通讯 OLED 显示屏的,而当我写 SPI 函数的时候,用到了 Delay 函数,其中 Delay 函数就是用系统定时器来实现的,这就导致我每次调用一下 Delay 函数,定时器就会关断的状态,且中断也会关闭,这与 SysTick _Config( ) 的设置产生矛盾。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值