1 SysTick定时器简介

什么是SysTick?
                SysTick定时器也叫SysTick滴答定时器,它是Cortex-M3内核的一个外设,被嵌入在NVIC 中,用于产生SYSTICK异常(异常号:15)。SysTick是一个24位的倒计数系统节拍计时器System Tick timer,每计数一次所需时间为1/SYSTICK,SYSTICK是系统定时器时钟,它可以直接取系统时钟,还可以通过系统时钟8分频后获取。当计数到0时,它就会从Load寄存器中自动重装定时初值,重新向下递减计数,如此循环往复。如果开启SysTick中断的话,当定时器计数到0,将产生一个中断信号。因此只要知道计数的次数就可以准确得到它的延时时间。只要不把CTRL寄存器中的ENABLE清0,它就永不停止。

        SysTick作用?
               
 在单任务引用程序中,因为其架构就决定了它执行任务的串行性,这就引出一个问题:当某个任务出现问题时,就会牵连到后续的任务,进而导致整个系统崩溃。要解决这个问题,可以使用实时操作系统(RTOS)。因为RTOS以并行的架构处理任务,单一任务的崩溃并不会牵连到整个系统。这样用户出于可靠性的考虑可能就会基于RTOS来设计自己的应用程序。SYSTICK存在的意义就是提供必要的时钟节拍,为RTOS的任务调度提供一个有节奏的“心跳”。微控制器的定时器资源一般比较丰富,比如STM32存在8个定时器,为啥还要再提供一个SYSTICK?原因就是所有基于ARM Cortex_M3内核的控制器都带有SysTick定时器,这样就方便了程序在不同的器件之间的移植。而使用RTOS的第一项工作往往就是将其移植到开发人员的硬件平台上,由于SYSTICK的存在无疑降低了移植的难度。SysTick定时器除了能服务于操作系统之外,还能用于其它目的:如作为一个闹铃,用于测量时间等。要注意的是,当处理器在调试期间被喊停(halt)时,则SysTick定时器亦将暂停运作。

2 SysTick时钟的选

SysTick寄存器说明在《Cortex-M3权威指南》(SysTick定时器章节)有说明:

SysTick->CTRL:控制和状态寄存器

SysTick->LOAD:重装载寄存器

SysTick->VAL:当前值寄存器

SysTick->CALIB:校准值寄存器

用户可以在位于Cortex_M3处理器系统控制单元中的系统节拍定时器控制和状态寄存器(SysTick control and status register ,SCSR)选择SysTick 时钟源。如将SCSR中的CLKSOURCE位置位,SysTick会在CPU频率下运行;而将CLKSOUCE位清除则SysTick会以CPU主频的1/8频率运行。
        在3.5版本的库函数中与SysTick相关的函数有两个:第一个,SysTick_Config(uint32_t ticks),在core_cm3.h头文件中进行定义的。第二个,void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource),在misc.c文件中定义的。
        在core_cm3.h头文件中进行定义的SysTick_Config(uint32_t ticks)函数主要的作用有一下方面:
                1、初始化systick
                2、打开systick
                3、打开systick的中断并设置优先级
                4、返回一个0代表成功或1代表失败

        Uint32_t ticks  即为重装值,这个函数默认使用的时钟源是AHB,即不分频。要想分频,调用void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource),但是要注意函数调用的次序,先调用SysTick_Config(uint32_t ticks),后调用SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
        在misc.c头文件中进行定义的void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)函数主要的作用有一下方面:
                1、选择systick的时钟源,AHB时钟或AHB的8分频
                2、库函数中默认使用的是AHB时钟(在SysTick_Config()函数中设置),即72MHz

        1)core_cm3.h头文件中uint32_t SysTick_Config(uint32_t ticks)函数说明:

/*** @摘要    初始化并启动SysTick计数器及其中断。** @参数    ticks   两个中断之间的滴答数* @返回值  1 = failed, 0 = successful** 初始化系统滴答计时器及其中断,并在自由运行模式下启动系统滴答计时器/计数器,以产生定时中断。*/
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{ if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* 不可能的重新加载值,重装载值必须小于0XFF FFFF,因为这是一个24位的递减计数器 */SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* 设置重装载值寄存器,SysTick_LOAD_RELOAD_Msk定义见后面*/NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* 设置Cortex-M3系统中断优先级 */SysTick->VAL   = 0;                                          /* 加载SysTick计数器值 */SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |      //配置CTRL寄存器,选择内核时钟FCLK为时钟源(STM32 的FCLK为72M)SysTick_CTRL_TICKINT_Msk   |      //开启SysTick中断SysTick_CTRL_ENABLE_Msk;          //SysTick使能      return (0);                                                  /* 初始化成功 */
}

core_cm3.h头文件SysTick相关的寄存器定义:

typedef struct
{__IO uint32_t CTRL;                         /*  Offset: 0x00  SysTick控制和状态寄存器 */__IO uint32_t LOAD;                         /*  Offset: 0x04  SysTick重新加载值寄存器 */__IO uint32_t VAL;                          /*  Offset: 0x08  SysTick当前值寄存器 */__I  uint32_t CALIB;                        /*  Offset: 0x0C  SysTick校准寄存器 */
} SysTick_Type;

core_cm3.h头文件SysTick寄存器相关的位的宏定义:

/* SysTick控制/状态寄存器定义 */
#define SysTick_CTRL_COUNTFLAG_Pos         16                                             /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk         (1ul << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk         (1ul << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */#define SysTick_CTRL_TICKINT_Pos            1                                             /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk           (1ul << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */#define SysTick_CTRL_ENABLE_Pos             0                                             /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk            (1ul << SysTick_CTRL_ENABLE_Pos)               /*!< SysTick CTRL: ENABLE Mask *//* SysTick重新加载寄存器定义 */
#define SysTick_LOAD_RELOAD_Pos             0                                             /*!< SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)        /*!< SysTick LOAD: RELOAD Mask *//* SysTick当前寄存器定义 */
#define SysTick_VAL_CURRENT_Pos             0                                             /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)        /*!< SysTick VAL: CURRENT Mask *//* SysTick校准寄存器定义 */
#define SysTick_CALIB_NOREF_Pos            31                                             /*!< SysTick CALIB: NOREF Position */
#define SysTick_CALIB_NOREF_Msk            (1ul << SysTick_CALIB_NOREF_Pos)               /*!< SysTick CALIB: NOREF Mask */#define SysTick_CALIB_SKEW_Pos             30                                             /*!< SysTick CALIB: SKEW Position */
#define SysTick_CALIB_SKEW_Msk             (1ul << SysTick_CALIB_SKEW_Pos)                /*!< SysTick CALIB: SKEW Mask */#define SysTick_CALIB_TENMS_Pos             0                                             /*!< SysTick CALIB: TENMS Position */
#define SysTick_CALIB_TENMS_Msk            (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)        /*!< SysTick CALIB: TENMS Mask */

        2)core_cm3.h头文件中void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)函数说明:

/*** @摘要   配置SysTick时钟源* @参数   SysTick_CLKSource: SysTick时钟源。* 该参数可以是以下值之一:*     @arg SysTick_CLKSource_HCLK_Div8: SysTick时钟源为AHB时钟除以8。*     @arg SysTick_CLKSource_HCLK: 选择AHB时钟作为SysTick时钟源。* @返回值 无*/
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
{/* 检查参数 */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;}
}

SysTick时钟源的定义:

