基于Systick系统时钟延时的LED闪烁灯

发布者:平安宁静最新更新时间:2024-08-14 来源: cnblogs关键字:Systick  LED闪烁灯 手机看文章 扫描二维码
随时随地手机看文章

1、回顾我们的51 单片机编程,当我们需要做系统延迟的时候,最常采用的一

种方式就是使用for 循环的空语句等待来实现。


当然,在STM32 里面也可以这么实现。但是在STM32 的Cortex 内核里面,有个比其更加精准的定时器专业用于


系统定时,我们称之为Cortex 系统定时器(SysTick,系统滴答)。


Systick 就是一个定时器而已,只是它放在了NVIC(中断事件)中,


主要的目的是为了给操作系统提供一个硬件上的中断(号称滴答中断)。


这样,只要设置好其中断的时间,就可以每隔一定时间跳入其处理程序,


通过这种方式,我们可以做一些分时的任务处理。


然而,由于我们刚刚接触STM32,因此我们本课程内容,仅仅是


用其做一些延迟函数的处理。可能有些同学有疑问,微控制器的定时器资源一般


比较丰富,比如STM32 存在8 个定时器,为啥还要再提供一个SYSTICK?原因就

是所有基于ARM Cortex_M3 内核的控制器都带有SysTick 定时器,这样就方便了

程序在不同的器件之间的移植。而使用RTOS 的第一项工作往往就是将其移植到

开发人员的硬件平台上,由于SYSTICK 的存在无疑降低了移植的难度。具体

Systick 的概述,请参考《Cortex-M3 权威指南》179 页。


关于SysTick 的编程

流程如下:

 配置系统时钟;

 配置SysTick;

 写SysTick 中断处理函数;

 编写delay 延迟函数;


第一步:

先让我们来设置系统时钟。关于系统时钟的配置,我们可以直接使

用默认的固件库函数“void SystemInit(void);”,这个函数在固件库手册上面

是没有的,一旦使用默认配置之后,整个STM32 的系统时钟就会被配置成:

SYSCLK(系统时钟) = 72MHZ(系统最高允许时钟);

AHB 总线时钟= 72MHZ(AHB 最高允许时钟);

APB1 总线时钟= 36MHZ(APB1 最高允许时钟);

APB2 总线时钟= 72MHZ(APB2 最高允许时钟);


第二步:

配置SysTick。我们在设置SysTick 的时候,只用到“core_cm3.h”

文件的函数“__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)”。

这个函数在固件库里面是没有介绍的,因为这个函数是在“core_m3.h”里面定

义的,所以不属于STM32 固件库的范畴。参考《STM32F10xxx 参考手册》第80

页的STM32 系统时钟框图,我们可以知道,系统时钟(AHB,此时为72MHz)经8

分频或者不分频之后产生的时钟给Systick 作为时钟震荡源,因此此时的

Systick 默认为频率为72MHz,如果需要使用8 分频之后的频率,可以使用函数

“SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);”,因此我们只

需要把Systick 设置成72000 时(计算方式:(1/72000000Hz)*72000 次=1ms),

就能产生1ms 时间基准,说白了就是一个中断信号。


见函数void Systick_Init(void)配置


第三步:


编写Systick 的中断处理函数。对于STM32 所有的中断处理函数,

我们都可以在对应的“startup_stm32f10x_xx.s”里面找到其入口。比如,在做

Systick 中断处理的时候,我们选择的入口地址就是“SysTick_Handler”。因

此,我们可以写如下的代码,如程序片段6 所示。同时,需要把“stm32f10x_it.c”

里面的“SysTick_Handler”入口屏蔽,不然会报错。


 1 __IO uint32_t TimingDelay;

 2 void TimingDelay_Decrement(void)

 3 {

 4 if (TimingDelay != 0x00)

 5 {

 6 TimingDelay--;

 7 }

 8 }

 9 void SysTick_Handler(void)

10 {

11 TimingDelay_Decrement();

12 }

 

第四步,写delay_ms函数


1 void delay_ms(__IO uint32_t nTime)//延迟函数,设置为US

2 {

3 TimingDelay = nTime;//时钟滴答数

4 while(TimingDelay != 0);

5 }

 


 


以上只是Systick的配置,下面是一个完整实现LED灯闪烁的代码


下面包含四个文件:分别是mian.c文件、timer.c文件、timer.h文件、led.c文件、led.h文件


 


