STM32之定时器

news2024/9/28 13:25:39

定时器

软件定时

缺点:不精确,占用CPU资源

定时器工作原理

  • 使用精准的时基,通过硬件的方式,实现定时功能。

  • 定时器的核心是计数器。

通用定时器框图

该框图主要分成四部分:时钟产生器、时基单元、输入捕获、输出比较

时钟产生器

STM32通用定时器有四种时钟源:

内部时钟(CK_INT)

外部时钟模式1:外部触发输入(TIMx_ETR)

内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器

外部时钟模式2:外部输入引脚

时基单元

输入捕获、输出比较

定时器分类

STM32F103C8T6只有TIM1~TIM4

高级定时器(TIM1、TIM8)

除具备通用定时器所有功能外,还具备带死区控制的互补信号输出刹车输入等功能可用于电机控制、数字电源设计等。

基本定时器(TIM6、TIM7)

没有输入输出通道,常用作时基,即定时功能

通用定时器(TIM2~TIM5)

具有多路独立通道,可用于输入捕获/输出比较,PWM生成,也可用作时基

特点

  • 位于低速的APB1总线上(APB1)

  • 16位向上、向下、向上/向下(中心对齐)自动装载计数器(TIMx_CNT)

  • 16 位可编程(可以实时修改)预分频器(TIMx_PSC),计数器时钟频率的分频系数为 1~65535

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

  1. 输入捕获

  1. 输出比较

  1. PWM 生成(边缘或中间对齐模式)

  1. 单脉冲模式输出

  • 可使用外部信号(TIMx_ETR)控制定时器和定时器互连(可以用 1个定时器控制另外一个定时器)

  • 如下事件发生时产生中断/DMA:

  1. 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)

  1. 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)

  1. 输入捕获

  1. 输出比较

  1. 支持针对定位的增量(正交)编码器和霍尔传感器电路

  1. 触发输入作为外部时钟或者按周期的电流管理

定时器时钟源

定时器计数模式

计数模式

计数器溢出值

计数器重装值

向上计数

CNT = ARR

CNT = 0

向下计数

CNT = 0

CNT = ARR

中心对齐计数

CNT = ARR- 1

CNT = ARR - 1

CNT = 1

CNT = 0

向上计数

计数器从0开始计数(递增),计数到自动加载值(TIMx_ARR)后产生一个计数器溢出事件并重新从0开始计数。

向下计数

计数器从自动加载值(TIMx_ARR)开始计数(递减),计数到0后产生一个计数器溢出事件并重新从自动加载值(TIMx_ARR)开始计数。

中心对齐计数

计数器从0开始计数(递增),计数到自动加载值(TIMx_ARR) - 1后产生一个计数器溢出事件并从自动加载值(TIMx_ARR)开始计数(递减),计数到1后产生一个计数器溢出事件并重新从0开始计数。

定时器计数溢出计算公式

72M = 72 00 00 00,算出来的定时时间(Tout)是以s为单位

定时器点灯

通过定时器2产生溢出中断,在中断处理函数中每隔1s翻转一次LED1的电平。

使用STM32CubeMX创建工程

配置SYS

配置RCC

配置TIM2

时钟来源选择中间时钟,打开定时器2中断

配置定时方式,定时时间

配置NVIC

配置GPIO

配置工程名称、工程路径

选择固件库

生成工程

main函数编写

找到中断处理函数

  1. 在中断相关文件中找到TIM2_IRQHandler()

  1. 找到HAL_TIM_IRQHandler()

  1. 找到HAL_TIM_PeriodElapsedCallback(),它是一个虚函数,在main.c文件中编写它的函数体

编写main.c

  1. 编写定时器2中断处理函数的函数体

  1. 在main函数中启动定时器2(HAL_TIM_Base_Start_IT(&htim2);)

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "tim.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

//编写定时器2中断处理函数的函数体
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    //判断是否是定时器2产生的中断
    if(htim2.Instance == TIM2){
        HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_9);
    }
}

/* 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();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */

  //启动定时器2
  HAL_TIM_Base_Start_IT(&htim2);

  /* USER CODE END 2 */

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

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/381692.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springboot通过aop实现全局日志(是否自定义注解都可以)

内容参考自以下两个链接1、springboot中使用AOP切面完成全局日志_aop全局日志_邹飞鸣的博客-CSDN博客使用AOP记录日志_aop日志_trusause的博客-CSDN博客第一个链接思路很清晰,讲的也很详细,第二个链接讲了自定义注解为了便于自己理解做了以下整理目录 1.aspectj基本概念 2.添加…

闪光桐人の实习日记(2023年2月27日-3月3日)

前往闪闪の小窝以获得更好的阅读和评论体验 文章目录2023年3月2日(测试流程)为什么是什么如何进行2023年3月1日(消息队列MQ)什么是消息队列为什么要使用消息队列消息队列(kafka)的优势关键信息SpringBoot整…

LeetCode题目笔记——448. 找到所有数组中消失的数字

文章目录题目描述题目链接题目难度——简单方法一:使用额外空间,字典代码/Python代码/C方法二:进阶,原地修改代码/C代码/C总结题目描述 这好像是一到经典的面试题 给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间…

遮挡检测--基于角度的遮挡检测方法

文章目录1基于角度的遮挡检测方法2遮挡检测遍历方法2.1方法1--自适应径向扫描方法2.2方法2--螺旋扫描法参考1基于角度的遮挡检测方法 在基于角度的方法中,通过依次分析DSM中沿径向方向的投影光线的角度来识别遮挡。定义α\alphaα角:DSM三维点与相机中心…

