news 2026/4/27 21:47:21

STM32定时器实战:用CubeMX和HAL库实现PWM测量与LCD显示(附完整代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32定时器实战:用CubeMX和HAL库实现PWM测量与LCD显示(附完整代码)

STM32定时器实战:用CubeMX和HAL库实现PWM测量与LCD显示(附完整代码)

在嵌入式开发中,定时器是最常用也最强大的外设之一。无论是简单的延时功能,还是复杂的PWM信号生成与捕获,定时器都能胜任。对于准备参加蓝桥杯嵌入式组比赛的开发者来说,掌握定时器的各种应用场景尤为重要。本文将带你完成一个完整的实战项目:利用STM32的定时器输入捕获功能测量外部PWM信号的频率和占空比,并通过LCD实时显示测量结果。

1. 项目概述与硬件准备

这个项目的主要目标是构建一个PWM信号分析仪,能够实时测量并显示输入PWM信号的频率和占空比。我们将使用STM32的定时器输入捕获功能来实现这一目标,并通过LCD模块直观地展示测量结果。

所需硬件组件

  • STM32开发板(本文以STM32G431为例)
  • LCD显示屏(支持SPI或I2C接口)
  • PWM信号源(可使用另一个定时器生成测试信号)
  • 杜邦线若干

软件工具

  • STM32CubeMX(版本6.5.0或更高)
  • Keil MDK-ARM或STM32CubeIDE
  • STM32 HAL库

在开始之前,确保你已经熟悉STM32CubeMX的基本操作和HAL库的基本函数调用方式。如果你是完全新手,建议先完成几个简单的GPIO和定时器实验。

2. CubeMX工程配置

2.1 时钟树配置

首先打开CubeMX并创建新工程,选择你的STM32型号。进入时钟配置界面,根据你的开发板设置系统时钟。对于STM32G431,我们可以配置如下:

SYSCLK: 80MHz APB1 Timer clocks: 80MHz APB2 Timer clocks: 80MHz

时钟配置直接影响定时器的精度,务必确保正确设置。保存时钟配置后,CubeMX会自动生成相应的初始化代码。

2.2 定时器配置

我们需要配置两个定时器:一个用于生成PWM信号(作为测试信号源),另一个用于捕获输入的PWM信号。

PWM生成定时器配置(TIM15)

  1. 选择TIM15,设置为PWM Generation CH1和CH2
  2. Prescaler: 79 (80分频,得到1MHz计数频率)
  3. Counter Mode: Up
  4. Period: 199 (200个计数周期,对应5kHz PWM)
  5. Pulse: 120 (占空比60%)
  6. CH2 Pulse: 50 (占空比25%)

输入捕获定时器配置(TIM2)

  1. 选择TIM2,设置为Input Capture direct mode和indirect mode
  2. Prescaler: 79 (80分频,1MHz计数频率)
  3. Counter Mode: Up
  4. Period: 65535 (最大计数值)
  5. Slave Mode: Reset Mode
  6. Trigger Source: TI1FP1
  7. Channel 1: Rising Edge, Direct TI
  8. Channel 2: Falling Edge, Indirect TI

这种配置实现了PWM输入模式,可以同时测量周期和占空比。TIM2会在上升沿复位计数器,在下降沿捕获通道2的值(高电平时间),在下一个上升沿捕获通道1的值(整个周期)。

2.3 LCD接口配置

根据你的LCD模块类型配置相应的接口。常见的有:

  • SPI接口:配置SPI外设和CS、DC、RESET等控制引脚
  • I2C接口:配置I2C外设
  • 并行接口:配置FSMC或直接使用GPIO

确保在CubeMX中正确配置了所有必要的引脚,并生成初始化代码。

3. 代码实现

3.1 定时器初始化和启动

CubeMX生成的代码已经包含了定时器的基本配置,我们只需要添加启动代码:

void PWM_Input_Init(void) { // 启动PWM生成定时器 HAL_TIM_PWM_Start(&htim15, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim15, TIM_CHANNEL_2); // 启动输入捕获定时器 HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2); // 如果需要,可以启动基本定时器用于计时 HAL_TIM_Base_Start_IT(&htim1); }

3.2 输入捕获中断处理

输入捕获的核心逻辑在中断回调函数中实现。我们需要处理两个通道的捕获事件:

// 全局变量存储测量结果 uint32_t pwm_period_count = 0; uint32_t pwm_duty_count = 0; float pwm_duty = 0.0; uint16_t pwm_freq = 0; void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if(htim->Instance == TIM2) { if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) { // 通道1捕获上升沿,获取周期 pwm_period_count = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1) + 1; pwm_freq = 1000000 / pwm_period_count; // 1MHz计数频率 } else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) { // 通道2捕获下降沿,获取高电平时间 pwm_duty_count = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2) + 1; pwm_duty = ((float)pwm_duty_count / pwm_period_count) * 100.0; } } }

3.3 LCD显示实现

LCD显示部分需要根据你使用的具体LCD模块来实现。这里给出一个通用的显示函数框架:

void Update_LCD_Display(void) { char display_str[32]; // 清屏或局部刷新 LCD_Clear(WHITE); // 显示频率 sprintf(display_str, "Freq: %d Hz", pwm_freq); LCD_DisplayString(10, 50, (uint8_t *)display_str, BLACK, WHITE); // 显示占空比 sprintf(display_str, "Duty: %.1f %%", pwm_duty); LCD_DisplayString(10, 70, (uint8_t *)display_str, BLACK, WHITE); // 可以添加其他信息,如信号质量指示等 }

4. 系统集成与调试

4.1 主循环实现

在主循环中,我们需要定期更新LCD显示,并可以添加一些调试信息:

int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_TIM2_Init(); MX_TIM15_Init(); MX_LCD_Init(); PWM_Input_Init(); LCD_Init(); while (1) { Update_LCD_Display(); HAL_Delay(200); // 每200ms更新一次显示 } }

4.2 常见问题与调试技巧

在实际开发中,你可能会遇到以下问题:

  1. 捕获不到信号

    • 检查GPIO配置是否正确,特别是复用功能
    • 确认信号电压电平匹配(STM32通常是3.3V)
    • 使用逻辑分析仪或示波器验证信号是否到达引脚
  2. 测量结果不准确

    • 检查定时器时钟配置是否正确
    • 确保预分频器和周期值设置合理
    • 对于高频信号,考虑使用更高性能的定时器
  3. LCD显示异常

    • 验证LCD初始化序列是否正确
    • 检查数据传输时序是否符合LCD规格要求
    • 确保电源稳定,背光正常工作

调试建议

  • 使用STM32的调试功能,设置断点观察捕获值
  • 在关键位置添加LED指示灯或串口打印调试信息
  • 逐步验证每个功能模块,先确保PWM生成正确,再测试捕获功能

5. 进阶优化与扩展

5.1 多通道测量

如果需要同时测量多个PWM信号,可以配置多个定时器或使用一个定时器的多个通道:

// 配置TIM3为第二个输入捕获通道 HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1); HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2);

在回调函数中区分不同的定时器实例进行处理。

5.2 数字滤波

对于噪声较大的信号,可以启用定时器的输入捕获滤波器:

// 在CubeMX中配置Input Filter参数 sConfigIC.ICFilter = 6; // 设置适当的滤波值

或者在软件中实现移动平均滤波:

#define FILTER_SIZE 5 uint32_t freq_buffer[FILTER_SIZE] = {0}; uint8_t buffer_index = 0; // 在捕获回调中 freq_buffer[buffer_index] = pwm_freq; buffer_index = (buffer_index + 1) % FILTER_SIZE; // 计算平均值 uint32_t avg_freq = 0; for(int i=0; i<FILTER_SIZE; i++) { avg_freq += freq_buffer[i]; } avg_freq /= FILTER_SIZE;

5.3 自动量程切换

对于宽范围的频率测量,可以实现自动量程切换功能:

void Auto_Range_Adjust(void) { if(pwm_freq < 1000) { // 低频模式,增加预分频 htim2.Init.Prescaler = 799; // 100kHz计数 HAL_TIM_Base_Init(&htim2); } else { // 高频模式,减少预分频 htim2.Init.Prescaler = 79; // 1MHz计数 HAL_TIM_Base_Init(&htim2); } HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2); }

6. 完整工程代码结构

一个完整的STM32工程通常包含以下关键文件:

Project/ ├── Core/ │ ├── Inc/ │ │ ├── main.h │ │ ├── tim.h │ │ └── lcd.h │ └── Src/ │ ├── main.c │ ├── tim.c │ └── lcd.c ├── Drivers/ │ ├── CMSIS/ │ └── STM32G4xx_HAL_Driver/ └── STM32CubeMX/ └── Project.ioc

关键代码文件说明

  1. main.c: 包含主循环和系统初始化
  2. tim.c: 定时器配置和中断处理
  3. lcd.c: LCD驱动和显示函数
  4. Project.ioc: CubeMX工程配置文件

在蓝桥杯嵌入式比赛中,通常会提供基本的工程框架,你需要在此基础上添加功能模块。建议将不同功能封装成独立的.c/.h文件,保持代码结构清晰。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/27 21:46:28

Google ADK-Python:用Python高效控制Android设备的官方方案

1. 项目概述&#xff1a;一个连接Android硬件与Python的桥梁如果你是一名Android开发者&#xff0c;或者对硬件交互、自动化测试感兴趣&#xff0c;那你大概率遇到过这样的场景&#xff1a;你想用自己熟悉的Python脚本来控制一台Android设备&#xff0c;比如自动安装应用、模拟…

作者头像 李华
网站建设 2026/4/27 21:45:21

掌握3DS游戏格式转换:高效实用的完整操作手册

掌握3DS游戏格式转换&#xff1a;高效实用的完整操作手册 【免费下载链接】3dsconv Python script to convert Nintendo 3DS CCI (".cci", ".3ds") files to the CIA format 项目地址: https://gitcode.com/gh_mirrors/3d/3dsconv 你是否曾经下载了…

作者头像 李华
网站建设 2026/4/27 21:45:20

C++笔记——STL map

在 C STL 中&#xff0c;map 是有序键值对&#xff08;key-value&#xff09;关联容器&#xff0c;它的核心特点是键唯一、自动排序、高效查找&#xff0c;是开发中处理映射关系&#xff08;如字典、配置、索引&#xff09;最常用的容器之一。这篇笔记会从核心特性、头文件、常…

作者头像 李华
网站建设 2026/4/27 21:40:25

如何用Untrunc免费快速修复损坏的MP4视频?终极完整指南

如何用Untrunc免费快速修复损坏的MP4视频&#xff1f;终极完整指南 【免费下载链接】untrunc Restore a truncated mp4/mov. Improved version of ponchio/untrunc 项目地址: https://gitcode.com/gh_mirrors/un/untrunc 你是否曾因珍贵的MP4视频文件损坏而束手无策&…

作者头像 李华
网站建设 2026/4/27 21:38:44

别再手动算距离了!Halcon平面拟合后,一键计算点到平面距离的两种方法

Halcon平面拟合实战&#xff1a;高效计算点到平面距离的两种工程方案 在工业视觉检测和三维点云处理中&#xff0c;平面拟合后的距离计算是个高频需求场景。想象一下这样的工作场景&#xff1a;你已经用Halcon完成了精密零件的平面拟合&#xff0c;接下来需要快速评估上千个测量…

作者头像 李华
网站建设 2026/4/27 21:37:53

【2026年最新600套毕设项目分享】社区二手物品交易小程序(30187)

有需要的同学&#xff0c;源代码和配套文档领取&#xff0c;加文章最下方的名片哦 一、项目演示 项目演示视频 项目演示视频2 项目演示视频3 二、资料介绍 完整源代码&#xff08;前后端源代码SQL脚本&#xff09;配套文档&#xff08;LWPPT开题报告/任务书&#xff09;远…

作者头像 李华