mian.c文件、


 1 #include 'stm32f10x.h'   // 相当于51单片机中的  #include

 2 #include 'timer.h'

 3 #include 'led.h'

 4 int main(void)

 5 {

 6     SystemInit();//初始化系统,使得系统频率为72MHZ

 7     systick_init();//配置Systick,使得1ms产生

 8     led_gpio_init();//LED灯的配置,要用到LED灯就要配置

 9     while(1)

10     {

11         GPIO_SetBits(GPIOB,GPIO_Pin_5);

12         delay_ms(1000);//延时1s

13         GPIO_ResetBits(GPIOB,GPIO_Pin_5);

14         delay_ms(1000);

15     }

16 }


timer.c文件、


 1 #include 'timer.h'

 2 #include 'stm32f10x.h'

 3 __IO uint32_t TimingDelay;//相当于宏定义一个TimingDelay

 4 void systick_init()

 5 {

 6     //配置Systick重载值,系统时钟为72MHZ

 7     //设置72000,中断时间:72000*(1/72000000)=1ms

 8     //有返回值,返回0则装在成功

 9     if(SysTick_Config(72000)==1)

10     {

11         while(1);

12             

13     }

14 }

15 

16 

17 

18 void TimingDelay_Decrement(void)

19 {

20     if(TimingDelay !=0x00)

21     {

22         TimingDelay--;

23     }

24 }

25 /*中断处理函数,中断一次减1ms*/

26 void SysTick_Handler(void)

27 {

28     TimingDelay_Decrement();//调用上面的函数

29 }

30 

31 

32 

33 void delay_ms(__IO uint32_t nTime)

34 {

35     TimingDelay = nTime;//时钟滴答数

36     while(TimingDelay !=0);

37 }

38     


注意:这里需要做一个细节!!


在stm32f10x_it.c文件里面的void SysTick_Handler(void)这个函数注释掉。


看截图:

timer.h文件、


 1 #ifndef _TIMER_H_

 2 #define _TIMER_H_

 3 

 4 #include 'stm32f10x_tim.h'

 5 #include 'stm32f10x_rcc.h'

 6 #include 'stm32f10x_it.h'

 7 #include 'misc.h'

 8 

 9 extern __IO uint32_t TimingDelay;

10 

11 void systick_init();

12 void delay_ms(__IO uint32_t nTime);

13 #endif


led.c文件、


 1 #include 'led.h'

 2 #include 'stm32f10x_gpio.h'

 3 //GPIO初始化

 4 void led_gpio_init()

 5 {

 6     GPIO_InitTypeDef gpio;

 7     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

 8     gpio.GPIO_Mode=GPIO_Mode_Out_PP;

 9     gpio.GPIO_Pin=GPIO_Pin_5;

10     gpio.GPIO_Speed=GPIO_Speed_50MHz;

11     GPIO_Init(GPIOB,&gpio);

12 }


led.h文件


1 #ifndef _LED_H_

2 #define _LED_H_

5 void led_gpio_init();

7 #endif


关键字:Systick  LED闪烁灯 引用地址:基于Systick系统时钟延时的LED闪烁灯

上一篇:直接存储器存取(Direct Memory Access,DMA)详细讲解
下一篇:STM32串口usart发送数据

推荐阅读最新更新时间:2026-03-24 11:15

