当前位置: 首页 > news >正文

32HAL——定时器总篇

一、时钟树与时钟源

二、定时器-基本定时功能

cubemx配置

Prescaler(预分频):7200-1表示7200分频,即72000000/7200=10000 表示频率为10000Hz,即1秒计数10000次;

Counter Preiod(重装载值):10000-1表示设置重装载值为10000,即当计数器计数到9999时就清0,表示计时1秒钟

记得打开中断

示例程序

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
char data[] = "😊😊❤️❤️";
//定时器回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {if (htim == &htim5) {HAL_UART_Transmit_IT(&huart2, (uint8_t *)data, strlen(data));}
}
/* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 */int counter = 10;char message[50];/* 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_TIM5_Init();MX_USART2_UART_Init();/* USER CODE BEGIN 2 */HAL_TIM_Base_Start_IT(&htim5);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){counter = __HAL_TIM_GET_COUNTER(&htim5);        //获取计数值HAL_Delay(99);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

该程序表示每秒钟通过串口发送“😊😊❤️❤️”。

三、外部中断与循迹模块(TCRT5000)

cubemx配置

Clock Source(时钟源):ETR-外部触发输入,即计数PA0引脚的上升沿或下降沿的数目

Clock Polarity: 时钟极性-选择计数上升沿还是下降沿

打开中断

示例程序

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2025 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 "i2c.h"
#include "tim.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "oled.h"
#include <string.h>
#include <stdio.h>
/* 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 */
#define Period  10    // 要与MX中设置的Counter Period(自动重装载值)相同
#define Width   1.5   // 每产生一次脉冲经过的黑白条物理长度  单位:cm
/* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV */
/*** 记录定时器更新中断的次数* stm32在配置tim后会直接触发一次中断* 因而初始化为-1,抵消掉这次中断*/
int loop = -1;
/* 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 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {if (htim == &htim2) {//每次重新计数时将loop加1loop += 1;}
}
/* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 */int counter = 0;      //用于获取当前的计数值char message[50];int lastCounter = 0;  //用于存储上次的计数值float speed = 0.0f;      //计算得出的速度/* 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_I2C2_Init();MX_TIM2_Init();/* USER CODE BEGIN 2 */HAL_Delay(20);OLED_Init();HAL_TIM_Base_Start_IT(&htim2);  //开启定时器/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){OLED_NewFrame();// 总计数值 = 更新中断次数 * 自动重装载值 + 当前计数值counter = loop * Period + __HAL_TIM_GET_COUNTER(&htim2);sprintf(message, "counter: %d", counter);OLED_PrintString(0, 0, message, &font16x16, OLED_COLOR_NORMAL);// 简易的速度计算speed = ((counter - lastCounter) * Width) / 0.1;lastCounter = counter;sprintf(message, "speed: %.1fcm/s", speed);OLED_PrintString(0, 16, message, &font16x16, OLED_COLOR_NORMAL);OLED_ShowFrame();HAL_Delay(100);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

该程序介绍了循迹模块TCRT5000基本用法,并计数电平变化

四、定时器从模式(Slave Mode)

从模式包含了以下3种模式 Reset Mode-复位模式 Gate Mode-门模式 Trigger Mode -触发模式

cubemx配置

这里使用触发模式演示,触发模式常常搭配单脉冲模式工作,即开始计时后,到达重装载值便停止计时。

开启中断

示例程序

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2025 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 "usart.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <string.h>
#include <stdio.h>
/* 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 */
char UpdateMessage[50] = "自动重装载😍";
char SlaveModeMessage[50] = "从模式触发😢";void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {//从模式触发// if (htim == &htim2) {//   if (__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_TRIGGER) == SET) {//     __HAL_TIM_CLEAR_FLAG(&htim2, TIM_FLAG_TRIGGER);//     HAL_UART_Transmit(&huart2, (uint8_t *)SlaveModeMessage, strlen(SlaveModeMessage), 100);//   }else {//     HAL_UART_Transmit(&huart2, (uint8_t *)UpdateMessage, strlen(UpdateMessage), 100);//   }// }//门模式触发 触发时,定时器暂停计数if (htim == &htim2) {HAL_UART_Transmit(&huart2, (uint8_t *)UpdateMessage, strlen(UpdateMessage), 100);}
}
/* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 */int counter = 0;char message[50];/* 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();MX_USART2_UART_Init();/* USER CODE BEGIN 2 */HAL_TIM_Base_Start_IT(&htim2);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){//门模式:因为暂停计数 所以不会进入中断,所以在主函数中判断标志位//触发模式:启动定时器计时,仅能启动,不能停止//触发模式通常配合单脉冲模式,计数到自动重装载值停止计时if (__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_TRIGGER) == SET) {__HAL_TIM_CLEAR_FLAG(&htim2, TIM_FLAG_TRIGGER);HAL_UART_Transmit(&huart2, (uint8_t *)SlaveModeMessage, strlen(SlaveModeMessage), HAL_MAX_DELAY);}counter = __HAL_TIM_GET_COUNTER(&htim2);sprintf(message, "counter: %d", counter);HAL_UART_Transmit(&huart2, (uint8_t *)message, strlen(message), 100);HAL_Delay(500);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

五、输入捕获&超声波测距模块(HC-SR04)

基本原理:Trig引脚发送一个高电平信号,紧接着Ecoh引脚变为高电平,当再次接收到反射回来的超声波信号时,Ecoh变为低电平,通过测量Ecoh高电平时间×声速 ÷ 2 便可以计算出距离。

因为一个通道只能接收上升沿或者下降沿的一种,所以这里设计了巧妙的直接模式和间接模式,

用直接模式捕获上升沿,间接模式捕获下降沿,分别存储在不同寄存器。

cubemx配置

IC Selection:Direct-直接模式 Indirect-间接模式

注:只需要打开捕获/比较中断即可

示例程序

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint32_t upEdge = 0;
uint32_t downEdge = 0;
float distance = 0.00f;void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {//判断通道4是因为,通道4捕获的是后来的下降沿,当下降沿来之后再同时处理上升沿就好//捕获到计数值,会存储在寄存器,什么时候读都可以if (htim == &htim1 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4) {upEdge = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3);downEdge = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_4);distance = ((downEdge - upEdge) * 0.034) / 2;}
}
/* 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_I2C2_Init();MX_TIM1_Init();/* USER CODE BEGIN 2 */HAL_Delay(20);OLED_Init();HAL_TIM_Base_Start(&htim1); //开启定时器计数HAL_TIM_IC_Start(&htim1, TIM_CHANNEL_3); //开启输入捕获HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_4); //开启输入捕获char message[50];/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){HAL_GPIO_WritePin(Trig_GPIO_Port, Trig_Pin, GPIO_PIN_SET);HAL_Delay(1);HAL_GPIO_WritePin(Trig_GPIO_Port, Trig_Pin, GPIO_PIN_RESET);__HAL_TIM_SET_COUNTER(&htim1, 0); //防止在下降沿时计数器自动重装导致下降沿减上升沿的值小于0 开始测量就将计数器清0HAL_Delay(20);OLED_NewFrame();sprintf(message, "distance: %.2f", distance);OLED_PrintASCIIString(0, 0, message, &afont8x6, OLED_COLOR_NORMAL);OLED_ShowFrame();HAL_Delay(500);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

六、PMW基础&呼吸灯

简单解释PWM就是,设定重装载值为100,设定比较值为50,则小于50时,输出低电平/高电平,大于50时,输出高电平/低电平,此时占空比为高电平时间50/周期时间100×100% = 50%。

cubemx配置

Pulse(初始脉冲) :50

即初始占空比为50%

示例程序

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_TIM4_Init();/* USER CODE BEGIN 2 */HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){for (int i = 0; i < 100; i ++) {__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, i);HAL_Delay(10);}for (int i = 99; i >= 0; i --) {__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, i);HAL_Delay(10);}/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

