STM32—TIM定时中断

1.TIM简介

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

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

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

分为高级定时器、通用定时器、基本定时器三种

类型编号总线功能
高级定时器TIM1、TIM8APB2拥有通用定时器的全部功能,并额外具有重复计数器、死区生成、互补输出、刹车输入等功能
通用定时器TIM2、TIM3、TIM4、TIM5APB1拥有基本定时器全部功能,并额外具有内外时钟源选择、输入捕获、输出比较、编码器接口、主从触发模式等功能
基本定时器TIM6、TIM7APB1拥有定时中断、主模式触发ADC的功能

2.基本定时器

预分频器PSC:若该寄存器写0,则为1分频,主频/2;若写1,则为2分频,主频/2...最大可以写65535,则为65536分频

计数器CNT:计数时钟每来一个上升沿,计数器+1,里面的值可以从0加到65535,再加就回到0

自动重装寄存器:存的是计数的目标,在计数过程中,当计数值等于该值时,就会产生一个中断信号(一般叫做更新中断),并且清零计数器

 

3.通用定时器

 通用定时器和高级定时器拥有向上计数、向下计数和中央对齐计数三种方式

向上计数:计数值从0向上计数到自动重装值产生中断并且清零

向下计数:计数值从自动重装值开始向下递减到0产生中断并重回自动重装值

中央对齐:计数器从0计数到自动重装值产生中断再向下递减到0产生中断

4.高级定时器

重复计数器:可以实现每隔几个计数周期再触发中断,最大值为65535+1

5.定时中断基本结构

 

6.预分频器时序

 

计数器计数频率:CK_CNT = CK_PSC / (PSC + 1)

7.计数器时序

 

计数器溢出频率:CK_CNT_OV = CK_CNT / (ARR + 1)

                                                    = CK_PSC / (PSC + 1) / (ARR + 1)

计算溢出时间则取倒数

更新中断标志置1则产生中断,需要在中断程序中手动清零

8.标准库相关代码介绍

void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
//时基单元初始化
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
//把结构体变量赋初始值
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
//使能计数器
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
//使能外设的中断输出
//时钟源选择相关函数

void TIM_InternalClockConfig(TIM_TypeDef* TIMx);
//选择RCC内部时钟

void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
//选择ITRx其他定时器时钟

void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,
                                uint16_t TIM_ICPolarity, uint16_t ICFilter);
//选择TIx捕获通道的时钟

void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
//选择ETR通过外部时钟模式1输入的时钟

void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, 
                             uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
//选择ETR通过外部时钟模式2输入的时钟

void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);
//单独用来配置ETR引脚的预分频器、极性、滤波器等参数
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);
//配置单独要写入的预分频PSC的值
//第三个参数选择该值是立刻生效还是在更新事件后生效

void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);
//可以用来改变计数器的计数模式

void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
//选择有预装还是无预装

void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);
//给计数器写入一个值

void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload);
//给自动重装数写入一个值

uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);
//返回当前计数器的值

uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);
//获取当前预分频器的值
//分别在主程序和中断函数里获取标志位和清除标志位的函数
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);

9.案例

9.1定时器定时中断

#include "stm32f10x.h"                  // Device header

void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	
	TIM_InternalClockConfig(TIM2);    //选择内部时钟,可以不写,因为上电默认为使用内部时钟
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    //可以选择1分频、2分频、4分频,如消除传感器的抖动
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    //选择计数器模式
	TIM_TimeBaseInitStructure.TIM_Period = 10000-1;
    //自动重装器ARR的值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200-1;
    //预分频器PSC的值
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
    //重复计数器的值,高级定时器才有
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM2,TIM_FLAG_Update);
    //避免刚初始化完就进中断
   	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
    //使能更新中断
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_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);
    //启动定时器
}

9.2定时器外部时钟

#include "stm32f10x.h"                  // Device header

void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x0F);
    //选择ETR通过外部时钟模式2作为时钟源
    //第二个参数选择分频系数,当前为不分频;第三个参数选择外部触发的极性,当前为上升沿有效;第三个参数为滤波器,当前为不使用滤波器
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 10-1;
	TIM_TimeBaseInitStructure.TIM_Prescaler = 1-1;
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM2,TIM_FLAG_Update);
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_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);
}

uint16_t Timer_GetCounter(void)
{
	return TIM_GetCounter(TIM2);
    //返回计时器CNT的值
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值