1、定时器的分类

STM32F103ZET6总共有8个定时器,它们是:TIM1~TIM8。STM32的定时器分为基本定时器、通用定时器和高等定时器。

TIM6、TIM7是基本定时器。基本定时器是只能向上计数的16位定时器,基本定时器只能有定时的功能,没有外部IO口,所以没有捕获和比较通道。

TIM2、TIM3、TIM4、TIM5是通用定时器。通用定时器是可以向上计数,也可以向下计数的16位定时器。通用定时器可以定时、输出比较、输入捕捉,每个通用定时器具有4个外部IO口。

TIM1、TIM8是高等定时器。高等定时器是是可以向上计数,也可以向下计数的16位定时器。高等定时器可以定时、输出比较、输入捕捉、还可以输出三相电机互补信号,每个高等定时器有8个外部IO口。

定时器分类图如下:

2、基本定时器

基本定时器没有外部IO口,所以它只有定时的功能。

基本定时器只能向上计数,也就是说基本定时器只能递增计数。

基本定时器功能框图如下:

从功能图的1中可以看到,基本定时器的时钟TIMxCLK来自内部时钟,该内部时钟为经过APB1预分频器分频后提供的。基本定时器跟APB1总线时钟的关系如下:

如果APB1预分频系数为1,则基本定时器的时钟等于APB1总线时钟。

如果APB1预分频系数不为1,则基本定时器的时钟等于APB1总线时钟经过分频后的2倍。

比如APB1总线经过2分频后的时钟为36MHZ,那么基本定时器的时钟就是72MHZ3(36*2)。

功能图中的2是一个预分频器,来自内部的时钟经过预分器分频后的时钟,用来驱动基本定时器的计数器计数。基本定时器的预分频器是一个16位的预分频器,预分频器可以对定时器时钟进行1~65536之间的任何一个数进行分频。计算方式如下:

定时器工作时钟 = 来自APB1的时钟/(预分频系数+1)

功能图中的3是一个16位的计数器,该计数器能能向上计数,最大计数值位65535。基本定时器的计数器从0开始向上计数,当计数器的值与自动重装载寄存器相等时产生更新事件,并清零从头开始计数。

功能图中的4是一个16位的自动重装载寄存器。该寄存器装着计数器能计数的最大数值。当基本定时器的计数器计数到这个值的时候,如果使能了中断。定时器就会产生溢出中断。

在定时器的参考资料中,很多地方都提到更新事件,其实更新事件就是计数器溢出。

3、定时器的时间计算

基本定时器每计数一次所经过的时间为:

Time = (PSC + 1)/ TIMxCLK(us)

PSC是定时器的分频系数,TIMxCLK是内部时钟。

基本定时器的计数次数由自动重装载寄存器决定的,基本定时器的计数器从0开始向上计数,当计数器的值与自动重装载寄存器相等时,产生溢出。所以基本定时器的溢出时间计算公式如下:

Time = (PSC+1)*(ARR)/ TIMxCLK(us)

ARR是自动重装载寄存器的值。

假设基本定时器TIMxCLK = 72MHZ,PSC = 71,ARR = 1000,那么定时器的溢出时间为:

Time = (71+1)*1000/72 = 1000(us) = 1(ms)

4、定时器的寄存器

TIMx_CR1控制寄存器1

Bit0位CEN是定时器的使能位,CEN=0时,计数器不工作;CEN=1是计数器开始计数。想要定时器工作,就要将CEN置1。

Bit1位UDIS是禁止更新位,当UDIS=0时,定时器溢出后会把TIMx_SR寄存器的UIF置1;当UDIS=1时,定时器溢出后并不会置位UIF位,即不会产生中断。

Bit2位URS是更新请求源,当URS=0时,计数器溢出、设置UG位、通过从模式控制器产生的更新都会产生中断;当URS=1时,只有在计数器溢出的情况下才会产生中断。

Bit3位OPM可以设置定时器是工作一次还是重复工作,当OPM=0时,定时器产生中断后继续工作;当OPM=1时,定时器溢出后会清除CEN位,即定时器停止计数。

