STM32F1定时器TIM

目录

[1. TIM(Timer)定时器](#1. TIM(Timer)定时器)

[2. 定时器类型](#2. 定时器类型)

[2.1 基本定时器框图](#2.1 基本定时器框图)

[2.2 通用定时器框图](#2.2 通用定时器框图)

[2.3 高级定时器框图](#2.3 高级定时器框图)

[3. 定时器代码](#3. 定时器代码)

[3.1 恢复缺省配置](#3.1 恢复缺省配置)

[3.2 时基单元初始化](#3.2 时基单元初始化)

[3.3 结构体变量附一个默认值](#3.3 结构体变量附一个默认值)

[3.4 使能计数器](#3.4 使能计数器)

[3.5 使能中断输出信号](#3.5 使能中断输出信号)

[3.6 选择内部时钟](#3.6 选择内部时钟)

[3.7 选择ITRx其他定时器的时钟](#3.7 选择ITRx其他定时器的时钟)

[3.8 选择TIx捕获通道的时钟](#3.8 选择TIx捕获通道的时钟)

[3.9 选择ETR通过外部时钟模式1输入的时钟](#3.9 选择ETR通过外部时钟模式1输入的时钟)

[3.10 选择ETR通过外部时钟模式2输入的时钟](#3.10 选择ETR通过外部时钟模式2输入的时钟)

[3.11 配置ETR引脚的预分频起,极性滤波器等](#3.11 配置ETR引脚的预分频起,极性滤波器等)

[3.12 单独写预分频的值](#3.12 单独写预分频的值)

[3.13 改变计数器的计数模式](#3.13 改变计数器的计数模式)

[3.14 自动重装器预装功能配置](#3.14 自动重装器预装功能配置)

[3.15 给计数器写入一个值](#3.15 给计数器写入一个值)

[3.16 给自动重装器写入一个值](#3.16 给自动重装器写入一个值)

[3.17 获取当前计数器的值](#3.17 获取当前计数器的值)

[3.18 获取当前预分频器的值](#3.18 获取当前预分频器的值)

[4. 定时器配置](#4. 定时器配置)

[4.1 指定时钟分频,1分频](#4.1 指定时钟分频,1分频)

[4.2 配置计数方式](#4.2 配置计数方式)

[4.3 全部配置如下](#4.3 全部配置如下)


1. TIM(Timer)定时器

定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断。

16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时。

计数器:用来执行计数定时的一个寄存器,每来一个时钟,计数器加1

预分频器:对计数器的时钟进行分频,让计数更加灵活

自动重装寄存器:计数的目标值,就是我们想要多少个时钟申请中断
16位寄存器(2^16=65536),假如预分频器和自动重装寄存器,设到最大,就是:

72MHz/(2^16)/(2^16)=中断频率(f)

取倒数得时间(T=1/f)

可得最大定时59.65s

不仅具备基本的定时中断功能,而且还包含内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等多种功能。

根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型。

2. 定时器类型

STM32F103C8T6定时器资源:TIM1、TIM2、TIM3、TIM4

2.1 基本定时器框图

2.2 通用定时器框图

2.3 高级定时器框图

第一遍暂时没看懂,插个眼:

[6-1] TIM定时中断_哔哩哔哩_bilibili

3. 定时器代码

大概了解一下

3.1 恢复缺省配置

复制代码
void TIM_DeInit(TIM_TypeDef* TIMx);

3.2 时基单元初始化

复制代码
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);

TIM_TypeDef* TIMx:选择某个定时器

TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct:包含了一些配置时基单元的参数

3.3 结构体变量附一个默认值

复制代码
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);

3.4 使能计数器

复制代码
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);

TIM_TypeDef* TIMx:选择定时器

FunctionalState NewState:新的状态(使能还是失能)

3.5 使能中断输出信号

复制代码
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);

TIM_TypeDef* TIMx:选择定时器

uint16_t TIM_IT:选择要配置哪个中断

FunctionalState NewState:新的状态(使能还是失能)

3.6 选择内部时钟

复制代码
void TIM_InternalClockConfig(TIM_TypeDef* TIMx);

3.7 选择ITRx其他定时器的时钟

复制代码
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);

TIM_TypeDef* TIMx:选择要配置的定时器

uint16_t TIM_InputTriggerSource:选择要接入哪个其他定时器

3.8 选择TIx捕获通道的时钟

复制代码
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,
                                uint16_t TIM_ICPolarity, uint16_t ICFilter);

TIM_TypeDef* TIMx:选择要配置的定时器

uint16_t TIM_TIxExternalCLKSource:选择TIx具体某个引脚

uint16_t TIM_ICPolarity, uint16_t ICFilter:选择极性和滤波器

3.9 选择ETR通过外部时钟模式1输入的时钟

复制代码
void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);

TIM_TypeDef* TIMx:选择要配置的定时器

uint16_t TIM_ExtTRGPrescaler:外部触发预分频起

uint16_t TIM_ExtTRGPolarity:极性

uint16_t ExtTRGFilter:滤波器

3.10 选择ETR通过外部时钟模式2输入的时钟

复制代码
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, 
                             uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);

TIM_TypeDef* TIMx:选择要配置的定时器

uint16_t TIM_ExtTRGPrescaler:外部触发预分频起

uint16_t TIM_ExtTRGPolarity:极性

uint16_t ExtTRGFilter:滤波器

3.11 配置ETR引脚的预分频起,极性滤波器等

复制代码
void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
                   uint16_t ExtTRGFilter);

TIM_TypeDef* TIMx:选择要配置的定时器

uint16_t TIM_ExtTRGPrescaler:外部触发预分频起

uint16_t TIM_ExtTRGPolarity:极性

uint16_t ExtTRGFilter:滤波器

3.12 单独写预分频的值

复制代码
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);

TIM_TypeDef* TIMx:选择要配置的定时器

uint16_t Prescaler:写入预分频的值

uint16_t TIM_PSCReloadMode:写入的模式

3.13 改变计数器的计数模式

复制代码
void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);

TIM_TypeDef* TIMx:选择要配置的定时器

uint16_t TIM_CounterMode:选择要计数的模式

3.14 自动重装器预装功能配置

复制代码
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);

TIM_TypeDef* TIMx:选择要配置的定时器

FunctionalState NewState:使能还是失能

3.15 给计数器写入一个值

复制代码
void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);

3.16 给自动重装器写入一个值

复制代码
void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);

3.17 获取当前计数器的值

复制代码
uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);

3.18 获取当前预分频器的值

复制代码
uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);

4. 定时器配置

4.1 指定时钟分频,1分频

复制代码
  uint16_t TIM_ClockDivision;     /*!< Specifies the clock division.
                                      This parameter can be a value of @ref TIM_Clock_Division_CKD */

点击TIM_Clock_Division_CKD,按Ctrl+F搜索,可以看到

复制代码
#define TIM_CKD_DIV1                       ((uint16_t)0x0000)
#define TIM_CKD_DIV2                       ((uint16_t)0x0100)
#define TIM_CKD_DIV4                       ((uint16_t)0x0200)
#define IS_TIM_CKD_DIV(DIV) (((DIV) == TIM_CKD_DIV1) || \
                             ((DIV) == TIM_CKD_DIV2) || \
                             ((DIV) == TIM_CKD_DIV4))

可以选择,1分频,2分频,4分频以及不分频,根据自己需求进行选择。

4.2 配置计数方式

复制代码
#define TIM_CounterMode_Up                 ((uint16_t)0x0000)
#define TIM_CounterMode_Down               ((uint16_t)0x0010)
#define TIM_CounterMode_CenterAligned1     ((uint16_t)0x0020)
#define TIM_CounterMode_CenterAligned2     ((uint16_t)0x0040)
#define TIM_CounterMode_CenterAligned3     ((uint16_t)0x0060)
#define IS_TIM_COUNTER_MODE(MODE) (((MODE) == TIM_CounterMode_Up) ||  \
                                   ((MODE) == TIM_CounterMode_Down) || \
                                   ((MODE) == TIM_CounterMode_CenterAligned1) || \
                                   ((MODE) == TIM_CounterMode_CenterAligned2) || \
                                   ((MODE) == TIM_CounterMode_CenterAligned3))
/**

向上计数,向下计数,三种中央对齐的模式

4.3 全部配置如下

复制代码
void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//开启始终APB1
	
	TIM_InternalClockConfig(TIM2);//选择时机单元的时钟,内部时钟
	//定时器上电默认内部时钟,可不写
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//结构体
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//指定时钟分频,1分频
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
	
	//计数器溢出频率:CK_CNT_OV=CK_CNT/(ARR+1)=CK_PSC/(PSC+1)/(ARR-1)
	//对72M进行7200分频,得到10k的计数频率,在10k的频率下,记10000个数,1s
	TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;//PSC,自动重装
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;//ARR,预分频
	//预分频多,自动重装少,以比较低的频率记比较少的数
	//预分频少,自动重装多,以比较高的频率记比较多的数
	
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//重复计数器,高级采用,这里不用给0
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);//手动把更新中断标志位清除一下,避免刚初始化完就进入中断的问题
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//更新中断到NVIC的通路
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC分组2
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_Cmd(TIM2, ENABLE);//使能计数器
}

STM32F1中断NVIC-CSDN博客

STM32F1外部中断EXTI-CSDN博客

相关推荐
small_wh1te_coder5 分钟前
硬件嵌入式学习路线大总结(一):C语言与linux。内功心法——从入门到精通,彻底打通你的任督二脉!
linux·c语言·汇编·嵌入式硬件·算法·c
花落已飘1 小时前
STM32中实现shell控制台(shell窗口输入实现)
stm32·单片机·嵌入式硬件
花落已飘1 小时前
STM32中实现shell控制台(命令解析实现)
stm32·shell
没有钱的钱仔1 小时前
STM32低功耗模式全面指南
css·stm32·css3
TDengine (老段)2 小时前
TDengine STMT2 API 使用指南
java·大数据·物联网·时序数据库·iot·tdengine·涛思数据
牵牛老人3 小时前
Qt处理USB摄像头开发说明与QtMultimedia与V4L2融合应用
stm32·单片机·qt
宇钶宇夕4 小时前
针对工业触摸屏维修的系统指南和资源获取途径
单片机·嵌入式硬件·自动化
黑听人4 小时前
【力扣 简单 C】70. 爬楼梯
c语言·leetcode
杜子不疼.4 小时前
二分查找,乘法口诀表,判断闰年,判断素数,使用函数实现数组操作
c语言
和风化雨4 小时前
stm32的三种开发方式
stm32·单片机·嵌入式硬件