#define SysTick_CLKSource_HCLK_Div8    ((uint32_t)0xFFFFFFFB)   //将控制状态寄存器的第二位置0,即用外部时钟源
#define SysTick_CLKSource_HCLK         ((uint32_t)0x00000004)   //将控制状态寄存器的第二位置1,即用内核时钟
#define IS_SYSTICK_CLK_SOURCE(SOURCE)  (((SOURCE) == SysTick_CLKSource_HCLK) || \((SOURCE) == SysTick_CLKSource_HCLK_Div8))

3 Systick使用实践

        Systick定时时间的设定:
                
重装载值=systick 时钟频率(Hz) X 想要的定时时间(S)
                如果时钟频率为:AHB的8分频;AHB=72MHz那么systick的时钟频率为72/8MHz=9MHz。若要定时1秒,则重装载值=9000000X1=9000000,调用函数:SysTick_Config(9000000X1)。若要定时1毫秒,重状态值=9000000X0.001=9000,调用函数:SysTick_Config(9000000/1000);

Systick的中断处理函数:
                在startup_stm32f10x_hd.s启动文件中有定义:DCD     SysTick_Handler         ; SysTick Handler
                根据需要直接编写中断处理函数即可:Void SysTick_Handler (void)
                注意:如果在工程中,加入了stm32f10x_it.c,而又在主函数中编写中断函数,则会报错。因为在stm32f10x_it.c文件中,也有这个中断函数的声明,只是内容是空的。

/*** @摘要   这个函数处理SysTick Handler。* @参数   无* @返回值 无*/
void SysTick_Handler(void)
{
}

        中断优先级的修改:
                在调用SysTick_Config(uint32_t ticks)之后,调用 void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)。这个函数在core_cm3.h头文件中。具体内容如下:

/**
* @摘要   设置中断的优先级
* @参数   IRQn      用于设置优先级的中断数
* @参数   priority  设定的优先级
*为指定的中断设置优先级。中断号可以是正数来指定外部(设备特定的)中断,也可以是负数来指定内部(核心)中断。
* 注释:   不能为每个核心中断设置优先级。
*/
static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{if(IRQn < 0) {SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* 设置Cortex-M3系统中断优先级 */else {NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        /* 设置Cortex-M3系统中断优先级  */
}

下面以一个实例来说明:利用systick来实现以1秒的时间间隔,闪亮一个LED指示灯,指示灯接在GPIOA.8,低电平点亮。

#include "stm32f10x.h"
//函数声明
void GPIO_Configuration(void);  //设置GPIOA.8端口
u32 t;       //定义一个全局变量
int main(void)
{// SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);SysTick_Config(9000000);SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);GPIO_Configuration();while(1);
}//GPIOA.8设置函数
void GPIO_Configuration(void)
{GPIO_InitTypeDef  GPIO_InitStruct;    //定义一个端口初始化结构体RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    //打开GPIOA口时钟GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;     //设置为推挽输出GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;    //设置输出频率50MGPIO_InitStruct.GPIO_Pin=GPIO_Pin_8;      //指定第8脚GPIO_Init(GPIOA,&GPIO_InitStruct);     //初始化GPIOA.8      GPIO_SetBits( GPIOA,  GPIO_Pin_8);    //置高GPIOA.8,关闭LED
}
//systick中断函数
void SysTick_Handler(void)
{
t++;if(t>=1){if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==1){GPIO_ResetBits( GPIOA, GPIO_Pin_8);}      }if(t>=2){if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==0){GPIO_SetBits( GPIOA, GPIO_Pin_8);}t=0;}
}

以上基本讲完了,下面是我在网上看到的一些其他理解。
        基于STM32F10x V3.5.0库如何操作Systick定时器呢?首先:STM32 的内核库已经提供了这个功能。只要配置SysTick_Config()即可实现。看下面的程序段:

/*
* 函数名:SysTick_Init
* 描述         :启动系统滴答定时器 SysTick
* 输入  : 无
* 输出  :无
* 调用  : 外部调用
*/
void SysTick_Init(void)
{if(SysTick_Config(SystemCoreClock/1000))         //1ms定时器{while(1);}//SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;            //若无法启动则关闭
}

