打印
[STM32F0]

【HAL库】STM32 Systick定时器

[复制链接]
3000|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Systick定时器简介
STM32处理器内部包含了一个Systick简单的定时器。因为所有的STM32芯片都带有这个定时器,软件在不同STM32器件间的移植工作得以化简。该定时器的时钟源可以是内部时钟,或者是外部时钟。Systick 为一个 24 位递减计数器,Systick 设定初值并使能后,每经过 1 个系统时钟周期,计数值就减 1。计数到 0 时,Systick 计数器自动重装初值并继续计数,同时内部的 COUNTFLAG 标志会置位,触发中断 (如果中断使能情况下)。
    Systick定时器常用来做延时,或者实时系统的心跳时钟。这样可以节省MCU资源,不用浪费一个定时器。比如UCOS中,分时复用,需要一个最小的时间戳,一般在STM32+UCOS系统中,都采用Systick做UCOS心跳时钟。

Systick包含的寄存器
STM32中的Systick部分内容属于NVIC控制部分,一共有4个寄存器,名称和地址分别是:
        STK_CTRL,        0xE000E010  --  控制寄存器
        STK_LOAD,        0xE000E014  --  重载寄存器
        STK_VAL,        0xE000E018  --  当前值寄存器
        STK_CALRB,        0xE000E01C  --  校准值寄存器

STK_CTRL 控制寄存器

第0位:ENABLE,Systick 使能位  
(0:关闭Systick功能;1:开启Systick功能)       
第1位:TICKINT,Systick 中断使能位
(0:关闭Systick中断;1:开启Systick中断)       
第2位:CLKSOURCE,Systick时钟源选择
(0:使用HCLK/8 作为Systick时钟;1:使用HCLK作为Systick时钟)       
第16位:COUNTFLAG,Systick计数比较标志,如果在上次读取本寄存器后,SysTick 已经数到了0,则该位为1。如果读取该位,该位将自动清零

STK_LOAD 重载寄存器

Systick是一个递减的定时器,当定时器递减至0时,重载寄存器中的值就会被重装载,继续开始递减。STK_LOAD  重载寄存器是个24位的寄存器最大计数0xFFFFFF。
STK_VAL 当前值寄存器

也是个24位的寄存器,读取时返回当前倒计数的值,写它则使之清零,同时还会清除在SysTick 控制及状态寄存器中的COUNTFLAG 标志。

精准微秒延时函数
void delay_us(u32 nus)
{
        u32 temp; SysTick->LOAD = 9*nus;//这里是F1系列参数,其他系列需要更改系数。 SysTick->VAL=0X00;//清空计数器 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源 do {   temp=SysTick->CTRL;//读取当前倒计数值 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达 SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器
}

精准毫秒延时函数
void delay_ms(u16 nms)
{
        u32 temp; SysTick->LOAD = 9000*nms;//这里是F1系列参数,其他系列需要更改系数。SysTick->VAL=0X00;//清空计数器 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源 do {   temp=SysTick->CTRL;//读取当前倒计数值 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达 SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器
}

Systick中断配置HAL库
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
  {
            return (1UL);                                                   
  }

  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                        
  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
  SysTick->VAL   = 0UL;                                             
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                   SysTick_CTRL_TICKINT_Msk   |
                   SysTick_CTRL_ENABLE_Msk;                        
  return (0UL);                                                   
}

Systick时钟配置HAL库
void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)
{
  assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource));
  if (CLKSource == SYSTICK_CLKSOURCE_HCLK)
  {
            SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
  }
  else
  {
            SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK;
  }
}

STM32F0 Systick定时器实验
精准微秒延时函数
void delay_us(u32 nus)
{
        u32 temp; SysTick->LOAD = 6*nus; SysTick->VAL=0X00;//清空计数器 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源 do {   temp=SysTick->CTRL;//读取当前倒计数值 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达 SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器
}
精准毫秒延时函数

void delay_ms(u16 nms)
{
        u32 temp; SysTick->LOAD = 6000*nms; SysTick->VAL=0X00;//清空计数器 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源 do {   temp=SysTick->CTRL;//读取当前倒计数值 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达 SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器
}

STM32F0 Systick定时器实验程序
BSP.zip (1.47 KB)
Drivers.zip (3.72 MB)
Inc.zip (6.7 KB)
LY_STM32F0.zip (1.52 KB)
MDK-ARM.zip (5.8 MB)
Src.zip (10.08 KB)
删除编译信息文件(缩小体积方便备份).zip (438 Bytes)
.zip (876 Bytes)

更多F0视频教程及资料请关注我发布的其他帖子,陆续更新HAL库视频及例程


沙发
huangcunxiake| | 2018-11-12 11:36 | 只看该作者
会使用这个库函数就行了。

使用特权

评论回复
板凳
磨砂| | 2018-11-12 12:55 | 只看该作者
非常的详细 感谢分享

使用特权

评论回复
地板
antusheng| | 2018-11-13 11:36 | 只看该作者
膜拜大神。

使用特权

评论回复
5
tom_xu| | 2018-11-14 11:02 | 只看该作者
能精确到微妙,精度已经很高了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

148

主题

499

帖子

61

粉丝