单片机系统时钟延时
#include REGtenxTM52FN8276.h #include intrins.h #include tm52fn8276_bsp.h /* 快时钟系统主频为 14.7456M/2 = 7.3728M */ void bsp_clock_init() { SELFCK = 0; // 切换到慢时钟 CLKCON = 0x02; // div 2 时钟分频 delay_10nop(); SELFCK = 1; // 切换到快时钟 } void bsp_delay_ms(unsigned int ms) { unsigned int i; unsigned char delay_
[单片机]
单片机LED流水灯闪烁灯程序大集合
/* 点亮LED灯:方1 位操作方式 sbit D1=P1^0; 方2 总线方工 P1=0x??; 让LED灯闪烁 */ /* //方1:位操作方式点亮LED #include reg52.h sbit D1=P1^0; //P1^0的P必须是大写 void main() { D1=0; //使用P1^0必须先经过sbit定义,而不能直接用P1^0=0;否则编译过不了 } */ //------------------------------------------------- :总线方式点亮LED #include reg52.h void main() { P1=0xfd; //1111
[单片机]
STM32单片机Systick函数的使用方法
在“嵌入式学习006_Systick使用(一)”中,详细介绍了Systick中寄存器的使用方法,用到了很多函数,实际上到了3.5版本的标准固件库中,移除了相关驱动函数,用户必须调用CMSIS.h中定义的函数,其中CMSIS只提供了一个Systick设置的函数,替代了STM32原来有的所有的驱动函数,这样做的目的,可能是简化Systick 的设置,可是降低了用户对SysTick的可控性。 在CMSIS中提供的函数是SysTick_Config(uint32_t ticks); 该函数设置了自动重载入计数器(LOAD)的值,SysTick IRQ的优先级,复位了计数器(VAL)的值,开始计数并打开SysTick IRQ中断。Sys
[单片机]
个人对STM32 SysTick的总结(寄存器操作)
一、概述: SysTick是一个简单的递减24位计数器。如果你不需要再应用程序中嵌入操作系统,SysTick可以作为简单的延时和产生周期性的中断。 状态控制寄存器的第0位可以使能计数器,当前值寄存器随着时钟一直递减,当他减到0的时候,重装载寄存器就会重新装载这只的值,计数器继续从这个值递减。 二、相关寄存器: 2.1SysTick- CTRL 状态和控制寄存器 位16:当前值寄存器递减到0,位16置1 位2:时钟源选择位,0:使用外部参考时钟;1:使用内核时钟 位1:使能SysTick中断,当前值寄存器递减到0时产生中断 位0:SysTick时钟使能 2.2SysTick- LOAD 重装载值寄存器 当前值寄存器为
[单片机]
个人对STM32 <font color='red'>SysTick</font>的总结(寄存器操作)
STM32 SysTick定时器讲解
STM32 SysTick定时器讲解 本文将介绍SysTick定时器、其工作原理与寄存器、及对应的应用实例 SysTick定时器简介 首先、我们先解释下定时器,“定时器”:能够定时、计数的器件 SysTick称为系统滴答定时器,它位于Cortex 内核中是一个定时器,可以对输入的时钟进行计数、若输入的时钟具有周期性的变化,则计数也相当于计时。 系统滴答定时器一般用于操作系统,为操作系统提供时基、维持操作系统的心跳; 系统滴答定时器每过一段时间会产生一个中断,根据这个特性、操作系统就可以实现时间片的任务调度。 工作原理分析 从上述两张图我们可以看出: 系统滴答定时器的时钟源是从SYSCLK处经过分频得到的,另外它处于内核中
[单片机]
STM32 <font color='red'>SysTick</font>定时器讲解
STM32时钟系统中的SysTick、FCLK、SYSCLK、PCLK和HCLK
时钟信号好比是单片机的脉搏,了解STM32时钟系统是必要的,下图是STM32F1xx用户手册中的时钟系统结构图。 在STM32F1xx中,有五个时钟源,分别为HSI、HSE、LSI、LSE、PLL。 HSI是高速内部时钟,RC振荡器,频率为8MHz HSE是高速外部时钟,可接石英/陶瓷谐振器或者接外部时钟源,频率范围为4MHz~16MHz LSI是低速内部时钟,RC振荡器,频率为40kHz LSE是低速外部时钟,接频率为32.768kHz的石英晶振 PLL为锁相环倍频输出,其输出频率最大不得超过72MHz SYSCLK 系统时钟SYSCLK最大频率为72MHz,它是供STM32中绝大部分部件工作的时钟源。系统时钟可由PLL
[单片机]
STM32 SysTick秒用
这里针对的是无操作系统的情况下的使用。之前一直想利用systick既实现记录系统运行时间又能够精确实现微秒延时的功能,如果将SysTick的定时器的定时中断时间设置为1us,这在有些情况下会导致死机的问题。这样的话就无法利用systick来实现us延时函数了。 利用SysTick实现1ms定时中断,us延时函数可以利用SysTick的寄存器来运算得到精确的延时函数,具体实现如下: 头文件: #ifndef __SYSTICK_H #define __SYSTICK_H #ifdef __cplusplus extern C { #endif /* Includes -----------------------
[单片机]
Systick滴答定时器讲解
Systick定时器基础知识讲解: Systick定时器,是一个简单的定时器,对于CM3,CM4内核芯片,都有- Systick定时器。 Systick定时器常用来做延时,或者实时系统的心跳时钟。这样可以节省MCU资源,不用浪费一个定时器。比如UCOS中,分时复用,需要一个最小的时间戳,一般在STM32+UCOS系统中,都采用Systick做UCOS心跳时钟。 Systick定时器就是系统滴答定时器,一个24位的倒计数(从大到小)定时器,计到0时,将从RELOAD寄存器中自动重装载定时初值。只要不把它在SysTick控制及状态寄存器中的使能位清除,就永不停息,即使在睡眠模式下也能工作。 SysTick定时器被捆绑在
[单片机]
<font color='red'>Systick</font>滴答定时器讲解
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved