stm32怎么通过systick——系统计时器 实现led灯闪烁

一.SysTick简介

SysTick—系统定时器是属于 CM3 内核中的一个外设,内嵌在 NVIC 中。系统定时器是一个 24bit 的向下递减的计数器,计数器每计数一次的时间为 1/SYSCLK,一般我们设置系统时钟 SYSCLK 等于 72M。当重装载数值寄存器的值递减到 0的时候,系统定时器就产生一次中断,以此循环往复
SysTick—系统定时器有 4 个寄存器,简要介绍如下。在使用 SysTick 产生定时的时候,只需要配置前三个寄存器,最后一个校准寄存器不需要使用
寄存器名称 寄存器描述
CTRL SysTick 控制及状态寄存器
LOAD SysTick 重装载数值寄存器
VAL SysTick 当前数值寄存器
CALIB SysTick 校准数值寄存器

目标:利用 SysTick产生 1s 的时基,LED 以 1s的频率闪烁。

  1. 编程要点
    1、设置重装载寄存器的值
    2、清除当前数值寄存器的值
    3、配置控制与状态寄存器
    void SysTick_Init(void)
    {
    /* SystemFrequency / 1000 1ms 中断一次
  • SystemFrequency / 100000 10us 中断一次
  • SystemFrequency / 1000000 1us 中断一次
    */
    SysTick_Config(SystemCoreClock / 100000

SysTick 中断时间的计算
SysTick 定时器的计数器是向下递减计数的,计数一次的时间 T DEC =1/CLK AHB ,当重装
载寄 存器 中的值 VALUE LOAD 减到 0 的时 候 ,产 生中 断, 可知 中断 一 次的 时间
T INT =VALUE LOAD * T DEC = VALUE LOAD /CLK AHB , 其 中 CLK AHB =72MHZ 。 如 果 设 置
VALUE LOAD 为 72,那中断一次的时间 T INT =72/72M=1us。不过 1us 的中断没啥意义,整个
程序的重心都花在进出中断上了,根本没有时间处理其他的任务。
SysTick_Config(SystemCoreClock / 100000))
SysTick_Config()的形我们配置为 SystemCoreClock / 100000=72M/100000=720,从
刚刚分析我们知道这个形参的值最终是写到重装载寄存器 LOAD 中的,从而可知我们现在
把 SysTick定时器中断一次的时间 T INT =720/72M=10us。
SysTick 定时时间的计算当设置好中断时间 T INT 后,我们可以设置一个变量 t,用来记录进入中断的次数,那么变量 t 乘以中断的时间 T INT 就可以计算出需要定时的时间。
SysTick 定时函数
现在我们定义一个微秒级别的延时函数,形参为 nTime,当用这个形参乘以中断时间
T INT 就得出我们需要的延时时间,其中 T INT 我们已经设置好为 10us。关于这个函数的具体
调用看注释即可。

@brief us 延时程序,10us 为一个单位
@param
@arg nTime: Delay_us( 1 ) 则实现的延时为 1 * 10us = 10us
@retval 无

void Delay_us(__IO u32 nTime)
{ TimingDelay = nTime;

while (TimingDelay != 0);
}
函数 Delay_us()中我们等待 TimingDelay 为 0,当 TimingDelay 为 0 的时候表示延时时
间到。变量 TimingDelay 在中断函数中递减,即 SysTick 每进一次中断即 10us 的时间
TimingDelay 递减一次。

void TimingDelay_Decrement(void) { if (TimingDelay != 0x00) { TimingDelay–; } } TimingDelay 的值等于延时函数中传进去的 nTime 的值,比如 nTime=100000,则延时 的时间等于 100000*10us=1s

接下来就好办了,最麻烦的时间算出来了

开始编程

#include "stm32f10x.h"
#include "stm32f10x_it.h"
extern uint32_t  g_timer_count;
void  LED_init()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;	
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
}
void TIME_init()
{
	SysTick_Config(SystemCoreClock/100000);
	
}

void delay_us(uint32_t time){
	
	g_timer_count=time;
	while(g_timer_count!=0){
	}
	
}


int main()
{
	LED_init();
	TIME_init();
	while(1){
		GPIO_ResetBits(GPIOA,GPIO_Pin_8);
		delay_us(100000);
		GPIO_SetBits(GPIOA,GPIO_Pin_8);
		delay_us(100000);
	}
  return 0;
}

注意配置一下systick时钟中断服务函数,在stm32f10x_it.c里

uint32_t g_timer_count=0;
/**
  * @brief  This function handles SysTick Handler.
  * @param  None
  * @retval None
  */
void SysTick_Handler(void)
{
	if(g_timer_count>0)
	{
		g_timer_count--;
	}
}

你可能感兴趣的:(stm32)