零基础STM32单片机编程入门(六)定时器TIMER详解及实战含源码视频

一.概要

定时器的简介
定时器就是计数器,应用在我们生活的方方面面,比如有闹钟、计时器等。在STM32F103C8T6定时器分为2类,即高级控制定时器(TIM1)、通用定时器(TIM2,TIM3,TIM4),要学会定时器要懂得分频设置、计数器设置。

1、高级控制定时器(TIM1)
高级控制定时器(TIM1)由一个16位的自动装载计数器组成,它由一个可编程的预分频器驱动。它适合多种用途,包含测量输入信号的脉冲宽度(输入捕获),或者产生输出波形(输出比较、PWM、嵌入死区时间的互补PWM等)。使用定时器预分频器和RCC时钟控制预分频器,可以实现脉冲宽度和波形周期从几个微秒到几个毫秒的调节。高级控制定时器(TIM1)和通用定时器(TIM2,TIM3,TIM4)是完全独立的,它们不共享任何资源。它们可以同步操作

2、通用定时器(TIM2,TIM3,TIM4)
通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成。它适用于多种场合,包括测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)。使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。每个定时器都是完全独立的,没有互相共享任何资源。它们可以一起同步操作

我们以通用定时器为例,通用定时器能应付我们一般使用场景,后面对定时器的内部构造,配置使用,实际使用进行一一讲解

二.通用定时器内部结构

通用定时器由4部分组成:①时基单元 ②时钟源 ③输入捕获 ④输出比较。

在这里插入图片描述

1.时基单元

可编程通用定时器的主要部分是一个16位计数器和与其相关的自动装载寄存器。这个计数器可以向上计数、向下计数或者向上向下双向计数。此计数器时钟由预分频器分频得到。 计数器、自动装载寄存器和预分频器寄存器可以由软件读写,在计数器运行时仍可以读写。
在这里插入图片描述

时基单元包含:
● 计数器寄存器(TIMx_CNT) :向上计数、向下计数或者中心对齐向计数,最常用是向上对齐。
● 预分频器寄存器 (TIMx_PSC) :可将时钟频率按1到65536之间的任意值进行分频,可在运行时改变其设置值。
● 自动装载寄存器 (TIMx_ARR) :
在向上计数模式中,计数器从0计数到自动装载寄存器值(TIMx_ARR计数器的内容),然后重新从0开始计数并且产生一个计数器溢出事件。
ARPE=0,当ARR值被修改时,同时马上更新影子寄存器的值;ARPE=1,当ARR值被修改时,必须在下一次事件UEV发生后才能更新影子寄存器的值,当计数器产生溢出条件时,产生更新事件。

自动装载寄存器是预先装载的,写或读自动重装载寄存器将访问预装载寄存器。根据在
TIMx_CR1寄存器中的自动装载预装载使能位(ARPE)的设置,预装载寄存器的内容被立即或在每次的更新事件UEV时传送到影子寄存器。当计数器达到溢出条件(向下计数时的下溢条件),产生更新事件。

在这里插入图片描述
上图中圈出来带了阴影的寄存器表示该寄存器存在影子寄存器,这些有阴影的寄存器在物理上对应了两个寄存器,一个是开放出来给程序员可以写入和读出的预装载寄存器(preloadregister),比如ARR,PSC,捕获/比较等寄存器;另一个并没有开放出来,即程序员看不见的、但在操作中真正起作用的影子寄存器(shadowregister)。
设计预装载寄存器 (preloadregister) 和影子寄存器 (shadowregister)的好处:
每次发生更新事件(UEV)时,所有真正起作用的影子寄存器(shadowregister)可以同时被更新为预装载寄存器 (preloadregister)里面的值,这样可以保证多个通道的操作能够准确同步;如果没有影子寄存器(shadowregister),或者预装载寄存器 (preloadregister) 和影子寄存器 (shadowregister)是直通的,当软件更新了预装载寄存器 (preloadregister),也就立即更新了影子寄存器 (shadowregister),由于软件不能同时更新多个影子寄存器,这就会导致多个通道的时序不能同步。

