zoukankan      html  css  js  c++  java
  • SysTick—系统定时器

    本章参考资料《ARM Cortex-M4F 技术参考手册》 -4.5 章节 SysTick Timer(STK), 和
    4.48 章节 SHPRx,其中 STK 这个章节有 SysTick 的简介和寄存器的详细描述。因为
    SysTick 是属于 CM4 内核的外设,有关寄存器的定义和部分库函数都在 core_cm4.h 这个头
    文件中实现。所以学习 SysTick 的时候可以参考这两个资料,一个是文档,一个是源码。

    SysTick 简介
    SysTick—系统定时器是属于 CM4 内核中的一个外设,内嵌在 NVIC 中。系统定时器
    是一个 24bit 的向下递减的计数器,计数器每计数一次的时间为 1/SYSCLK,一般我们设置
    系统时钟 SYSCLK 等于 180M。当重装载数值寄存器的值递减到 0 的时候,系统定时器就
    产生一次中断,以此循环往复。
    因为 SysTick 是属于 CM4 内核的外设,所以所有基于 CM4 内核的单片机都具有这个
    系统定时器,使得软件在 CM4 单片机中可以很容易的移植。系统定时器一般用于操作系统,
    用于产生时基,维持操作系统的心跳。
    SysTick 属于内核的外设,有关的寄存器定义和库函数都在内核相关的库文件
    core_cm4.h 中。
    用固件库编程的时候我们只需要调用库函数 SysTick_Config()即可,形参 ticks 用来设
    置重装载寄存器的值,最大不能超过重装载寄存器的值 224,当重装载寄存器的值递减到 0
    的时候产生中断,然后重装载寄存器的值又重新装载往下递减计数,以此循环往复。紧随
    其后设置好中断优先级,最后配置系统定时器的时钟为 180M,使能定时器和定时器中断,
    这样系统定时器就配置好了,一个库函数搞定。
    SysTick_Config()库函数主要配置了 SysTick 中的三个寄存器: LOADVAL CTRL
    有关具体的部分看代码注释即可。其中还调用了固件库函数 NVIC_SetPriority()来配置系统
    定时器的中断优先级,该库函数也在 core_m4.h 中定义,
    原型如下:
    1 __STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
    2 {
    3 if ((int32_t)IRQn < 0) {
    4 SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] =
    5 (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
    6 } else {
    7 NVIC->IP[((uint32_t)(int32_t)IRQn)] =
    8 (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
    9 }
    10 }
    因为 SysTick 属于内核外设,跟普通外设的中断优先级有些区别,并没有抢占优先级
    和子优先级的说法。在 STM32F429 中,内核外设的中断优先级由内核 SCB 这个外设的寄
    存器: SHPRxx=1.2.3)来配置。有关 SHPRx 寄存器的详细描述可参考《 Cortex-M4 内核
    编程手册》 4.4.8 章节。
    在系统定时器中,配置优先级为(1UL << __NVIC_PRIO_BITS) - 1UL),其中宏
    __NVIC_PRIO_BITS 4,那计算结果就等于 15,可以看出系统定时器此时设置的优先级
    在内核外设中是最低的。

    SysTick 初始化函数由用户编写,里面调用了 SysTick_Config()这个固件库函数,通过
    设置该固件库函数的形参,就决定了系统定时器经过多少时间就产生一次中断。
    SysTick 中断时间的计算
    SysTick 定时器的计数器是向下递减计数的,计数一次的时间 TDEC=1/CLKAHB,当重装
    载寄存器中的值 VALUELOAD 减到 0 的时候,产生中断,可知中断一次的时间
    TINT=VALUELOAD * TDEC 中断= VALUELOAD/CLKAHB,其中 CLKAHB =180MHZ。如果设置为
    180,那中断一次的时间 TINT=180/180M=1us。不过 1us 的中断没啥意义,整个程序的重心
    都花在进出中断上了,根本没有时间处理其他的任务。
    SysTick_Config(SystemCoreClock / 100000))
    SysTick_Config()的形我们配置为 SystemCoreClock / 100000=180M/100000=1800
    从刚刚分析我们知道这个形参的值最终是写到重装载寄存器 LOAD 中的,从而可知我们现
    在把 SysTick 定时器中断一次的时间 TINT=1800/180M=10us

     

  • 相关阅读:
    理解java容器:iterator与collection,容器的起源
    【软件构造】-<笔记>-浅谈java中类的初始化过程
    CSAPP HITICS 大作业 hello's P2P by zsz
    2年经验,java后端必备技术点总结(脑图)
    手把手教,手写AVL树
    Redis源码分析-底层数据结构盘点
    验证mysql事务隔离级别机制加锁情况与MVCC机制
    Layui镜像站
    elasticsearch技术实战——第一篇(使用篇)
    【基础1】JniHelper静态函数和非静态函数的调用
  • 原文地址:https://www.cnblogs.com/yangguang-it/p/7056398.html
Copyright © 2011-2022 走看看