七、编码器

cubemx配置

预分频Prescaler 设置为2分频是因为不分频时编码器每旋转一格计数值加2,因为在一个周期内AB两相均有一次上升沿,2分频后就可以每旋转一格计数值加1.

示例代码

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_I2C2_Init();MX_TIM1_Init();MX_TIM4_Init();/* USER CODE BEGIN 2 */HAL_Delay(20);OLED_Init();int counter = 0;char message[50];OLED_NewFrame();OLED_DrawRectangle(13, 30, 81, 7, OLED_COLOR_NORMAL);OLED_PrintASCIIString(13, 20, "Loading...", &afont8x6, OLED_COLOR_NORMAL);for (int i = 0; i <= 100; i ++) {OLED_DrawFilledRectangle(13, 31, i / 100.0 * 80, 6, OLED_COLOR_NORMAL);sprintf(message, "%d%%", i);OLED_PrintASCIIString(100, 31, message, &afont8x6, OLED_COLOR_NORMAL);HAL_Delay(20);OLED_ShowFrame();}HAL_TIM_Encoder_Start(&htim1, TIM_CHANNEL_ALL);HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){OLED_NewFrame();counter = __HAL_TIM_GET_COUNTER(&htim1);if (counter > 60000) {counter = 0;__HAL_TIM_SET_COUNTER(&htim1, 0);}else if (counter > 100){counter = 100;__HAL_TIM_SET_COUNTER(&htim1, 100);}__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, counter);// OLED_DrawImage(40, 8, &androidImg, OLED_COLOR_NORMAL);OLED_DrawRectangle(13, 16, 101, 9, OLED_COLOR_NORMAL);OLED_DrawFilledRectangle(13, 17, counter, 8, OLED_COLOR_NORMAL);sprintf(message, "counter: %d", counter);OLED_PrintASCIIString(13, 0, message, &afont8x6, OLED_COLOR_NORMAL);OLED_ShowFrame();HAL_Delay(100);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

