STM32个人笔记-系统定时器Systick

目录

对于Systick控制及状态寄存器,即STK_CTRL。

对于Systick重装载数值寄存器,即STK_LOAD。

对于Systick当前数值寄存器,即STK_VAL。

Systick定时时间计算

书写一个微秒和毫秒的延时函数(基于systick)


系统定时器Systick属于Cortex-M内核的外设,嵌套在NVIC中。24位,只能递减,计数器每计数一次的时间为1/SYSCLK,减到0时产生systick中断,以此循环往复

系统定时器一般用于操作系统,用于产生时基,维持操作系统的心跳。

主要头文件:core_cm4.h。

Systick是24位的,重装载寄存器也为24位,递减计数器也是24位,所以它们最大可为2的24次方。

counter(当前值)在时钟的驱动下,从reload(初值)开始往下递减计数到0,产生中断和COUNTFLAG标志置1。然后又从reload值开始重新递减计数,如此循环。

对于Systick控制及状态寄存器,即STK_CTRL。

位段名称类型复位值描述
16

COUNTFLAG

R0如果在上次读取本寄存器后, SysTick 已经计到了 0,则该位为 1。如果读取该位,该位将自动清零
2

CLKSOURCE

R/W00=外部时钟源(STCLK)
1=内核时钟(FCLK)
1

TICKINT

R/W01=SysTick倒数计数到0时产生SysTick异常请求
0=数到 0 时无动作
0

ENABLE

R/W0

SysTick 定时器的使能位

对于Systick重装载数值寄存器,即STK_LOAD。

位段名称类型复位值描述
23:0RELOADR/W0当递减计数至0时,将被重装载的值

对于Systick当前数值寄存器,即STK_VAL。

位段名称类型复位值描述
23:0CURRENTR/W0读取时返回当前倒计数值,写它则使之清零

Systick定时时间计算

1)一个计数循环的时间,跟reload和CLK有关。

2)CLK:72M或9M,有CTRL寄存器配置。

3)RELOAD:24位,用户自己配置。

t=reload*(1/clk)

clk=72M时,t=(72)*(1/72M)=1us

clk=72M时,t=(72000)*(1/72M)=1ms

根据固件库文件core_cm3.h查看Systick结构体

typedef struct
{
  __IO uint32_t CTRL;                         //偏移: 0x00  SysTick控制及状态寄存器
  __IO uint32_t LOAD;                         //偏移: 0x04  SysTick重装载寄存器
  __IO uint32_t VAL;                          //偏移: 0x08  SysTick当前数值寄存器
  __I  uint32_t CALIB;                        //偏移: 0x0C  SysTick校准寄存器
} SysTick_Type;

根据固件库文件core_cm3.h查看Systick配置

/* SysTick Reload Register Definitions */
#define SysTick_LOAD_RELOAD_Pos             0                                             //位置
#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)        //置1

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); } 
  else {            //系统外设
    NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        
}


static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{ 
  //判断tick的值是否大于2^24,如果大于,则不符合规则
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            

  //初始化reload寄存器的值                                                             
  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      

  //配置中断优先级,配置为1<<4-1=15,默认为最低的优先级
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); 

  //配置count计数器的值
  SysTick->VAL   = 0;    

  //配置Systick的时钟为72M
  //使能中断
  //使能Systick                                     
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | 
                   SysTick_CTRL_TICKINT_Msk   | 
                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
  return (0);                                                  /* Function successful */
}

STM32里面无论是内核还是外设都是使用4个二进制位来表示中断优先级。

中断优先级的分组对内核和外设同样适用。当比较的时候,只需要把内核的中断优先级的四个位按照外设的中断优先级来分组解析即可,即人为的分出抢占优先级和子优先级。

书写一个微秒的延时函数(基于systick)

/**
 * @bieaf 微秒延时函数
 * @detail 注意:由于指令执行需要时间, 实际的延时精度约为1微秒
 *
 * @param unsigned int Delay 延时的微秒
 */
void delay_us(unsigned int Delay)
{
    uint32_t tickstart = SysTick->VAL;                            ///<获取当前tick
    uint32_t tickNum = 0;
    uint32_t tickMax = SysTick->LOAD + 1;
    uint32_t delay_usvalue = (tickMax / 1000) * Delay;            ///<计算一共需要延时的tick
    while(1)
    {
        uint32_t cur_tick = SysTick->VAL;
        if (cur_tick > tickstart)                                 ///<进行了一次重载
        {
            tickNum = tickstart + (tickMax - cur_tick);
        }
        else                                                      ///<未进行过重载
        {
            tickNum = tickstart - cur_tick;
        }

        if (tickNum > delay_usvalue)                              ///<达到延时的tick数
        {
            return;
        }
    }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值