解决Windows虚拟机启动资源占用过多

由于虚拟机中的Windows一般是指定版本的,创建后,其自身仍在不断自动更新,因此这里我们禁用两个服务,以后启动Windows之后就不会占用太多资源了: 禁用setuphost.exe禁用.net runtime optimization 文章目录1. 禁用setu…

分布式定时任务-学习笔记

1 发展历程 1.1 Linux命令-CronJob 只能控制单台机器 1.2 任务调度-Quartz 单任务极致控制 1.3 分布式定时任务 1.3.1 定时任务 系统为了自动完成特定任务,实时、延时、周期性完成任务调度的过程 1.3.2 分布式定时任务 把分散的、可靠性差的定时任务纳入统一的平…

VScode下 ESP32 下载程序

ESP32-S3 下载方式可以通过UART0 下载,USB 下载,JTAG下载,还可以使用WIFI进行远程OTA升级程序。插件底栏按键介绍:①选择串口端口号,如COM3; ②选择芯片型号; ③工程idf设置,相当于menuconfig; …

Redis缓存雪崩、缓存击穿、缓存穿透

用户的数据一般都是存储于数据库,数据库的数据是落在磁盘上的,磁盘的读写速度可以说是计算机里最慢的硬件了。 当用户的请求,都访问数据库的话,请求数量一上来,数据库很容易就奔溃的了,所以为了避免用户直…

【Java】Spring Boot 日志文件

文章目录SpringBoot日志文件1. 日志有什么用2. 日志怎么用3. 自定义日志打印3.1 在程序中得到日志对象3.2 使用日志对象打印日志4. 日志级别4.1 日志级别有什么用?4.2 日志级别的分类与使用5. 日志持久化6. 更简单的日志输出--lombok6.1 添加 lombok 依赖6.2 输出日…

操作系统真相还原——第6章内存管理系统

第八章 内存管理系统 makefile 编译整个项目,如果改变局部关系,只靠人工难以维护文件间的依赖关系,所以通过make程序进行处理 makefile文件是make程序的搭档:发现某个文件更新后,只编译该文件和受该文件影响的相关文…

为什么95%的Java程序员人,都是用不好Synchronized?

Synchronized锁优化 jdk1.6对锁的实现引入了大量的优化,如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁等技术来减少锁操作的开销。 锁主要存在四中状态,依次是:无锁-> 偏向锁 -> 轻量级锁 -> 重量级锁,他们…

upload-labs通关详细教程

文章目录文件上传要点1、前端验证绕过做题步骤源码分析2、Content-Type方式绕过做题步骤源码分析3、黑名单绕过做题步骤源码分析4、.htaccess文件绕过简介做题步骤源码分析5、后缀大小写绕过简介做题步骤源码分析6、文件后缀(空)绕过简介做题步骤源码分析…

CAN工具-VSpy(ValueCAN) - Panel面板(续)

继续上次的Panel面板介绍!!!7. LED 控件LED控件可以用作指示器。在Graphical Panels中选中该控件,在界面右侧侧拉框的Properties中可设置LED控件的通用属性。LED控制属性LED On Color:双击打开标准的Windows颜色选择器…

Vue 3.0 学习笔记之基础知识

系列文章目录 提示:阅读本章之前,请先阅读目录 文章目录系列文章目录前言Vue 3.0 创建与Vue2.0对比的变化关闭语法检查setup 组合式函数compositions前言 Vue 3.0 创建 与Vue2.0对比的变化 关闭语法检查 lintOnSave: false setup 组合式函数compositions…

Git 初体验 (处理 .ssh 文件的相关问题)

目录前沿环境入门教程出现的问题问题 1 :C 盘用户文件中找不到 .ssh 文件问题 2 : 在 clone 远程仓库文件时报错问题3 : 第一次从 Gitee clone 项目时会弹出一个 Git 窗口,要你输入用户和密码获取 credential (可以信任的证明)自我实践总结引用前沿 很早前安装了 G…

二叉树——删除二叉搜索树中的节点

删除二叉搜索树中的节点 链接 给定一个二叉搜索树的根节点 root 和一个值 key,删除二叉搜索树中的 key 对应的节点,并保证二叉搜索树的性质不变。返回二叉搜索树(有可能被更新)的根节点的引用。 一般来说,删除节点可…

2022_SPL_CMINet

Cross-Stage Multi-Scale Interaction Network for RGB-D Salient Object Detection 用于rgb-d显着目标检测的跨阶段多尺度交互网络 目录 文章目录 前言 一、引言 二、提出的方法 A.概述 感觉有点乱,没看太懂,没关系,我们接着往下看 …

Postman 实现 UI 自动化测试

看到这篇文章的标题,是不是有小伙伴会感到惊讶呢? Postman 不是做接口测试的吗?为什么还能做 UI 自动化测试呢? 其实,只要你了解 Selenium 的运行原理,就可以理解为什么 Postman 也能实现 UI 自动化测试了…

EPICS motor模块

一、概要 1) 在EPICS motor模块中的是什么并且它为了什么? 2) 支持的电机控制器和模型 3)电机记录特性 4)配置示例 5)反馈 6) 重试 7) 回程差矫正 8)发行 二、术…

Linux上的校验和验证

校验和(checksum)程序用来从文件中生成相对较小的唯一密钥。我们可以重新计算该密钥,用以检查文件是否发生改变。修改文件可能是有意为之(添加新用户会改变密码文件),也可能是无意而为(从CD-ROM…