淘宝网做宝贝详情用哪个网站,民和县wap网站建设公司,做剧情网站侵权吗,怎么自创公众号一、什么是 SysTick
SysTick—系统定时器是属于CM3内核中的一个外设#xff0c;内嵌在NVIC中。系统定时器是一个24bit的向下递减的计数器#xff0c; 计数器每计数一次的时间为1/SYSCLK#xff0c;一般我们设置系统时钟SYSCLK等于72M。当重装载数值寄存器的值递减到0的时候…一、什么是 SysTick
SysTick—系统定时器是属于CM3内核中的一个外设内嵌在NVIC中。系统定时器是一个24bit的向下递减的计数器 计数器每计数一次的时间为1/SYSCLK一般我们设置系统时钟SYSCLK等于72M。当重装载数值寄存器的值递减到0的时候系统定时器就产生一次中断以此循环往复。
因为SysTick是属于CM3内核的外设所以所有基于CM3内核的单片机都具有这个系统定时器使得软件在CM3单片机中可以很容易的移植。 系统定时器一般用于操作系统用于产生时基维持操作系统的心跳。
当然更常用的还是在裸机环境下作为延迟函数使用本篇不介绍rtos相关的 SysTick 使用。
二、SysTick 寄存器描述 SysTick-CTRL, --控制和状态寄存器 SysTick-LOAD, --重装载寄存器 SysTick-VAL, --当前值寄存器 SysTick-CALIB, --校准值寄存器 不常用 不做介绍 2.1 SysTick-CTRL 2.2 SysTick-LOAD 2.3 SysTick-VAL 2.4 SysTick-CALIB 三、如何使用滴答定时器
3.1 初始化滴答定时器
通过设置 SysTick-CTRL 的第二位寄存器我们可以配置滴答定时器使用外部时钟 (STCLK) 或者是 Cortex 内核时钟 (FCLK)。
所谓 Cortex 内核时钟就是如下图所示AHB 八分频后的时钟。 在此我们配置为使用 Cortex 内核时钟对 CTRL 第二位置 1 即可。
SysTick-CTRL~(12); //使用 Cortex 内核时钟
SystemCoreClock 是定义了系统时钟 (SYSCLK)频率的宏,即等于AHB 的时钟频率。笔者使用的是STM32F103x系列mcuSystemCoreClock 被系统库配置成 72Mhz。
因为我们使了 Cortex 内核时钟。所以同样需要除 8 来当作八分频使用。
下面的代码则代表每1秒钟SysTick会有 72000000/8 9000000 次的计数周期。
fac_s SystemCoreClock/8; //为系统时钟的1/8 代表每个s完成的systick时钟数 之后我们依次配置每秒每毫秒每微秒的滴答定时器周期。
//1s1000ms1000000us
static u32 fac_s0; //一秒的滴答定时器计数周期数量
static u32 fac_ms0; //一毫秒的滴答定时器计数周期数量
static u32 fac_us0; //一微秒的滴答定时器计数周期数量void delay_init(){SysTick-CTRL~(12); //使用 Cortex 内核时钟fac_s SystemCoreClock/8; //为系统时钟的1/8 代表每个s完成的systick时钟数fac_ms fac_s/1000; //代表每个ms完成的systick时钟数fac_us fac_ms/1000; //代表每个us完成的systick时钟数
}
3.2 实现 delay_us() 函数
细看注释配合之前的寄存器描述即可看懂。
void delay_us(u32 nus)
{u32 temp; SysTick-LOADnus*fac_us; //时间加载 SysTick-VAL0x00; //清空计数器SysTick-CTRL|1 ; //使能计数器 ENABLE位置1do{tempSysTick-CTRL;//检查CTRL的ENABLE位和COUNTFLAG位//如果ENABLE位为0或者COUNTFLAG位为1则判断为计数结束 等待时间到达 }while((temp0x01)!(temp(116)));SysTick-CTRL~1; //关闭计数器 ENABLE位置0SysTick-VAL 0X00; //清空计数器
}
三、使用 SysTick 的中断 根据 SysTick-CTRL 寄存器表的提示我们只需要把第一位置高即可开启 SysTick 异常中断。
3.1 使用库函数
在这里我们不再从头写寄存器而是使用core_cm3.h 的库函数并且解析其中的原理。
#include stm32f10x.hint main(void)
{ if (SysTick_Config(SystemCoreClock / 1000)) // ST3.5.0库版本{while (1);}for(;;){__NOP();}
}void SysTick_Handler(void)
{//每1ms中断一次
}
在下列代码中我们的程序可以每隔 1ms 调用一次滴答定时器回调函数。
3.2 源码解析
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{if (ticks SysTick_LOAD_RELOAD_Msk) return (1); /* 值超过0xFFFFFF直接退出 */SysTick-LOAD (ticks SysTick_LOAD_RELOAD_Msk) - 1; /* 设置重载寄存器 与运算防止越界 */NVIC_SetPriority (SysTick_IRQn, (1__NVIC_PRIO_BITS) - 1); /* 设置Cortex-M0系统中断的优先级 */SysTick-VAL 0; /* 加载SysTick计数器值 */SysTick-CTRL SysTick_CTRL_CLKSOURCE_Msk |SysTick_CTRL_TICKINT_Msk |SysTick_CTRL_ENABLE_Msk; /* 使能 SysTick IRQ 和 SysTick Timer */return (0); /* 函数成功 */
}
方便阅读代码我将下边的几个宏定义也粘贴过来
#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 Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos 0 /*! SysTick LOAD: RELOAD Position */
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFul SysTick_LOAD_RELOAD_Pos) /*! SysTick LOAD: RELOAD Mask */