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

相关文章

通信系统网络架构_2.广域网网络架构

1.概述          通俗来讲,广域网是将分布于相比局域网络更广区域的计算机设备联接起来的网络。广域网由通信子网于资源子网组成。通信子网可以利用公用分组交换网、卫星通信网和无线分组交换网构建,将分布在不同地区的局域网或计算机系统互连起来,实现资源子网的共享。 2.网络组成          广域网属于多级网络,通常由骨干网、分布网、接入网组成。在网络规模较小时,可仅由骨干网和接入网组成

Linux系统稳定性的奥秘:探究其背后的机制与哲学

在计算机操作系统的世界里,Linux以其卓越的稳定性和可靠性著称,成为服务器、嵌入式系统乃至个人电脑用户的首选。那么,是什么造就了Linux如此之高的稳定性呢?本文将深入解析Linux系统稳定性的几个关键因素,揭示其背后的技术哲学与实践。 1. 开源协作的力量Linux是一个开源项目,意味着任何人都可以查看、修改和贡献其源代码。这种开放性吸引了全球成千上万的开发者参与到内核的维护与优化中,形成了

[FPGA][基础模块]跨时钟域传播脉冲信号

clk_a 周期为10ns clk_b 周期为34ns 代码: module pulse(input clk_a,input clk_b,input signal_a,output reg signal_b);reg [4:0] signal_a_widen_maker = 0;reg signal_a_widen;always @(posedge clk_a)if(signal_a)

PS系统教程25

介绍软件 BR(bridge) PS 配套软件,方便素材整理、管理素材 作用:起到桥梁作用 注意:PS和BR尽量保持版本一致 下载和安装可通过CSDN社区搜索,有免费安装指导。 安装之后,我们打开照片只需双击照片,就自动在Ps软件中打开。 前提:电脑上有PS软件 三种预览格式 全屏预览 评星级 直接按数字键就可以 方向键可以更换图片 esc退出 幻灯片放

风水研究会官网源码系统-可展示自己的领域内容-商品售卖等

一款用于展示风水行业,周易测算行业,玄学行业的系统,并支持售卖自己的商品。 整洁大气,非常漂亮,前端内容均可通过后台修改。 大致功能: 支持前端内容通过后端自定义支持开启关闭会员功能,会员等级设置支持对接官方支付支持添加商品类支持添加虚拟下载类支持自定义其他类型字段支持生成虚拟激活卡支持采集其他站点文章支持对接收益广告支持文章评论支持积分功能支持推广功能更多功能,搭建完成自行体验吧! 原文

Django 路由系统详解

Django 路由系统详解 引言 Django 是一个高级 Python Web 框架,它鼓励快速开发和干净、实用的设计。在 Django 中,路由系统是其核心组件之一,负责将用户的请求映射到相应的视图函数或类。本文将深入探讨 Django 的路由系统,包括其工作原理、配置方式以及高级功能。 目录 路由基础URL 映射路由参数命名空间URL 反向解析路由分发include 路由路由修饰符自

【图像识别系统】昆虫识别Python+卷积神经网络算法+人工智能+深度学习+机器学习+TensorFlow+ResNet50

一、介绍 昆虫识别系统,使用Python作为主要开发语言。通过TensorFlow搭建ResNet50卷积神经网络算法(CNN)模型。通过对10种常见的昆虫图片数据集(‘蜜蜂’, ‘甲虫’, ‘蝴蝶’, ‘蝉’, ‘蜻蜓’, ‘蚱蜢’, ‘蛾’, ‘蝎子’, ‘蜗牛’, ‘蜘蛛’)进行训练,得到一个识别精度较高的H5格式模型文件,然后使用Django搭建Web网页端可视化操作界面,实现用户上传一

OSG数学基础:坐标系统

坐标系是一个精确定位对象位置的框架,所有的图形变换都是基于一定的坐标系进行的。三维坐标系总体上可以分为两大类:左手坐标系和右手坐标系。常用的坐标系:世界坐标系、物体坐标系和摄像机坐标系。 世界坐标系 世界坐标系是一个特殊的坐标系,它建立了描述其他坐标系所需要的参考框架。从另一方面说,能够用世界坐标系来描述其他坐标系的位置,而不能用更大的、外部的坐标系来描述世界坐标系。世界坐标系也被广泛地

LoRaWAN在嵌入式网络通信中的应用:打造高效远程监控系统(附代码示例)

引言 随着物联网(IoT)技术的发展,远程监控系统在各个领域的应用越来越广泛。LoRaWAN(Long Range Wide Area Network)作为一种低功耗广域网通信协议,因其长距离传输、低功耗和高可靠性等特点,成为实现远程监控的理想选择。本文将详细介绍LoRaWAN的基本原理、应用场景,并通过一个具体的项目展示如何使用LoRaWAN实现远程监控系统。希望通过图文并茂的讲解,帮助读

获取Windows系统版本号(转)

https://blog.csdn.net/sunflover454/article/details/51525179