SysTick_Config()的参数,其实就是一个时钟次数,叫SysTick重装定时器的值。意思就是我要多少个1/fosc 时间后中断一下。
        根据学过的物理中的时间与频率的公式:fosc=1/T   T=1/fosc ,fosc为系统的频率。如果STM32时钟频率为:72MHz,每次的时间为:T=1/72MHz。1秒钟为:1/(每次的时间)=1/(1/72MHz)=72 000 000次。1MHz是:1000 000。反过来讲。SysTick_Config(72000)代表:72000*(1/72MHz)=1/1000=1(ms)。即定时为1ms。如果需要1S,可以通过设置一个全局变量,然后定初值得为1000,这样,每个systick中断一次,这个全局变量减1,减到0,即systick中断1000次,时间为:1ms*1000=1S。从而实现1S的定时。因为SysTick定时器是:24位的,最大定时时间为:2的24次方*(1/72MHz)的时间,这里系统频率为:72MHz的情况下。

如何使用这个Systick用于程序设计上的延时或是定时作用呢?如下:__IO uint32_t TimingDelay;  定义一个全局变量,注意类型为 volatile的。volatile的作用: 作为指令关键字,确保本条指令不会因为编译器的优化而省略,且要求每次直接读值,然后定义一个延时或是定时函数:

/*
* 函数名:Delay_ms
* 描述         :ms延时程序,1ms为一个单位
* 输入  : - nTime
* 输出  :无
* 示例  : Delay_ms(1) 实现的延时为:1*ms=1ms
* 调用  :外部调用
*/
void Delay_ms(uint16_t nTime)
{TimingDelay = nTime;//使能系统滴答定时器while(TimingDelay !=0);
}

还要在系统的中断函数文件:stm32f10x_it.c/h  里面,修改系统自带的 SysTick 函数。这个函数要么没有声明或是为空操作。这里加入定时延时里的处理。即中断后,全局变量做个延时处理即可。在stm32f10x_it.c里修改如下:添加外部的声明:extern __IO uint32_t TimingDelay;  修改这个函数:SysTick_Handler  ,这是系统的关于SysTick_Handler的中断服务程序名,在启动文件里如:startup_stm32f10x_hd.s   有它的定义的名字。不要弄错了。否则无法中断处理。

/*** @摘要   这个函数处理SysTick Handler。* @参数   无* @返回值 无*/
void SysTick_Handler(void)
{
if (TimingDelay != 0x00){   TimingDelay--; }
}

以上,即定义配置好了Systick定时器。如何使用呢?很简单。Delay_ms(500);  即为延时500ms。当然,使用前,请先初始化:SysTick_Init();否则无法使用并影响后续的程序运行,这个很重要,就像打开了串口中断,你不清标志位,也同样在接收字符后,CPU中断在那里,而不能继续执行!。使用外设功能,需要初始化!

4 配置延时函数(systick定时器)

4.1 delay_init函数

该函数初始化了两个重要参数:fac_usfac_ms,同时将SysTick是时钟源配置为外部时钟,具体代码如下:

//初始化延迟函数
//SYSTICK的时钟固定为HCLK时钟的1/8
//SYSCLK:系统时钟
void delay_init()
{//选择外部时钟  HCLK/8SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);fac_us = SystemCoreClock/8000000;  //为系统时钟的1/8fac_ms = fac_us * 1000;            //1ms = 1us * 1000
}

SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); 这里把SysTick的时钟配置为外部时钟,要注意的是SysTick 的时钟源自与HCLK的8分频,如果外部晶振为8MHz,然后倍频到72MHz,那么SysTick的时钟就是72/8 = 9MHz,即是SysTick的计数器每减1,时间就过去了1/9us。所以fac_us = SystemCoreClock/8000000; 表示过了1us,可能有部分人对这句话不太理解,下面做个大概解释,上面说到systick为系统时钟的8分频,假设系统时钟倍频到72MHz,8分频即为9MHz,所以每一个systick时钟周期的时间为1/9us,SystemCoreClock/8000000 的意思是算出 1us 需要几个 systick 周期,即72000000/8000000 = 9个systick时钟周期,fac_us = 9 * 1/9us = 1us 没毛病,还没看懂的多看几遍就理解了,接下来的fac_ms = fac_us * 1000,1ms等于1000 us 这个不用怎么解释了。
        该注意的是delay_init函数需要在main函数的开头调用作为对systick定时器的配置,fac_us和fac_ms变量需要在定义为全局变量,因为接下来的两个函数还将用到。

static uint8_t   fac_us;   //us延时倍乘数
static uint16_t  fac_ms;   //ms延时倍乘数,在ucos下,代表每个节拍的ms数

4.2 delay_us函数

该函数用来延时指定的us,其参数nus为要延时的毫秒数,代码如下:

//功能:     delay_us
//参数:     nus
void delay_us(uint32_t nus)
{uint32_t temp;SysTick->LOAD = nus * 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;                        //清空计数器
}

以上是配置SysTick的寄存器实现的延时,有兴趣的可以参阅core_cm3.h头文件CTRL、LOAD、VAL、CALIB 这4个寄存器。

4.3 delay_ms函数

该函数用来延时指定的ms,其参数nms为要延时的毫秒数,代码如下:

//功能:     delay_ms
//参数:     nms  注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms,对72M条件下,nms<=1864
void delay_ms(uint16_t nms)
{uint32_t temp;SysTick->LOAD = nms * 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;                        //清空计数器
}

创建 delay.h 加入上面3个函数的声明,然后在main函数或者其他函数中直接调用 delay_us() 函数和 delay_ms() 函数就可以了。

5 总结

1)要使用systick定时器,只需调用SysTick_Config(uint32_t ticks)函数即可,函数自动完成:重装载值的装载,时钟源选择,计数寄存器复位,中断优先级的设置(最低),开中断,开始计数的工作。
        2)要修改时钟源调用SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource),也可按照SysTick_Config()中默认设置FCLK不变。
        3)要修改中断优先级调用 void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
        应用说明:
        1)因systick是一个24位的定时器,故重装值最大值为2的24次方=16 777 215,要注意不要超出这个值。
        2)systick是cortex_m3的标配,不是外设。故不需要在RCC寄存器组打开他的时钟。
        3)每次systick溢出后会置位计数标志位和中断标志位,计数标志位在计数器重装载后被清除,而中断标志位也会随着中断服务程序的响应被清除,所以这两个标志位都不需要手动清除。
        4)采用使用库函数的方法,只能采用中断的方法响应定时器计时时间到,如要采用查询的方法,那只能采用设置systick的寄存器的方法,具体操作以后再做分析。