ARPE=0,当ARR值被修改时,同时马上更新影子寄存器的值;
ARPE=1,当ARR值被修改时,必须在下一次事件UEV发生后才能更新影子寄存器的值
ARR寄存器工作模式如下:
在这里插入图片描述

2.时钟源

计数器时钟可由下列时钟源提供:
① 内部时钟 (TIMxCLK)
② 外部时钟模式 1 :外部输入脚 (TIx)
③ 外部时钟模式 2 :外部触发输入 (ETR)
④ 内部触发输入 (ITRx) :使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器 Timer1 而作为另一个定时器 Timer2 的预分频器。

我们常用内部时钟 (TIMxCLK)作为时钟源

在这里插入图片描述

3.输入捕获

输入捕获就是通过检测捕获通道上(TI1,TI2,TI3,TI4)的边沿信号。在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCR)里面,完成一次捕获,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数。
在这里插入图片描述

4.输出比较

输出比较可以通过比较CNT(计数器)与CCR(捕获/比较)寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形。
在这里插入图片描述

三.通用定时器内部特色

在这里插入图片描述

四.CubeMX配置一个TIME定时1ms中断例程

1.硬件准备

STLINK接STM32F103C8T6小系统板,STLINK接电脑USB口。

在这里插入图片描述

2.创建工程

打开STM32CubeMX软件,新建工程
在这里插入图片描述
Part Number处输入STM32F103C8,再双击就创建新的工程
在这里插入图片描述
配置下载口引脚
在这里插入图片描述
配置外部晶振引脚
在这里插入图片描述

可以查看STM32F103C8T6小系统板原理图,PC13连接LED灯,所以配置PC13为GPIO输出

在这里插入图片描述
配置系统主频
在这里插入图片描述
配置TIM3通用定时器,1ms溢出中断事件
TIM3内部时钟是72MHZ,72分频就是1MHZ,计数1000次中断一次,计数时间就是1ms。
在这里插入图片描述
配置中断
在这里插入图片描述
配置工程文件名,保存路径,KEIL5工程输出方式
在这里插入图片描述
生成工程
在这里插入图片描述
用Keil5打开工程
在这里插入图片描述

3.添加代码和调试

main中添加代码,启动定时器3,并启动中断。
在这里插入图片描述
添加HAL_TIM_PeriodElapsedCallback函数,这个函数会在定时器1ms中断产生的时候在中断服务程序中自动调用。我们在里面增加计数到500次,那就是500ms时LED翻转输出,这样LED灯就是闪烁。
在这里插入图片描述
进入调试模式,在HAL_TIM_PeriodElapsedCallback函数中打断点,全速运行,每500ms,就会进入断点一次,调试就完成了。
在这里插入图片描述

4.重点代码


uint16_t TimeCounter;
//定时器溢出中断回调函数,1ms进入一次
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* Prevent unused argument(s) compilation warning */
	TimeCounter++;
	if(TimeCounter>=500)//计数到500ms
	{
		TimeCounter=0;
    HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);//LED闪烁
	}

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_TIM_PeriodElapsedCallback could be implemented in the user file
   */
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();//8M外部晶振,72M主频

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */
 if (HAL_TIM_Base_Start_IT(&htim3) != HAL_OK)//启动TIM3,并启动中断
 {
	 while(1);
 }
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */
}
void MX_TIM3_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 71;//72分频
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;//向上计数
  htim3.Init.Period = 999;//计数1000次产生中断
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;//定时器内部时钟,时钟源就是72M
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }

}

五.CubeMX工程源代码下载

链接:https://pan.baidu.com/s/15llECbVUiWYKsRRt4vItSQ
提取码:jchj
如果链接失效,可以联系博主给最新链接

程序下载下来之后解压就行

六.讲解视频链接地址

定时器讲解

七.小结

通过定时器周期性地产生中断信号,可以实现系统定时和时间戳等功能。例如,在智能家居系统中,可以使用定时器控制各种设备的开关,在工业控制系统中,定时器可以用于检测传感器数据并执行相应的动作,定时器还可以配合PWM模块实现对电机等设备的精确控制。通过定时器产生固定频率的方波信号,然后使用PWM模块将其转化为可调节占空比的脉冲信号,从而实现对电机速度和输出功率的控制。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值