Bit7位ARPE是自动重装载预装载使能,当ARPE=0时,TIMx_ARR寄存器没有缓冲;当ARPE=1时,TIMx_ARR寄存器具有缓冲。

TIMx_DIER中断使能寄存器

Bit0位UIE是更新中断使能位,当UIE=0时,定时器禁止溢出中断;当UIE=1时,定时器可以产生溢出中断。

Bit8位UDE是更新DMA请求使能位,当UDE=0时,禁止更新DMA请求;当UDE=1时,使能更新DMA请求。

TIMx_SR状态寄存器

Bit1位UIF是溢出中断标志。当TIMX_CR1的UDIS=0,如果定时器产生溢出,UIF就会被置1,UIF不会被硬件自动清除,只能软件清除。当产生中断时,可以由该位判断是否是定时器的溢出中断。

TIMx_EGR事件产生寄存器

Bit0位UG是产生更新事件,UG位由软件置1,但由硬件自动清除。当UG写0时无作用;当UG写1时,如果TIMx_CR1寄存器的UDIS = 0,则会重新初始化定时器的计数器并产生对寄存器的更新,需要注意的是预分频器也被清除(但预分频系数不变)。

TIMx_CNT计数器寄存器

TIMx_CNT只有低16位有效,可以从0到65535之间计数。

自动重装载寄存器TIMx_ARR

如果TIMx_ARR的数值为0,则TIMx则会停止工作。

自动重装载寄存器是预加载的,每次读写TIMx_ARR寄存器时,实际上是通过读写预加载寄存器实现的。TIMx_ARR寄存器根据TIMx_CR1控制寄存器的bit7位ARPE来决定是带缓冲的或是不带缓冲的。

当ARPE=0时,TIMx_ARR寄存器是不具有缓冲功能的,当改变TIMx_ARR寄存器的值时,立马就更新定时器的自动重装载寄存器,如下图。

从上图可以看到,在没改变TIMx_ARR寄存器的值之前自动重装载的寄存器的是FF,当在计数器跑到32的时候突然改变TIMx_ARR寄存器的值为36,那么自动重装载的寄存器的值也立马从FF变为了36,改变TIMx_ARR寄存器的值并不会影响计数器寄存器的值,计数器寄存器继续从32计数到36后溢出并产生更新中断。

当ARPE=1时,TIMx_ARR寄存器是具有缓冲功能的,当改变TIMx_ARR寄存器的值时,并不会马上更新定时器的自动重装载寄存器,而是要等到下一次更新事件发生时,才会更新定时器的自动重装载寄存器的值,如下图。

从上图可以看到,在没改变TIMx_ARR寄存器的值之前自动重装载的寄存器的是F5,当在计数器跑到F1的时候突然改变TIMx_ARR寄存器的值为36时,虽然自动重装载的寄存器的值也变为了36,但是自动重载影子寄存器的值还是F5,并没有被改变,而且计数器寄存器的值是跟自动重载影子寄存器的值比较,只有当产生更新事件的时候,自动重载影子寄存器的值才变为了36。

TIMx_PSC预分频寄存器

TIMx_PSC只有低16位有效,用来设置定时器时钟的分频系数。

TIMx_PSC预分频寄存器具有缓冲功能,如果在定时器运行的过程中更改TIMx_PSC寄存器的值,定时器的分频系数并不会立马发生更改,而是会等到下一个计数器溢出时新的预分频数值才会更改。如下图。

从图中可以看到,当计数器寄存器递增到F8的时候,TIMx_PSC的值被改写成了1,但是实际的预分频系数还没有被改变,还是0,只有当计数器寄存器溢出变为0时,实际的预分频系数才变为1。从图中还可以看出,当预分频系数为0的时候,CK_PSC = CK_CNT,当预分频系数为1的时候,CK_CNT = 2CK_PSC,也就是通过波形可以看出计数频率变了。

5、基本定时器的配置流程