此代码实现了旋转编码器调节LED亮度,并以进度条的形式显示在屏幕上

上述相关PPT均来自keysking up

http://www.dtcms.com/a/558495.html

相关文章:

  • 骑士人才网全系与phpyun人才网系统数据转移或互转的技术文档和要领,和大家一起共勉
  • 车载消息中间件FastDDS 源码解析(一)FastDDS 介绍和使用
  • 上街免费网站建设wordpress迁移后无法登录
  • 找人建站做网站需要注意什么问题广州seo优化费用
  • 做头像的网站有没有做京东客好的网站推荐
  • 上海家装设计网站网站内容的创新
  • 百度快照投诉seo优化推广工程师招聘
  • 看谁做的好舞蹈视频网站建设银行光明支行网站
  • 北京市建设投标网站公司官网优化
  • 合肥如何做百度的网站最专业的做网站公司有哪些
  • 网站域名分类做的网站不能放视频软件
  • 网站后台邮箱设置静态网站设计与制作书籍
  • 网站式的公司记录怎么做商城网站建设哪家公司好
  • 什么是软文文案深圳网站建设推广优化seo
  • aspnet网站开发实战易语言开发安卓app
  • 新手学做网站 pdf 网盘龙岗附近网站建设
  • KeepAlived高可用
  • 珠海网站建设方案报价做个网页需要多少钱
  • Java Optional 类详解
  • 网站海外推广资源北京建设局网站首页
  • 宁波seo推广费用西青seo
  • 网站建设财务上怎么处理网站策划书模板
  • 网站上传用什么软件做视频教程微信公众号怎么做网页
  • 龙华做棋牌网站建设多少钱网页设计模板素材代码
  • 人工蜂鸟算法的详细原理和公式
  • 网站建设服务器技术有哪些昆明网络营销咨询
  • 软件跟网站开发的区别公司网站建设建设
  • 石家庄网站托管公司wordpress企业主题源码
  • 个人网站代码编写网站建设 费用
  • 做的怎样 英文网站手机获取短信验证码 wordpress