赞
踩
Systick定时器
Systick定时器是什么?
Systick定时器就是系统滴答定时器,一个24 位的倒计数定时器,计到0 时,将从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息,即使在睡眠模式下也能工作;
SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常中断请求(异常号:15);
Systick中断的优先级也可以设置。
CTRL | SysTick 控制和状态寄存器 |
LOAD | SysTick 自动重装载除值寄存器 |
VAL | SysTick 当前值寄存器 |
CALIB | SysTick 校准值寄存器 |
- 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;
- }
- }
时钟中断设置函数SysTick_Config(uint32_t ticks)
补充说明:ul后缀表示什么?
UL表示无符号长整型。
Systick滴答时钟的时钟源简介
对于STM32,外部时钟源是 HCLK(AHB总线时钟)的1/8;内核时钟是 HCLK时钟。
SysTick_Config(uint32_t ticks)的函数体
- static __INLINE uint32_t SysTick_Config(uint32_t ticks)
- {
- if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
-
- SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */
- NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
- SysTick->VAL = 0; /* Load the SysTick Counter Value */
- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
- SysTick_CTRL_TICKINT_Msk |
- SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
- return (0); /* Function successful */
- }
- static __INLINE uint32_t SysTick_Config(uint32_t ticks)
- {
- if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* 判断计数值是否超过MAX */
-
- SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* 设置预定的计数值,以便从该数值开始倒数至0 */
- NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* 配置中断优先级 */
- SysTick->VAL = 0; /* 初始值设置为零 */
- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
- SysTick_CTRL_TICKINT_Msk |
- SysTick_CTRL_ENABLE_Msk; /* 使能中断请求(IRQ)和定时器timer */
- return (0); /* 函数调用成功 */
- }
函数体中的预定义部分
- #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 */
掩膜操作听起来很高大上,其实就是遮掩其他位只对我们要操作的位进行相应的操作,比如:0x01101&A意味着将A的第2,5位进行置零操作,其他位不变。
函数体
- void delay_init() // 去除了OS的相关内容
- {
- SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8
- fac_us=SystemCoreClock/8000000; //为系统时钟的1/8
- fac_ms=(u16)fac_us*1000; //非OS下,代表每个ms需要的systick时钟数
- }
函数功能
① 配置外部时钟源;
② 按照系统时钟源的大小配置systick滴答定时器时钟源
- #ifdef SYSCLK_FREQ_HSE
- uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /*!< System Clock Frequency (Core Clock) */
- #elif defined SYSCLK_FREQ_24MHz
- uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz; /*!< System Clock Frequency (Core Clock) */
- #elif defined SYSCLK_FREQ_36MHz
- uint32_t SystemCoreClock = SYSCLK_FREQ_36MHz; /*!< System Clock Frequency (Core Clock) */
- #elif defined SYSCLK_FREQ_48MHz
- uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz; /*!< System Clock Frequency (Core Clock) */
- #elif defined SYSCLK_FREQ_56MHz
- uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz; /*!< System Clock Frequency (Core Clock) */
- #elif defined SYSCLK_FREQ_72MHz
- uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /*!< System Clock Frequency (Core Clock) */
- #else /*!< HSI Selected as System Clock source */
- uint32_t SystemCoreClock = HSI_VALUE; /*!< System Clock Frequency (Core Clock) */
- #endif
③ 计算毫秒/微秒的延迟因子。
- void delay_us(u32 nus) // 非OS的delay函数的调用
- {
- u32 temp;
- SysTick->LOAD=nus*fac_us; //时间加载
- SysTick->VAL=0x00; //清空计数器
- SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //使能systcik滴答定时器
- do
- {
- temp=SysTick->CTRL;
- }while((temp&0x01)&&!(temp&(1<<16))); //等待直达条件不成立
- SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
- SysTick->VAL =0X00; //清空计数器
- }
- // systick滴答定时器退出循环的标志:systick滴答定时器被使能+计数器自减至0
使用原理如上“Delay_ms函数的使用”。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。