【STM32】定时器

一、 定时器概述
  1. 定义

​ 设置等待时间, 到达后则执行指定操作的硬件。

  1. STM32F407 的定时器有以下特征

​ 具有基本的定时功能, 也有 PWM 输出(灯光亮度控制、 电机的转速)、 脉冲捕获功能(红外捕捉)。

2 个高级控制定时器、 10 个通用定时器和 2 个基本定时器

​ 高级控制定时器(TIM1 和 TIM8)

​ 具有 16 位定时器功能, 也具有 PWM 输出高级控制功能, 一个定时器支持多路的 PWM 输出。

​ 通用定时器(TIM2 到 TIM5)

​ 具有 16 位定时功能, 也具有 PWM 输出控制功能, 一个定时器支持 1 路的 PWM 输出。

​ 通用定时器(TIM9 到 TIM14)

​ 具有 16 位定时功能, 也具有 PWM 输出控制功能, 一个定时器支持 1 路的 PWM 输出。

​ 基本定时器(TIM6 和 TIM7)

​ 具有 16 位定时功能

​ 注: TIM 是 TIMER 英文的缩写

3.STM32定时器区别

  1. 通用定时器功能特点描述

​ STM3 F4的通用 TIMx (TIM2、TIM3、TIM4 和 TIM5)定时器功能特点包括:

​ 16 /32 位向上、向下、向上/向下(中心对齐)计数模式,自动装载计数器(TIMx_CNT)。

​ 16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数 为 1~65535 之间的任意数 值。

​ 4 个独立通道(TIMx_CH1~4),这些通道可以用来作为:

​ ① 输入捕获

​ ② 输出比较

​ ③ PWM 生成(边缘或中间对齐模式)

​ ④ 单脉冲模式输出

​ 可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1 个定时器控制另外一个定时器)的同 步电路。

  1. 计数模式

    通用定时器可以向上计数、向下计数、向上向下双向计数模式。

    ①向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。

    ②向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。

    ③中央对齐模式(向上/向下计数):计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。

  2. 定时器工作过程

  1. 计数时钟选择
  1. 时基单元
二.定时器配置
  1. 时钟选择

    内部时钟(CK_INT)

    外部时钟模式:外部输入脚(TIx)

    外部时钟模式2:外部触发输入(ETR)(仅适用TIM2,3,4)

    内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器Timer1而作为另一个定时器Timer2的预分频器

  2. 内部时钟选择

  1. 通用定时器寄存器
    1. 计数器当前值寄存器CNT

​ 2. 预分频寄存器TIMx_PSC

​ 3. 自动重装载寄存器(TIMx_ARR)

​ 4. 控制寄存器1(TIMx_CR1)

通用寄存器库函数常用库函数:stm32f4xx_tim.c/.h
  1. 定时器参数初始化

    c 复制代码
     void TIM_TimeBaseInit(TIM_TypeDef* TIMx, 
                           TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
  2. 定时器使能函数:

    c 复制代码
    void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)
  3. 定时器中断使能函数:

    c 复制代码
    void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
  4. 状态标志位获取和清除

    c 复制代码
    FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
    void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
    ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
    void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
溢出时间
c 复制代码
Tout(溢出时间)=(ARR+1)(PSC+1)/Tclk

PSC: 预分频器

ARR : 预转载值

作业
复制代码
使用定时器3控制LED0 500ms进行闪烁
使用定时器8控制LED1 2000ms进行闪烁
c 复制代码
#include "led.h"
#include "beep.h"
#include "sys.h"
#include "delay.h"

void init_TIM3(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;


	// 使能定时器3系统时钟源
	// APB1 :42M
    // TIM3 : 42*2 = 84M == 1s	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	// 配置定时时间 1s
	TIM_TimeBaseStructure.TIM_Period = 10000-1; // 重装载寄存器
	TIM_TimeBaseStructure.TIM_Prescaler = 8400-1; // 分频系数
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; // 时钟二次分频
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

	/* TIM Interrupts enable */
	TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
	
	/* TIM3 enable counter */
	TIM_Cmd(TIM3, ENABLE);

}

void init_TIM8()
{
	NVIC_InitTypeDef NVIC_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	// APB2时钟源为84M
	// TIM8时钟源是84*2 = 168M
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
	
	// 配置中断控制向量表,确定并绑定中断服务函数
	NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	
	// 配置定时时间 2s
	TIM_TimeBaseStructure.TIM_Period = 20000-1; // 重装载寄存器
	TIM_TimeBaseStructure.TIM_Prescaler = 16800-1; // 分频系数
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; // 时钟二次分频
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);

	/* TIM Interrupts enable */
	TIM_ITConfig(TIM8, TIM_IT_Update, ENABLE);
	
	/* TIM3 enable counter */
	TIM_Cmd(TIM8, ENABLE);

	
}

// 定时器3中断服务函数
void TIM3_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
	{
		PFout(10) ^= 1;

		TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
	}
  
}

// 定时器8
void TIM8_UP_TIM13_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM8, TIM_IT_Update) != RESET)
	{
		PFout(9) ^= 1;

		TIM_ClearITPendingBit(TIM8, TIM_IT_Update);
	}
  
}


int main()
{
	init_led();
	 
	init_TIM3();
	
	init_TIM8();

	while(1)
	{
	}
}
总结:
  1. 确定定时器工作频率,只有确定好定时器工作频率才能计算定时时间

  2. 确定定时器分频后的频率

    1. 定时器的分频器为psc,数值范围是 (0 - 2^16)-1
  3. 确定ARR装载寄存器Pre的数值,数值范围是 (0 - 2^16)-1

  1. 根据公式计算

    定时器最后的频率是 : 84000000 / psc = 1S

    根据等比 规则

  1. 附带定时器工作流程图
相关推荐
llilian_1610 小时前
总线授时卡 CPCI总线授时卡的工作原理及应用场景介绍 CPCI总线校时卡
运维·单片机·其他·自动化
禾仔仔11 小时前
USB MSC从理论到实践(模拟U盘为例)——从零开始学习USB2.0协议(六)
嵌入式硬件·mcu·计算机外设
The Electronic Cat12 小时前
树莓派使用串口启动死机
单片机·嵌入式硬件·树莓派
先知后行。15 小时前
常见元器件
单片机·嵌入式硬件
恒锐丰小吕15 小时前
屹晶微 EG2302 600V耐压、低压启动、带SD关断功能的高性价比半桥栅极驱动器技术解析
嵌入式硬件·硬件工程
Dillon Dong16 小时前
按位或(|=)的核心魔力:用宏定义优雅管理嵌入式故障字
c语言·stm32
Free丶Chan17 小时前
dsPIC系列-1:dsPIC33点灯 [I/O、RCC、定时器]
单片机·嵌入式硬件
v先v关v住v获v取18 小时前
塔式立体车库5张cad+设计说明书+三维图
科技·单片机·51单片机
恒锐丰小吕18 小时前
屹晶微 EG2106D 600V耐压、半桥MOS/IGBT驱动芯片技术解析
嵌入式硬件·硬件工程