stm32F407学习DAY.12(1) 通用定时器与定时器中断实验(含溢出时间Tout计算公式)

目录

STM32F407定时器概述

一、通用定时器(以TIM2~5为例)

1、概述

2、计数器框图

1)时基电路时钟源CK_PSC的四种来源:

2)时基单元

3)预分频器时序

4)计数器时序

二、定时器中断试验(内部时钟源)

1、常用库函数:stm32f4xx_tim.c/.h

​2、寄存器配置

1)计数器TIMx_CNT​

 2)TIMx 预分频器 TIMx_PSC​

 3)TIMx 自动重载寄存器 TIMx_ARR

 4)TIMx 控制寄存器 1  TIMx_CR1

 5)TIMx DMA/中断使能寄存器 TIMx_DIER 

3、定时器初始化

1)选择时钟

内部时钟的配置

2)定时器时基初始化

3)定时器中断开启与配置

       4、定时器中断服务函数 

三、定时器中断实验(外部时钟源)

1、写明时钟来源

 2、在定时器初始化函数中增加对IO口的配置

 3、代码


STM32F407定时器概述

一共14个,包含12个16位计数器和2个32位计数器。

一、通用定时器(以TIM2~5为例)

1、概述

 

 可以被用于:测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM)等。

使用定时器预分频器和 RCC 时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。

STM32 的每个通用定时器都是完全独立的,没有互相共享的任何资源。

2、计数器框图

1.定时器时钟来源(含内部时钟84MHz和各路外部时钟)产生时基电路时钟源CK_PSC       

2.时基电路        3.输入捕获        4.输出比较         5.相关捕获/比较寄存器

 图源中文参考手册p393

名词注解:

TIMx_ETR:TIMER外部触发引脚      ETR:外部触发输入

ETRP:分频后的外部触发输入           ETRF:滤波后的外部触发输入

ITRx:内部触发x(由其他定时器触发,也是外部触发方式)(定时器级联时使用)

TI1F_ED:TI1的边沿检测器

TI1FP1/2:滤波后定时器1/2的输入

TRGI:触发输入  TRGO:触发输出

CK_PSC:分频器时钟输入

CK_CNT:定时器时钟。(定时周期的计算就靠它)

TIMx_CHx:TIMER的输入脚  TIx:应该叫做定时器输入信号x

ICx:输入比较x  ICxPS:分频后的ICx

OCx:输出捕获x  OCxREF:输出参考信号

1)时基电路时钟源CK_PSC的四种来源:

1)内部时钟CK_INT

2)ETRF时钟:定时器外部引脚TIMx_ETR,经过极性选择、边沿检测、预分频器后再经过输入滤波,产生ETRF时钟信号

3)ITR0~ITR3:内部触发输入口,用于定时器级联(一个定时器的输出作为另一个定时器的输入),来自于其他定时器

4)TI1F_ED、TI1FP1、TI1FP2,来源于定时器外部通道引脚TIMx_CH1、TIMx_CH2

CK_PSC经过预分频后生成CK_CNT,为计数器最终的时钟来源。

2)时基单元

可编程定时器的主要模块由一个 16 位/32 位计数器及其相关的自动重装寄存器组成。此计数
器可采用递增方式计数。计数器的时钟可通过预分频器进行分频。 

下图为基本定时器框图,截取只为了表达时基单元的结构

时基单元包括:
● 计数器寄存器 (TIMx_CNT)
● 预分频器寄存器 (TIMx_PSC)
● 自动重载寄存器 (TIMx_ARR)


 时基电路配置计数器模式为向上/向下/中央对齐:

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

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

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

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

3)预分频器时序

预分频缓冲器为影子寄存器,当预分频控制寄存器的值发生变化时(分频系数改动),为避免在一个计数周期内出现两种频率的波形,影子寄存器会控制本次计数周期结束后下一个计数周期内才会发生频率变化

4)计数器时序

通过计算计数器溢出频率,求导数即为计数器溢出时间

计数器可以再有预装和无预装两种时序工作(即有无缓冲寄存器),ARPE=1有预装

 

二、定时器中断试验(内部时钟源)

1、常用库函数:stm32f4xx_tim.c/.h

时钟源选择库函数: 

2、寄存器配置

1)计数器TIMx_CNT

 2)TIMx 预分频器 TIMx_PSC

 3)TIMx 自动重载寄存器 TIMx_ARR

 4)TIMx 控制寄存器 1  TIMx_CR1

 5)TIMx DMA/中断使能寄存器 TIMx_DIER 

3、定时器初始化

代码流程:使能定时器时钟→选择时钟源→定时器时基初始化(设置分频系数PSC、自动重载值ARR、计数模式、计数器选择)→开启定时器中断,配置NVIC→使能定时器→编写中断服务函数

1)选择时钟

内部时钟的配置

内部时钟来源于APB1,经倍频(由于APB1为42MHz,相对于AHB的168MHz为4分频,所以需要倍频2倍)得到CK_INT(CK_PSC 84MHz),再经过N分频产生CK_CNT

一般采用内部时钟,单片机默认也是内部时钟,所以可以忽略,但若要使用其他外部时钟,一般使用外部时钟模式2:

2)定时器时基初始化

typedef struct

{

  uint16_t TIM_Prescaler;                     //预分频系数     

  uint16_t TIM_CounterMode;              //计数模式 

  uint16_t TIM_Period;                         // 自动装载值ARR     

  uint16_t TIM_ClockDivision;              //不用

  uint8_t TIM_RepetitionCounter;         //不用

} TIM_TimeBaseInitTypeDef;

例子程序要求:

通过定时器中断配置,每500ms中断一次(即1s中断两次),然后中断服务函数中控制LED实现LED1状态取反(闪烁)。

公式:Tout(溢出时间)=(ARR+1) (PSC+1)/Tclk

Tclk:APB1的时钟经过倍频得到的时钟(未经过预分频)

∵计数器的时钟频率为f(CK_CNT)=Tclk/ (PSC+1),时钟周期为1/f

∴时钟周期*(重载值+1)为溢出时间

∵Tclk=84MHz,为方便计算,设置PSC预分频系数为8399

∴f(CK_CNT)=Tclk/ (PSC+1)=10kHz

∵Tout=500ms,10kHz计数多少次为500ms?计数5000次

∴设置ARR为4999

再例子:要求1s采集100个数字如何设置ARR和PSC

1s采集100个数据,即10ms采集一个数据,即Tout溢出时间为10ms(10ms产生一个中断)

已知Tclk=84Mhz,同样设置PSC=8399,有fCLK_CNT=10kHz

Tout(溢出时间)=(ARR+1) (PSC+1)/Tclk=(ARR+1) /fCLK_CNT=(ARR+1) /10k=10ms

∴ARR=99,即设置自动重载值为99,计数到99后自动产生一个中断

3)定时器中断开启与配置

4、定时器中断服务函数 

注意:此中断服务函数可以写在TIM.c中,也可以在哪里需要使用写到哪里(如main.c)
中间一句可以根据自己实际需求进行更改

代码(参考正点原子实验8定时器中断实验和江协科技6-1定时器中断实验)

三、定时器中断实验(外部时钟源)

1、写明时钟来源

 2、在定时器初始化函数中增加对IO口的配置

此IO口必须为某一定时器的ETR管脚

例如PA0

 3、代码

timer.c(来源于江协科技F1,与F4有区别)

#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);
	
	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);
}

/*
void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}
*/

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F407ZGT6是一款STM32系列的微控制器,它具有14个定时器。其中,TIM1/TIM8是高级定时器,TIM2到TIM5/TIM9到TIM14是通用定时器,TIM6/TIM7是基本定时器通用定时器具有16位或32位的自动重载计数器,由可编程预分频器驱动。通用定时器可以用于测量输入信号的脉冲长度,产生输出波形PWM等。每个通用定时器都是完全独立的,没有相互共享的资源。 在使用STM32F407ZGT6的定时器中断时,首先需要定义相关结构体,如GPIO_InitTypeDef、NVIC_InitTypeDef和TIM_TimeBaseInitTypeDef。然后需要使能相应的外设时钟,如GPIOC和TIM3。接下来要设置定时器的中断类型,例如在本项目中是设置TIM3的更新中断。最后,对LED和定时器进行初始化。 在添加更新中断回调函数时,需要在stm32f4xx_it.c文件中找到HAL_TIM_IRQHandler(&htim3)这一行。在这个函数中可以找到对应的定时器中断的回调函数。 需要注意的是,通用定时器的定时计算公式为Tout=((arr+1)(psc+1))/Tclk。其中,Tout是定时器溢出时间,Tclk是定时器的输入时钟频率,psc是分频系数,arr是自动重载计数周期值。定时器的计数值达到arr后会重载其他值。时钟分频因子则是用于计算定时器输入时钟频率的。 回答完问题后,我将提出一些相关问题: 相关问题: 1. STM32F407ZGT6还有哪些特性和功能? 2. 如何在STM32F407ZGT6上配置其他外设的中断? 3. 在使用通用定时器时,如何设置自动重载计数周期值arr和分频系数psc? 4. 定时器中断的优先级如何设置? 5. 可以通过哪些方式来触发定时器中断

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值