学习STM32入门基本定时器(六)笔记

一、定时器的分类

 STM32F1 系列中,除了互联型的产品,共有 8 个定时器,分为基本定时器,通用定时器和高级定时器。

基本定时器 TIM6 和 TIM7 是一个 16 位的只能向上计数的定时器,只能定时,没有外部 IO。

通用定时器 TIM2/3/4/5 是一个 16 位的可以向上/下计数的定时器,可以定时,可以输出比较,可以输入捕捉,每个定时器有四个外部 IO。

高级定时器 TIM1/8是一个 16 位的可以向上/下计数的定时器,可以定时,可以输出比较,可以输入捕捉,还可以有三相电机互补输出信号,每个定时器有 8 个外部 IO。

二、基本定时器

2.1 简介

      STM32F103 有两个基本定时器 TIM6 TIM7,它们的功能完全相同,资源是完全独立的, 可以同时使用。其主要特性如下:16 位自动重载递增计数器,16 位可编程预分频器,预分频系数 1~65536,用于对计数器时钟频率进行分频,还可以触发 DAC 的同步电路,以及生成中断 /DMA 请求。

2.2 基本定时器框图

① 时钟源

       定时器的核心就是计算器,要实现计数功能,首先要给它一个时钟源。基本定时器时钟挂 载在 APB1 总线,所以它的时钟来自于 APB1 总线,但是基本定时器时钟不是直接由 APB1 总 线直接提供,而是先经过一个倍频器。

② 控制器

控制器除了控制定时器复位、使能、计数等功能之外,还可以用于触发 DAC 转换。

③ 时基单元

时基单元包括:计数器寄存器(TIMx_CNT)、预分频器寄存器(TIMx_PSC)、自动重载寄存器 (TIMx_ARR)(自动重装载寄存器ARR是一个16位的寄存器,这里面装的计数器能计数的最大数值。当计数到这个值的时候,如果使能了中断,定时器就会产生溢出中断。) 。基本定时器的这三个寄存器都是 16 位有效数字,即可设置值范围是 0~65535。

影子寄存器是一个实际起作用的寄存器,不可直接访问。举个例子:我们可以把预分频系数写入预分频器寄存器(TIMx_PSC), 但是预分频器寄存器只是起到缓存数据的作用,只有等到更新事件发生时,预分频器寄存器的 值才会被自动写入其影子寄存器中,这时才真正起作用。

2.3 TIM6 / TIM7寄存器

控制寄存器 1(TIMx_CR1)

注意:位 0(CEN)用于使能或者禁止计数器,置 1工作,置 0停止。位 7(APRE)用于控制自动重载寄存器 ARR 是否具有缓冲作用,置 1,ARR 起缓冲作用,即只有在更新事件发生时才会把 ARR 的值写入其影子寄存器里;置 0,那么修改自动重载寄存器的值,该值会马上被写入其影子寄存器中,从而立即生效。

DMA/中断使能寄存器(TIMx_DIER)

注意:位 0(UIE)用于使能或者禁止更新中断;位 8(UDE)用于使能或者禁止更新 DMA 请求。

状态寄存器(TIMx_SR)

计数器寄存器(TIMx_CNT)

该寄存器位[15:0]就是计数器的实时的计数值。

预分频寄存器(TIMx_PSC)

       该寄存器是 TIM6/TIM7 的预分频寄存器,比如我们要 7200 分频,就往该寄存器写入 7199。 注意这是 16 位的寄存器,写入的数值范围是 0 到 65535,分频系数范围:1 到 65536。

自动重载寄存器(TIMx_ARR)

       计数器的值会和 ARR 寄存器影子寄存器进行比较,当两者相等,定时器就会溢出,从而发生更新事件,如果打开更新中断,还会发生更 新中断。

2.4 定时器中断实验配置步骤

2.5 相关HAL库函数介绍

HAL_TIM_Base_Init 函数

其声明如下:HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim);

用于初始化定时器。

函数形参:

形参 1 是 TIM_HandleTypeDef 结构体类型指针变量(亦称定时器句柄),结构体定义如下:

typedef struct 
{ 
 TIM_TypeDef *Instance;           /* 外设寄存器基地址 */ 
 TIM_Base_InitTypeDef Init;       /* 定时器初始化结构体*/ 
 HAL_TIM_ActiveChannel Channel;   /* 定时器通道 */ 
 DMA_HandleTypeDef *hdma[7];      /* DMA 管理结构体 */ 
 HAL_LockTypeDef Lock;            /* 锁定资源 */ 
 __IO HAL_TIM_StateTypeDef State; /* 定时器状态 */ 
}TIM_HandleTypeDef; 

TIM_Base_InitTypeDef 这个结构体类型定义:

typedef struct
{ 
 uint32_t Prescaler;            /* 预分频系数 */ 
 uint32_t CounterMode;          /* 计数模式 */ 
 uint32_t Period;               /* 自动重载值 ARR */ 
 uint32_t ClockDivision;        /* 时钟分频因子 */ 
 uint32_t RepetitionCounter;    /* 重复计数器 */ 
 uint32_t AutoReloadPreload;    /* 自动重载预装载使能 */ 
} TIM_Base_InitTypeDef; 

HAL_TIM_Base_Start_IT 函数

HAL_TIM_Base_Start_IT 函数是更新定时器中断和使能定时器的函数。

HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim); 

该函数调用了__HAL_TIM_ENABLE_IT 和__HAL_TIM_ENABLE 两个函数宏定义,分别 是更新定时器中断和使能定时器的宏定义。

