【STM32】用SysTick滴答定时器定时1s实现LED亮灭循环

        SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。在以前,大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统的时基。例如,为多个任务许以不同数目的时间片,确保没有一个任务能霸占系统;或者把每个定时器周期 的某个时间范围赐予特定的任务等,还有操作系统提供的各种定时功能,都与这个滴答定时器有关。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。

        SysTick定时器除了能服务于操作系统之外,还能用于其它目的:如作为一个闹铃,用于测量时间等。本文用SysTick滴答定时器定时1s。

逻辑:

1.配置滴答定时器时钟源,初始化微秒/毫秒数值。

2.相关寄存器配置:设置当前数值初始值、重装数值、控制状态(使能、读取计数标志位)等。

 程序仅使用到这三个SysTick定时器的寄存器。

【STM32】用SysTick滴答定时器定时1s实现LED亮灭循环_第1张图片

单片机里面,频率就是晶振的震动次数,72MHz代表1s震动72*10^6次,此时1us震动72次。系统时钟8分频下1us的频率:f=SystemCoreClock/8/1000000=9,计数值就是以频率为基础。(用于重装载数值计算)

SysTick.c(先配置滴答定时器时钟源,对于定时器即开即关)

#include "systick.h"

static u8 fac_us=0;
static u16 fac_ms=0;

void SysTick_Init(void)
{
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//AHB时钟除以8作为系统时钟源
	fac_us = SystemCoreClock/8000000; 
	fac_ms = (u16)fac_us*1000;
}

void delay_us(u32 nus)
{
	u32 temp;
	SysTick->LOAD = (u32)nus*fac_us;  //被重装载的值(重装数值寄存器)
    SysTick->VAL = 0x00;  //当前数值清0(当前数值寄存器)
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk ;  //使能滴答定时器(控制及状态寄存器第0位)
    do{
		temp = SysTick->CTRL ; 
		//读取寄存器,作用是获取控制及状态寄存器的值
        //SysTick已经倒数到了0,则COUNTFLAG位(控制及状态寄存器第16位)置1。
		//SysTick未数到0,则COUNTFLAG位为0。
	}while((temp&0x01)&&!(temp&(1<<16)));  
        //产生异常请求(控制及状态寄存器第0位)且SysTick未数到0(COUNTFLAG位为0)

    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;  //失能滴答定时器
    SysTick->VAL =0x00;  //当前值清0
}

void delay_ms(u16 nms)  //原理与上类似
{
	u32 temp;
	SysTick->LOAD = (u32)nms*fac_ms; 
	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;
}

SysTick.h

#ifndef __SYSTICK_H
#define __SYSTICK_H

#include "stm32f10x.h"

void SysTick_Init(void);

void delay_us(u32 nus);

void delay_ms(u16 nms);

#endif

led.h(开启相关时钟,初始化端口)

#include "led.h"

void LED_Init(void){
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);  //开启相关时钟
	
	GPIO_InitTypeDef GPIO_InitIntructrue;
	GPIO_InitIntructrue.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽输出
	GPIO_InitIntructrue.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitIntructrue.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC,&GPIO_InitIntructrue);  //初始化端口
}

void LED_ON(void){
	GPIO_SetBits(GPIOC,GPIO_Pin_13);
}

void LED_OFF(void){
	GPIO_ResetBits(GPIOC,GPIO_Pin_13);
}

led.h

#ifndef __LED_H
#define __LED_H

#include "stm32f10x.h"

void LED_Init(void);

void LED_ON(void);

void LED_OFF(void);

#endif

 main.c

#include "stm32f10x.h"
#include "systick.h"
#include "led.h"

int main(void)
{
	SysTick_Init();
	LED_Init();
	while(1){
		delay_ms(1000);
		LED_ON();
		delay_ms(1000);
		LED_OFF();
	}
}

一个入门级的小程序,记录一下。

你可能感兴趣的:(笔记,学习,STM32学习笔记,stm32,单片机,嵌入式硬件)