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博客

相关推荐
EricWang135822 分钟前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
我是谁??24 分钟前
C/C++使用AddressSanitizer检测内存错误
c语言·c++
希言JY1 小时前
C字符串 | 字符串处理函数 | 使用 | 原理 | 实现
c语言·开发语言
午言若1 小时前
C语言比较两个字符串是否相同
c语言
Thanks_ks2 小时前
探索计算机互联网的奇妙世界:从基础到前沿的无尽之旅
物联网·云计算·区块链·tcp/ip协议·计算机互联网·万维网·未来科技
m0_739312873 小时前
【STM32】项目实战——OV7725/OV2604摄像头颜色识别检测(开源)
stm32·单片机·嵌入式硬件
嵌入式小章3 小时前
基于STM32的实时时钟(RTC)教学
stm32·嵌入式硬件·实时音视频
TeYiToKu3 小时前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm
互联网打工人no13 小时前
每日一题——第一百二十四题
c语言
爱吃生蚝的于勒3 小时前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法