使能基本定时的时钟,不然无法使用基本定时器。

设置基本定时器的预分频系数和自动重装载寄存器值,通用定时器和高等定时器还要设置计数方向,因为基本定时器只能向上计数,所以不用设置。

开启基本定时器。

通过NVIC配置基本定时器的中断。

编写基本定时器的中断服务函数,在中断服务函数中,可以通过基本定时器的状态寄存器的值来判断此次产生的中断属于什么类型。

6、HAL库操作基本定时器

在使用HAL操作基本定时器之前,需要将stm32f1xx_hal_tim.c和stm32f1xx_hal_tim_ex.c文件添加到功能目录,还要在stm32f1xx_hal_conf.h文件中使能HAL_TIM_MODULE_ENABLED宏。如下图。

以操作基本定时器TIM6为例,初始化代码如下:

1 TIM_HandleTypeDef TIM6_Handler_Init;2

3 void TIM6_Init(void)4 {5 __HAL_RCC_TIM6_CLK_ENABLE();6

7 TIM6_Handler_Init.Instance =TIM6;8 TIM6_Handler_Init.Init.Prescaler = 36000-1;9 TIM6_Handler_Init.Init.Period = 1000;10 HAL_TIM_Base_Init(&TIM6_Handler_Init);11

12 HAL_TIM_Base_Start_IT(&TIM6_Handler_Init);13

14 HAL_NVIC_SetPriority(TIM6_IRQn,2,1);15 HAL_NVIC_EnableIRQ(TIM6_IRQn);16

17 }

第1行首先定义一个全局变量TIM6_Handler_Init,这是一个句柄变量,用来操作TIM6。

第5行通过__HAL_RCC_TIM6_CLK_ENABLE()宏使能TIM6的时钟,如果不是能时钟,是无法操作TIM6的。

第7行是将TIM6_Handler_Init句柄变量指向TIM6。

第8行是将TIM6的分频系数设为36000,如果TIM6的时钟为72M,那么分频后的值为72000000/36000 = 2000HZ。

第9行是将TIM6的自动重载在的值设为1000,即TIM6的计数器计数1000次后溢出,根据分频系数可以得出溢出时间为1000 * 36000 /72000000 = 1000 / 2000 = 0.5s,即TIM6的计数器每0.5秒溢出一次。

第10行是通过HAL_TIM_Base_Init函数配置TIM6定时器。

第12行是通过HAL_TIM_Base_Start_IT函数使能溢出中断,并启动定时器从0开始向上计数。

第14行是通过HAL_NVIC_SetPriority函数设置TIM6的中断优先级。

第15行是通过HAL_NVIC_EnableIRQ函数使能TIM6中断,只有使能了中断,才能进入中断服务函数。

初始化完TIM6后,编写中断服务函数,代码如下:

1 void TIM6_IRQHandler(void)2 {3 HAL_TIM_IRQHandler(&TIM6_Handler_Init);4 }5

6 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)7 {8 if(htim == &TIM6_Handler_Init)9 {10 HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_6);11 }12 }

第1行是TIM6的中断服务函数。

第2行是调用HAL库编写的定时器中断处理函数,将定时器的句柄变量通过参数传入其中。

第6行是定时器的中断回调函数,通过这个函数实现定时器的中断处理。

第8行是通过句柄判断需要处理的是什么类型的中断。

