4、系统滴答时钟SysTick

2024-03-28 02:08
文章标签 时钟 系统 systick 滴答

本文主要是介绍4、系统滴答时钟SysTick,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

写在开篇前:

       首先要明确的第一点:学习知识我们都会到网上查询各种资料,但是由于网上资料大多不全

面,我们对于这些资料需要加以自身的理解并对其有所取舍,所以建议网上查来的资料只做引导、

参考作用,最终确定对技术的应用还要以官方文档为准。而这个辨别资料可行性的过程是十分耗费

时间的,对于此点笔者也实在无奈,如果哪些同学有更好的方法,请不吝赐教,以图共同进步。

由于本文将详细的分析SysTick整个实现过程,为了方便大家快速掌握该流程,先将结论总结如

下:

1、systick是一个24位的定时器,故重装值最大值为2的24次方 = 16 777 215,要注意不要超出这

     个值。

2、systick是cortex_m3的标配,不是外设,不需要在RCC寄存器组打开它的时钟。

3、每次systick溢出后会置位计数标志位和中断标志位,计数标志位在计数器重装载后被清除,而

     中断标志位也会随着中断服务程序的响应被清除,所以这两个标志位都不需要手动清除。

4、采用使用库函数的方法,只能采用中断的方法响应定时器计时时间到,如要采用查询的方法,

     那只能采用设置systick的寄存器的方法。

目录

0x01、什么是时钟

0x02、STM32的时钟

0x0001)、STM32的时钟源

0x0002)、STM32的倍频、分频系统

0x03、SysTick

第一步:设置STM32系统时钟源

第二步:设置SysTick定时器

0x0001、SysTick寄存器配置

0x0002、SysTick库函数配置

0x04、源程序下载地址


       SysTick是一个系统时钟定时器,属于ARM Cortex-Mx内核的一个“内设”,所有基于此内核的

微控制器都带SysTick。(ST的芯片中F1系列属于Cortex-M3内核,F3与F4系列属于Cortex-M4内

核)。

0x01、什么是时钟

关于这个问题 ,我们需要从 CPU 的时钟说起。

       计算机是一个十分复杂的电子设备。它由各种集成电路和电子器件组成,每一块集成电路中都

集成了数以万计的晶体管和其他电子元件。这样一个十分庞大的系统,要使它能够正常地工作,就

必须有一个指挥,对各部分的工作进行协调。各个元件的动作就是在这个指挥下按不同的先后顺序

完成自己的操作的,这个先后顺序我们称为时序。

       时序是计算机中一个非常重要的概念,如果时序出现错误,就会使系统发生故障,甚至造成死

机。那么是谁来产生和控制这个操作时序呢?这就是“时钟”。

       “时钟”可以认为是计算机的“心脏”,如同人一样,只有心脏在跳动,生命才能够继续。不要把

计算机的“时钟”等同于普通的时钟,它实际上是由晶体振荡器产生的连续脉冲波,这些脉冲波的幅

度和频率是不变的,这种时钟信号我们称为外部时钟。它们被送入 CPU 中,再形成 CPU 时钟。

不同的 CPU,其外部时钟和 CPU 时钟的关系是不同的。

       CPU 的时钟周期通常为节拍脉冲或T周期,它是处理操作的最基本的单位。

       在微程序控制器中,时序信号比较简单,一般采用节拍电位——节拍脉冲二级体制。就是说它

只要一个节拍电位,在节拍电位又包含若干个节拍脉冲(时钟周期)。节拍电位表示一个CPU周期

的时间,而节拍脉冲把一个CPU周期划分为几个较小的时间间隔。根据需要,这些时间间隔可以相

等, 也可以不等。

       指令周期是取出并执行一条指令的时间。指令周期常常有若干个CPU周期,CPU周期也称为

机器周期,由于CPU访问一次内存所花费的时间较长,因此通常用内存中读取一个指令字的最短时

间来规定CPU周期。这就是说,一条指令取出阶段(通常为取指)需要一个CPU周期时间。而一

个CPU周期时间又包含若干个时钟周期(通常为节拍脉冲或T周期,它是处理操作的最基本的单

位)。这些时钟周期的总和则规定了 一个CPU周期的时间宽度。

总结:

1、时钟是为CPU产生时序信号而采用晶体振荡器产生的相同幅度和频率的脉冲。

2、1个指令周期包含若干个机器周期,1个机器周期又包含了若干个时钟周期,指令周期 > 机器周

     期 > 时钟周期

0x02、STM32的时钟

明白了什么是时钟之后,我们来分析一下STM32芯片的时钟。

STM32的时钟系统设计十分复杂,总结起来有以下两个特点

1、提供多种时钟源选择

2、可以进行倍频、分频操作。

那么为什么要设计这么复杂的时钟系统呢?主要有以下两点原因

1、倍频:考虑到电磁兼容性,如stm32f103系列芯片,最高主频可达72MHZ,如果外部直接提供

     一个72MHz的晶振,太高的振荡频率可能会给制作电路板带来一定的难度。

2、分频:因为STM32既有高速外设又有低速外设,各种外设的工作频率不尽相同,如同PC机上

     的南北桥,把高速的和低速的设备分开来管理。最后,每个外设都配备了外设时钟的开关,当

     我们不使用某个外设时,可以把这个外设时钟关闭,从而降低STM32的整体功耗

       众所周知,微控制器(处理器)的运行必须要依赖周期性的时钟脉冲来驱动——往往由一个外

部晶体振荡器提供时钟输入为始,最终转换为多个外部设备的周期性运作为末,这种时钟“能量”扩

散流动的路径,犹如大树的养分通过主干流向各个分支,因此常称之为“时钟树”。在一些传统的低

端 8 位单片机诸如 51,AVRPIC 等单片机,其也具备自身的一个时钟树系统,但其中的绝大部

分是不受用户控制的,即在单片机上电后,时钟树就固定在某种不可更改的状态(假设单片机处于

正常工作的状态)。比如 51 单片机使用典型的 12MHz 晶振作为时钟源,则外设如 IO 口、定时

器、串口等设备的驱动时钟速率便已经是固定的,用户无法将此时钟速率更改,除非更换晶振。这

样对比起来,STM32的时钟系统设计具有明显的优势。

0x0001)、STM32的时钟源

       STM32对于系统时钟提供多种选择。在STM32中,有五个时钟源,为 HSI、HSE、LSI、

LSE、PLL,它们都可以作为系统时钟的来源。

       系统时钟的选择是在启动时进行,复位时内部 8MHZ 的 RC 振荡器被选为默认的 CPU 时钟,

随后可以选择外部的、具失效监控的 4-16MHZ 时钟;当检测到外部时钟失效时,它将被隔离,系

统将自动地切换到内部的 RC 振荡器。

1、HSI 是高速内部时钟,RC 振荡器,频率默认为 8MHz

2.、HSE 是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为 4MHz~16MHz

3、LSI 是低速内部时钟,RC 振荡器,频率为 40kHz,可以用于驱动独立看门狗和通过程序选择

     驱动 RTC(RTC 用于从停机/待机模式下自动唤醒系统)

4、LSE 是低速外部时钟,接频率为 32.768kHz 的石英晶体,也可以被用来驱动 RTC

5、PLL 为锁相环倍频输出,其时钟输入源可选择为 HSI/2HSE 或者 HSE/2。倍频可选择为

     2~16 倍, 但是其输出频率最大不得超过 72MHz

0x0002)、STM32的倍频、分频系统

我们先贴上STM32的时钟树图

从时钟树的分析,看到经过一系列的倍频、分频后得到了几个与我们开发密切相关的时钟。

SYSCLK:系统时钟,STM32大部分器件的时钟来源。主要由AHB预分频器分配到各个部件。

HCLK:AHB预分频器直接输出得到,它是高速总线AHB的时钟信号,提供给存储器,DMA

             Cortex内核,是Cortex内核运行的时钟,CPU主频就是这个信号,它的大小与STM32运算

             速度,数据存取速度密切相关。

FCLK:同样由AHB预分频器输出得到,是内核的“自由运行时钟”。“自由”表现在它不来自时钟

             HCLK,因此在HCLK时钟停止时FCLK也继续运行。它的存在,可以保证在处理器休眠

             时, 也能够采样和到中断和跟踪休眠事件,它与HCLK互相同步。

PCLK1:外设时钟,由APB1预分频器输出得到,最大频率为36MHZ,提供给挂载在APB1总线上

              的外设。

PCLK2:外设时钟,由APB2预分频器输出得到,最大频率可为72MHZ,提供给挂载在APB2总线

              上的外设。

我们举一个实例,分析一下我们是如何得到外设 GPIOF 的时钟(各型号芯片略有不同),根据我

上图(时钟树图片)中的红色箭头走向

       首先,这里我们为了得到STM32F103系列的最高主频72MHz,我们的外部时钟是 8MHz,

过9倍的倍频即可得到72MHz。首先,8M的HSE经过 PLLXTPRE,直接选择 HSE 为输入,得 8

(MHz)。经过 PLLSRC 选择,还是 8(MHz)。8MHz 经过 PLLMULL 的 9 倍频,8*9=72

(MHz)。经过 SW 选择 PLLCLK 做为 SYSCLK(系统时钟)的输入时钟,那么 SYSCLK 等于

输送过来的 72MHz。外设 GPIO 的时钟来源于APB2 总线,那么经过 AHB 预分频器不分频。

在经过 APB2 预分频器不分频。最后 APB2 外设 GPIO 就可以得到 72MHz 的时钟源了。

0x03、SysTick

前面我们分析了STM32的整个时钟系统,那么SysTick是什么呢,具体怎么使用呢?

       SysTick是一个24位向下递减的系统节拍定时器(system tick timer)也叫作系统滴答时钟,具

有自动重载和溢出中断功能。每计数一次所需时间为1/SYSTICK,SYSTICK是系统定时器时钟,

它可以直接取系统时钟,还可以通过系统时钟8分频后获取。当定时器计数到0时,将从LOAD寄存

器中自动重装定时器初值,重新向下递减计数,如此循环往复。如果开启SysTick中断的话,当定

时器计数到0,将产生一个中断信号。

SysTick定时器的操作可以分为2步:

第一步:设置STM32系统时钟源

因为系统时钟频率决定HCLK频率,HCLK频率决定SysTick定时器频率

       这一步由于基本上有系统启动时自行设定的,无需人工参与,所以很多介绍SysTick的文章中

并没有介绍,但为了更好的理解SysTick的具体工作原理,我觉得有必要详细的介绍一下。

系统启动,设置系统时钟是通过如下函数调用过程完成的

IMPORT  SystemInit  ——>  SetSysClock()  ——> SetSysClockTo72()

IMPORT  SystemInit 在文件startup_stm32f10x_xx.s文件中,该文件为系统启动文件

SystemInit ()在文件system_stm32f10x.c文件

SetSysClock()在文件system_stm32f10x.c文件

SetSysClockTo72()在文件system_stm32f10x.c文件

其中IMPORT  SystemInit表示系统启动时要调用SystemInit()这个函数

Reset_Handler   PROCEXPORT  Reset_Handler             [WEAK]IMPORT  __mainIMPORT  SystemInitLDR     R0, =SystemInitBLX     R0               LDR     R0, =__mainBX      R0ENDP

SystemInit()又调用SetSysClock()

void SystemInit (void)
{/* Reset the RCC clock configuration to the default reset state(for debug purpose) *//* Set HSION bit */RCC->CR |= (uint32_t)0x00000001;/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CLRCC->CFGR &= (uint32_t)0xF8FF0000;
#elseRCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */   /* Reset HSEON, CSSON and PLLON bits */RCC->CR &= (uint32_t)0xFEF6FFFF;/* Reset HSEBYP bit */RCC->CR &= (uint32_t)0xFFFBFFFF;/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */RCC->CFGR &= (uint32_t)0xFF80FFFF;
#ifdef STM32F10X_CL/* Reset PLL2ON and PLL3ON bits */RCC->CR &= (uint32_t)0xEBFFFFFF;/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x00FF0000;/* Reset CFGR2 register */RCC->CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x009F0000;/* Reset CFGR2 register */RCC->CFGR2 = 0x00000000;      
#else/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x009F0000;
#endif /* STM32F10X_CL */#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)#ifdef DATA_IN_ExtSRAMSystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM */
#endif /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers *//* Configure the Flash Latency cycles and enable prefetch buffer */SetSysClock();
#ifdef VECT_TAB_SRAMSCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#elseSCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif 
}

 SetSysClock()通过 #define SYSCLK_FREQ_72MHz  72000000 设定调用 SetSysClockTo72(),最终将系统时钟频率设置为72M

static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSESetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHzSetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHzSetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHzSetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHzSetSysClockTo56();  
#elif defined SYSCLK_FREQ_72MHzSetSysClockTo72();
#endif/* If none of the define above is enabled, the HSI is used as System clocksource (default after reset) */ 
}
#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */#define SYSCLK_FREQ_24MHz  24000000
#else
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
/* #define SYSCLK_FREQ_24MHz  24000000 */ 
/* #define SYSCLK_FREQ_36MHz  36000000 */
/* #define SYSCLK_FREQ_48MHz  48000000 */
/* #define SYSCLK_FREQ_56MHz  56000000 */
#define SYSCLK_FREQ_72MHz  72000000
#endif

上面我们对于外部8MHZ晶振输入如何倍频到72MHZ做过解释,这里我们看一下软件上是怎么实现

的(这个实现过程无需人为参与)

在SetSysClockTo72中,有如下一段操作,

/*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |RCC_CFGR_PLLMULL));RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);

通过上述操作,我们将STM32的系统时钟频率设置为72MHZ。

总结:系统会自动调用上述函数进行设置,不需要我们人为的参与,但是我们需要通过宏定义来确

定系统的主频。

第二步:设置SysTick定时器

       设置SysTick定时器有两种方法,一种是通过寄存器,一种是通过库函数,而库函数直接启动

了SysTick定时器的中断,如果你不需要使用中断功能,为了避免对官方库文件的修改,我建议使

用寄存器直接配置SysTick

0x0001、SysTick寄存器配置

       我们先看一下SysTick的寄存器列表,这张表位于文件Cortex®-M3 programming manual,该

文件的官方下载地址如下:

https://www.st.com/resource/en/programming_manual/cd00228163-stm32f10xxx20xxx21xxxl1xxxx-cortexm3-programming-manual-stmicroelectronics.pdf

1)、STK_CTRL —— SysTick控制寄存器 

Bit 16:COUNTFLAG:Returns 1 if timer counted to 0 since last time this was read. 如果在上次

                                        读取本寄存器后,SysTick已经数到了0,则该位为1,。如果读取该位,该

                                        位将自动清零

Bit 2:CLKSOURCEClock source selection 时钟源选择位

                                      0: AHB/8

                                      1: AHB

 Bit 1:TICKINT: SysTick exception request enable 中断响应位 

                               0: Counting down to zero does not assert the SysTick exception request     

                                    计数器减到0不产生中断

                               1: Counting down to zero to asserts the SysTick exception request.           

                                   计数器减到0产生中断

 Bit 0:ENABLE: Counter enable 计数器使能位     启用计数器,当ENABLE设置为1时,计数

                                器重加载寄存器,然后倒计时。当达到0时,它将COUNTFLAG设置为1,

                                然后根据TICKINT的值选择是否产生中断。然后,它将重新加载再次计算,

                                然后开始计数。 

                                0: Counter disabled  关闭计数器

                                1: Counter enabled  开启计数器

2)、STK_LOAD —— SysTick重载寄存器

Bit 23 ~ Bit 0:共24位,加载计数值,取值范围为0x00000001-0x00FFFFFF

3)、STK_VAL    —— SysTick当前值寄存器

Bit 23 ~ Bit 0:共24位,当前计数值,取值范围为0x00000001-0x00FFFFFF,写入任何值都会将

                         字段清除为0,并且还会清除STK_CTRL寄存器为0。

4)、STK_CALIB —— SysTick校准寄存器

Bit 31   :NOREF:NOREF 标志

                                0: 外部参考时钟可用

                                1: 外部参考时钟不可用

Bit 30   :SKEW:SKEW标志

                                0: 校准值是准确的10ms

                                1: 校准值不是准确的10ms

Bit 23 ~ Bit 0:TENMS:10ms的时间内倒计数的格数。芯片设计者应该通过Cortex-M3的输入信

                                          号提供该数值。若读取该值为0,则表示无法使用校准功能。

延时程序实例:根据上述对寄存器的描述,我们利用SysTick做一个ms延时和us延时程序

static u8  fac_us = 0;		    // 1us时间内SysTick计数器的计数值
static u16 fac_ms = 0;			// 1ms时间内SysTick计数器的计数值/***@brief     初始化SysTick定时器*@param     无*@return    无*/
void Delay_Init(void)
{SysTick->CTRL &= 0xfffffff9;                             // bit2清0,选择时钟为HCLK/8即9MHZ,即1s计数9M,bit1清0,禁止SysTick中断fac_us = (72000000/8)/1000000;                           // 1us计数值为72 000 000/8/1000 000,1us计数9次fac_ms = (72000000/8)/1000;                              // 1ms计数值为72 000 000/8/1000,1ms计数9000次
}/***@brief   微秒延时函数*@param   time_us:要延时微秒时间数*@return  无*/
void Delay_us(uint32_t time_us)
{uint32_t temp;SysTick->LOAD  = time_us * fac_us;                         // 时间加载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;                                     // 清空计数器 
}/***@brief   毫秒延时函数*@param   time_ms:要延时毫秒时间数*@return  无*/
void Delay_ms(uint32_t time_ms)
{                 uint32_t temp;          SysTick->LOAD  = (uint32_t)time_ms * fac_ms;               // 时间加载(SysTick->LOAD为24bit)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;                                     // 清空计数器
}

0x0002、SysTick库函数配置

使用库函数设置SysTick定时器,只需调用SysTick_Config(uint32_t ticks)函数即可,函数自动完

成:重装载值的装载,时钟源选择,计数寄存器复位,中断优先级的设置(最低),开中断,开始计

数的工作。

如果不调整SysTick时钟,那么默认SysTick_CLKSource_HCLK(HCLK)

如果需要调整SysTick时钟,则调用void SysTick_CLKSourceConfig(uint32_t

SysTick_CLKSource)函数来配置,该函数位于文件misc.c中。

注意:函数调用顺序,应先调用SysTick_Config(uint32_t ticks),再调用

SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)。

其中SysTick_CLKSource参数有两个选择,SysTick_CLKSource_HCLK_Div8(HCLK的8分

频),SysTick_CLKSource_HCLK(HCLK时钟)

SysTick_CLKSourceConfig原函数如下:

/*** @brief  Configures the SysTick clock source.* @param  SysTick_CLKSource: specifies the SysTick clock source.*   This parameter can be one of the following values:*     @arg SysTick_CLKSource_HCLK_Div8: AHB clock divided by 8 selected as SysTick clock source.*     @arg SysTick_CLKSource_HCLK: AHB clock selected as SysTick clock source.* @retval None*/
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
{/* Check the parameters */assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));if (SysTick_CLKSource == SysTick_CLKSource_HCLK){SysTick->CTRL |= SysTick_CLKSource_HCLK;}else{SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;}
}

其中assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));是对传入的参数是否有宏

定义进行校验,宏定义代码如下:

#define SysTick_CLKSource_HCLK_Div8    ((uint32_t)0xFFFFFFFB)
#define SysTick_CLKSource_HCLK         ((uint32_t)0x00000004)
#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \((SOURCE) == SysTick_CLKSource_HCLK_Div8))

如果需要调整SysTick的中断优先级,则调用void NVIC_SetPriority(IRQn_Type IRQn, uint32_t

priority)函数来配置,该函数位于文件core_cm3.h中。

注意:函数调用顺序,应先调用SysTick_Config(uint32_t ticks),再调用

NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)。

延时程序实例:我们利用库函数做一个ms级延时程序

main函数中调用SysTick_Config()配置并启动SysTick定时器

int main(void)
{led_init();/* 使用while (1)等待SysTick配置启动成功 *//* 如果不更改SysTick时钟源,那么SysTick时钟为72MHz,即计数72 000次为1ms,并产生1次中断 */if(SysTick_Config(72000))  { /* Capture error */ while (1);}        while(1){GPIO_ResetBits(GPIOC,GPIO_Pin_10);Delay(1000);GPIO_SetBits(GPIOC,GPIO_Pin_10);   Delay(1000);}
}/*** @brief  Inserts a delay time.* @param  nTime: 延时nTime毫秒* @retval None*/
void Delay(__IO uint32_t nTime)
{ TimingDelay = nTime;while(TimingDelay != 0);
}/*** @brief  在中断中调用该函数,每1ms中断1次,每次中断TimingDelay变量减1* @param  None* @retval None*/
void TimingDelay_Decrement(void)
{if(TimingDelay != 0x00){ TimingDelay--;}
}/*** @brief  This function handles SysTick Handler.SysTick中断函数* @param  None* @retval None*/
void SysTick_Handler(void)
{TimingDelay_Decrement();
}

至此,SysTick定时器的完整的使用方式就介绍完了。

总结:SysTick定时器的使用流程如下:

设置系统时钟 ——> 设置SysTick定时器时钟 ——> 使用SysTick寄存器设置或者调用库函数设置

SysTick定时器

需要注意的点:

1、如果使用查询法产生延时,只能用寄存器设置SysTick定时器,用库函数设置SysTick定时器会

产生SysTick中断。

2、使用库函数更改SysTick时钟源或者中断优先级时需要注意函数调用顺序

SysTick_Config ——> SysTick_CLKSourceConfig

SysTick_Config ——> NVIC_SetPriority

0x04、源程序下载地址

下面上传一个源程序供大家参考:

SysTickandled_滴答时钟-硬件开发文档类资源-CSDN下载

这篇关于4、系统滴答时钟SysTick的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/854136

相关文章

什么是cron? Linux系统下Cron定时任务使用指南

《什么是cron?Linux系统下Cron定时任务使用指南》在日常的Linux系统管理和维护中,定时执行任务是非常常见的需求,你可能需要每天执行备份任务、清理系统日志或运行特定的脚本,而不想每天... 在管理 linux 服务器的过程中,总有一些任务需要我们定期或重复执行。就比如备份任务,通常会选在服务器资

TP-LINK/水星和hasivo交换机怎么选? 三款网管交换机系统功能对比

《TP-LINK/水星和hasivo交换机怎么选?三款网管交换机系统功能对比》今天选了三款都是”8+1″的2.5G网管交换机,分别是TP-LINK水星和hasivo交换机,该怎么选呢?这些交换机功... TP-LINK、水星和hasivo这三台交换机都是”8+1″的2.5G网管交换机,我手里的China编程has

基于Qt实现系统主题感知功能

《基于Qt实现系统主题感知功能》在现代桌面应用程序开发中,系统主题感知是一项重要的功能,它使得应用程序能够根据用户的系统主题设置(如深色模式或浅色模式)自动调整其外观,Qt作为一个跨平台的C++图形用... 目录【正文开始】一、使用效果二、系统主题感知助手类(SystemThemeHelper)三、实现细节

CentOS系统使用yum命令报错问题及解决

《CentOS系统使用yum命令报错问题及解决》文章主要讲述了在CentOS系统中使用yum命令时遇到的错误,并提供了个人解决方法,希望对大家有所帮助,并鼓励大家支持脚本之家... 目录Centos系统使用yum命令报错找到文件替换源文件为总结CentOS系统使用yum命令报错http://www.cppc

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听