STM32-SysTick定时器相关推荐

  1. stm32 systick定时器

    systick定时器是系统滴答定时器,一个24位的倒计时定时器,计到0时,将从RELOAD寄存器中自动装载定时初值,只要不把它在Systick控制及状态寄存器中的使能位清楚,就永不停息,即使在睡眠状态 ...

  2. STM32——SysTick 定时器讲解(代码)

    一.SysTick-系统定时器简介 SysTick-系统定时器是属于CM3内核中的一个外设,内嵌在NVIC中.系统定时器是一个24bit的向下递减的计数器, 计数器每计数一次的时间为1/SYSCLK, ...

  3. STM32延时函数的四种方法:普通延时(2种)、SysTick 定时器延时(2种)

    STM32延时函数的三种方法:普通延时.SysTick 定时器延时(1.中断方式:2.非中断方式) 单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时delay_us( )和毫秒级delay_ ...

  4. STM32开发 -- Systick定时器

    如需转载请注明出处:https://blog.csdn.net/qq_29350001/article/details/81630311 一.Systick定时器介绍 参看:STM32菜鸟成长记录-系 ...

  5. 【STM32】SysTick定时器

    00. 目录 文章目录 00. 目录 01. SysTick定时器概述 02. SysTick定时器寄存器描述 03. 相关函数实现 04. 延时函数实现 05. 应用示例 06. 附录 07. 声明 ...

  6. STM32系统定时器SysTick(只能向下递减)延时闪烁灯

    参考:stm32 系统定时器 SysTick 作者:点灯小哥 发布时间: 2021-03-10 13:46:00 网址:https://blog.csdn.net/weixin_46016743/ar ...

  7. STM32学习及应用笔记一:SysTick定时器学习及应用

     这几年一直使用STM32的MCU,对ARM内核的SysTick计时器也经常使用,但几乎没有仔细了解过.最近正好要在移植一个新的操作系统时接触到了这块,据比较深入的了解了一下. 1.SysTick ...

  8. STM32系统定时器SysTick

    1. SysTick系统定时器概述 学习完STM32的中断,下来就要学习STM32的定时器.就像电话最基本的功能是与人通话一样,定时器最基本的功能就是定时(STM32有些定时器的功能强大得超乎想象,当 ...

  9. STM32的SysTick定时器记录一篇

    CSDN博客主页 ID : Eterlove 一笔一画,记录我的学习生活!站在巨人的肩上Standing on Shoulders of Giants! 该文章为原创,转载请注明出处和作者! 前言 我 ...

  10. STM32 SysTick 滴答定时器原理及应用

    SysTick滴答定时器 一.功能 SysTick定时器是一个简单的定时器,CM3\CM4内核芯片都具备此定时器.SysTick定时器常用来做延时,采用实时系统时则用来做系统时钟. 无论用作延时还是用 ...

最新文章

  1. 剑指offer-调整数组顺序使奇数位于偶数前面13
  2. 树转换为二叉树小技巧
  3. 使用pagination分页插件实现Ajax动态分页
  4. 后台代码和前台显示一样a href=' + URL + ' 使用转义字符
  5. oracle误删除记录或者表的处理方法
  6. PDF转HTML常用方法分享
  7. 计算机与信息科学相关教材,AdobeIllustrator实例教程/计算机与信息科学系列规划教材...
  8. 腐蚀rust服务器命令_腐蚀rust服务器命令一览 腐蚀rust有哪些服务器命令
  9. css+html投票系统,网上在线投票系统的设计与实现.doc
  10. SSL1653 数字游戏
  11. Firefox火狐浏览器插件大全
  12. 010Java知识点小结--抽象类、接口
  13. 四成单身、平均年薪19万、最爱买房,原来真实的程序员是这个样子的…...
  14. @生存技巧!程序员如何应对女朋友的“小脾气”(最后附女友靓照)
  15. 片上总线Wishbone 学习(三)Wishbone互联的类型
  16. Unity 第三方SDK框架接入 (Android Studio)
  17. 响应式布局的实现方法
  18. yarn unlink 简单使用
  19. 语义分割--Dilated Residual Networks
  20. long自动转为float类型

热门文章

  1. oracle 内部表连接方式,ORACLE 表连接方式
  2. Java 并发编程之 ThreadLocal 线程局部变量
  3. Redis HyperLogLog
  4. linux 如何查看远程代码分支,linux看git 创建分支、删除本地分支、查看远程分支、本地分支例子...
  5. Flink Java 使用map reduce实现wordcount
  6. Mac 安装配置 chromedriver
  7. 计算机图形学在线作业,电子科大16秋《计算机图形学》在线作业3答案
  8. java volatile关键字的作用_java volatile关键字作用及使用场景详解
  9. java字符串拼接_字符串拼接,什么时候会走StringBuilder?
  10. 浅谈密码学中数论基础