stm32关定时器_STM32F103ZET6的基本定时器相关推荐

  1. stm32关定时器_【菜鸟必看】stm32定时器的妙用

    摘要:本文为你带来关于stm32定时器的使用的便利和优势之处. 使用定时器去计算获取一条的时间 一.初步了解定时器 stm32定时器时钟图如下: 定时器2-7:普通定时器 定时器1.8:高级定时器 二 ...

  2. stm32关定时器_手把手之STM32通用定时器(一)

    ●通用定时器(TM2~TM5) 通用定时器由芯片来管理,可以实现向上计数.向下计数.或者上下同时计数.而且这些定时器还有其他功能:输入捕捉.输出比较.PWM.单脉冲. ●从手册到流程 定时器的主要模块 ...

  3. STM32入门笔记04_TIM定时器+案例:TIM定时器定时中断、定时器外部时钟

    TIM定时器 TIM简介 TIM(Timer) 定时器 定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断 16位计数器.预分频器.自动重装寄存器的时基单元,在72MHz(系统主频)计数时 ...

  4. stm32定时器中断_stm32F4之定时器的基本使用

    概述 上一篇说了stm32F4GPIO的使用,这篇说说定时器的使用 一. stm32F407的定时器资源介绍: ​ STM32F407有14个定时器,其中有12个16位的定时器,2个32位的定时器 这 ...

  5. STM32那点事(6)_定时器(上)

    STM32定时器是CPU中的基本功能模块之一,最基本的功能是提供定时,STM32定时器共用16个定时器,主要分为两个基本定时器,10个通用定时器,2个高级定时器,以及两个看门狗定时器.看门狗定时器后面 ...

  6. 【正点原子STM32连载】第二十章 基本定时器实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1

    1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...

  7. STM32理论 —— ADC、存储、定时器、时钟、中断

    文章目录 1. ADC 1.1 ADC相关寄存器 1.1.1 ADC 控制寄存器1(ADC_CR1) 1.1.2 ADC 控制寄存器2(ADC_CR2) 1.1.3 ADC 采样时间寄存器(ADC_S ...

  8. 基于STM32滴答时钟的多任务定时器

    基于STM32滴答时钟的多任务定时器 基于STM32滴答时钟的多任务定时器 概述 声明:此定时器仅提升个人编程能力和学习使用,不得用于商用,用于商用一切后果自行负责. API说明 滴答时钟初始化并创建 ...

  9. STM32系统学习——TIM(基本定时器)

    一.定时器分类 STM32F1 系列中,除了互联型的产品,共有 8 个定时器,分为基本定时器,通用定时器和高级定时器.基本定时器 TIM6 和 TIM7 是一个 16 位的只能向上计数的定时器,只能定 ...

最新文章

  1. Web项目使用nginx实现代理端口访问,看这篇就够了
  2. java好过去前一天日期_Java-日期保存为前一天
  3. vue 原理简单实现
  4. linux修改系统时间为北京时间(CentOS)
  5. 浅谈Python中的编码规则
  6. 爬虫实战:通过百度关键词爬取大量图片
  7. .SQL Server中 image类型数据的比较
  8. Vs code 02 配置非标准的C、C++的编译环境
  9. linux中波浪号代表什么_建筑电气施工图纸中BV、ZRBLV和TC、SC符号代表什么?
  10. Linux系统运维人员常用速查表
  11. PHP操作图片简单案例
  12. 洛谷P1061 Jam的计数法 数学
  13. Linux中log打印输入输出的格式字符串
  14. scrapy-redis3
  15. 如何解决Vosviewer关键词共现分析出现的Incorrect number of columns错误
  16. 鸿蒙系统桌面壁纸,华为鸿蒙桌面怎么设置好看
  17. 小米路由器 内核 linux,小米路由器配置ssh登入方法教程
  18. 服务器挂起的原因以及需要如何应对?
  19. 全局mixin封装文本溢出隐藏显示省略号
  20. java网课|等待与唤醒线程池

热门文章

  1. vue.js 常见面试题_使用Vue.js时应避免的常见错误
  2. mvc中的mvc分别指什么_什么是MVC,它像三明治店吗?
  3. win10饥荒服务器未响应,win10系统玩饥荒联机很卡如何解决[多图]
  4. dictionary在python中什么意思_Python 字典(Dictionary)操作详解
  5. docker安装elasticsearch2.4.4
  6. Lugre摩擦模型的Stribeck曲线仿真
  7. Python调用Windows API函数编写录音机和音乐播放器
  8. 机器学习的算法和普通《算法导论》里的算法有什么本质上的异同
  9. ASP.NET状态管理之一(概括篇)
  10. 关于Jquery中animate可以操作css样式属性总结