__HAL_TIM_ENABLE_IT(htim, TIM_IT_UPDATE); /* 使能句柄指定的定时器更新中断 */ 
__HAL_TIM_DISABLE_IT (htim, TIM_IT_UPDATE); /* 关闭句柄指定的定时器更新中断 */ 
__HAL_TIM_ENABLE(htim);                      /* 使能句柄 htim 指定的定时器 */ 
__HAL_TIM_DISABLE(htim);                    /* 关闭句柄 htim 指定的定时器 */ 

三、实验

        利用基本定时器 TIM6/7 定时 1s,1s 时间到 LED 翻转一次。基本定时器是单片机内部的资源,没有外部 IO,不需要接外部电路,现只需要一个 LED 即可。

bsp_TiMbase.h

#ifndef __BSP_TIMEBASE_H
#define __BSP_TIMEBASE_H
 
 
#include "stm32f10x.h"
 
 
/********************基本定时器TIM参数定义,只限TIM6、7************/
#define BASIC_TIM6 // 如果使用TIM7,注释掉这个宏即可
 
#ifdef  BASIC_TIM6 // 使用基本定时器TIM6
#define            BASIC_TIM                   TIM6
#define            BASIC_TIM_APBxClock_FUN     RCC_APB1PeriphClockCmd
#define            BASIC_TIM_CLK               RCC_APB1Periph_TIM6
#define            BASIC_TIM_Period            (1000-1)
#define            BASIC_TIM_Prescaler         71
#define            BASIC_TIM_IRQ               TIM6_IRQn
#define            BASIC_TIM_IRQHandler        TIM6_IRQHandler
 
#else  // 使用基本定时器TIM7
#define            BASIC_TIM                   TIM7
#define            BASIC_TIM_APBxClock_FUN     RCC_APB1PeriphClockCmd
#define            BASIC_TIM_CLK               RCC_APB1Periph_TIM7
#define            BASIC_TIM_Period            1000-1
#define            BASIC_TIM_Prescaler         71
#define            BASIC_TIM_IRQ               TIM7_IRQn
#define            BASIC_TIM_IRQHandler        TIM7_IRQHandler
 
#endif
/**************************函数声明********************************/
 
void BASIC_TIM_Init(void);
 
 
#endif	/* __BSP_TIMEBASE_H */
 
 

bsp_TiMbase.c

 
// 基本定时器TIMx,x[6,7]定时初始化函数
 
#include "bsp_TiMbase.h" 
 
// 中断优先级配置
static void BASIC_TIM_NVIC_Config(void)
{
    NVIC_InitTypeDef NVIC_InitStructure; 
    // 设置中断组为0
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);		
		// 设置中断来源
    NVIC_InitStructure.NVIC_IRQChannel = BASIC_TIM_IRQ ;	
		// 设置主优先级为 0
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;	 
	  // 设置抢占优先级为3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;	
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}
 
/*
 * 注意:TIM_TimeBaseInitTypeDef结构体里面有5个成员,TIM6和TIM7的寄存器里面只有
 * TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的时候只需初始化这两个成员即可,
 * 另外三个成员是通用定时器和高级定时器才有.
 *-----------------------------------------------------------------------------
 *typedef struct
 *{ TIM_Prescaler            都有
 *	TIM_CounterMode			     TIMx,x[6,7]没有,其他都有
 *  TIM_Period               都有
 *  TIM_ClockDivision        TIMx,x[6,7]没有,其他都有
 *  TIM_RepetitionCounter    TIMx,x[1,8,15,16,17]才有
 *}TIM_TimeBaseInitTypeDef; 
 *-----------------------------------------------------------------------------
 */
 
 
static void BASIC_TIM_Mode_Config(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
		
		// 开启定时器时钟,即内部时钟CK_INT=72M
    BASIC_TIM_APBxClock_FUN(BASIC_TIM_CLK, ENABLE);
	
		// 自动重装载寄存器的值,累计TIM_Period+1个频率后产生一个更新或者中断
    TIM_TimeBaseStructure.TIM_Period = BASIC_TIM_Period;	
 
	  // 时钟预分频数为
    TIM_TimeBaseStructure.TIM_Prescaler= BASIC_TIM_Prescaler;
	
		// 时钟分频因子 ,基本定时器没有,不用管
    //TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
		
		// 计数器计数模式,基本定时器只能向上计数,没有计数模式的设置
    //TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; 
		
		// 重复计数器的值,基本定时器没有,不用管
		//TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
	
	  // 初始化定时器
    TIM_TimeBaseInit(BASIC_TIM, &TIM_TimeBaseStructure);
		
		// 清除计数器中断标志位
    TIM_ClearFlag(BASIC_TIM, TIM_FLAG_Update);
	  
		// 清除计数器中断标志位
    TIM_ITConfig(BASIC_TIM,TIM_IT_Update,ENABLE);
		
		// 使能计数器
    TIM_Cmd(BASIC_TIM, ENABLE);	
}
 
void BASIC_TIM_Init(void)
{
	BASIC_TIM_NVIC_Config();
	BASIC_TIM_Mode_Config();
}
/*********************************************END OF FILE**********************/

main.c

 
// 基本定时器TIMx,x[6,7]定时应用
#include "stm32f10x.h"
#include "bsp_led.h"
#include "bsp_TiMbase.h"
 
volatile uint32_t time = 0; // ms 计时变量 
 
/**
  * @brief  主函数
  * @param  无  
  * @retval 无
  */
int main(void)
{
	/* led 端口配置 */ 
	LED_GPIO_Config();
	
	BASIC_TIM_Init();
	
  while(1)
  {
    if ( time == 1000 ) /* 1000 * 1 ms = 1s 时间到 */
    {
      time = 0;
			/* LED1 取反 */      
			LED1_TOGGLE; 
    }        
  }
}
/*********************************************END OF FILE**********************/

  • 20
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值