STM32F407 HAL库 PWM 捕获功能 DMA 使用详解及优缺点分析

一、STM32F407 PWM 捕获功能简介

STM32F407的定时器(TIM)模块支持输入捕获功能,用于测量外部PWM信号的频率和占空比。关键特性包括:

多通道支持:每个定时器最多4个独立捕获通道(如TIM2/TIM3/TIM4/TIM5)。

高精度测量:支持16位/32位计数器,最高计数频率84 MHz(APB1时钟)。

双边沿触发:可捕获上升沿和下降沿时间戳,计算脉冲宽度和周期。

硬件滤波:通过数字滤波器抑制输入噪声。

DMA支持:自动传输捕获值,减少CPU中断负载。

二、HAL库配置PWM捕获的关键步骤

  1. 初始化定时器(以TIM3通道1为例)
    c
TIM_HandleTypeDef htim3;

// 定时器基础配置
htim3.Instance = TIM3;
htim3.Init.Prescaler = 84 - 1;          // 分频系数(APB1时钟=84MHz → 定时器时钟=1MHz)
htim3.Init.CounterMode = TIM_COUNTERMODE_UP; // 向上计数模式
htim3.Init.Period = 0xFFFF;             // 自动重载值设为最大(65535),防止溢出
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; // 时钟分频(无分频)
HAL_TIM_IC_Init(&htim3);               // 初始化输入捕获模式

// 配置输入捕获通道1(PA6复用为TIM3_CH1)
TIM_IC_InitTypeDef sConfigIC;
sConfigIC.ICPolarity = TIM_ICPOLARITY_BOTHEDGE; // 双边沿触发
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; // 直接连接到TI1输入
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;        // 无分频,每个边沿都捕获
sConfigIC.ICFilter = 0x0;                      // 关闭输入滤波器
HAL_TIM_IC_ConfigChannel(&htim3, &sConfigIC, TIM_CHANNEL_1);
  1. 配置GPIO为输入捕获模式
    c
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_6;              // PA6对应TIM3_CH1
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;        // 复用推挽模式
GPIO_InitStruct.Pull = GPIO_PULLUP;            // 上拉电阻避免悬空
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;     // 复用功能为TIM3
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  1. 配置中断或DMA
    中断模式(推荐用于实时性要求高的场景)
    c
// 启用捕获中断
HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1);

// 中断回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {
    if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) {
        static uint32_t first_edge = 0, second_edge = 0;
        static uint32_t period = 0, pulse_width = 0;
        
        if (first_edge == 0) {
            first_edge = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
        } else {
            second_edge = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
            
            // 计算周期和占空比(单位:微秒,假设定时器时钟1MHz)
            period = second_edge - first_edge;
            pulse_width = (htim->Instance->CCR2 - first_edge); // 假设使用通道2捕获下降沿
            first_edge = 0; // 重置为下一次捕获
            
            // 示例输出:周期和脉宽
            printf("Period: %lu us, Pulse Width: %lu us\n", period, pulse_width);
        }
    }
}
DMA模式(适合高频信号,减少CPU中断)

c

// 配置DMA传输捕获值到内存
DMA_HandleTypeDef hdma_tim3_ch1;

hdma_tim3_ch1.Instance = DMA1_Stream4;            // TIM3_CH1对应DMA1 Stream4
hdma_tim3_ch1.Init.Channel = DMA_CHANNEL_5;       // 通道5
hdma_tim3_ch1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_tim3_ch1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tim3_ch1.Init.MemInc = DMA_MINC_ENABLE;
hdma_tim3_ch1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; // 32位对齐
hdma_tim3_ch1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_tim3_ch1.Init.Mode = DMA_CIRCULAR;           // 循环模式
hdma_tim3_ch1.Init.Priority = DMA_PRIORITY_HIGH;
HAL_DMA_Init(&hdma_tim3_ch1);
__HAL_LINKDMA(&htim3, hdma[TIM_DMA_ID_CC1], hdma_tim3_ch1);

// 启动DMA捕获
uint32_t capture_buffer[2]; // 存储两次捕获值
HAL_TIM_IC_Start_DMA(&htim3, TIM_CHANNEL_1, capture_buffer, 2);
  1. 处理捕获数据
    频率计算:

在这里插入图片描述

占空比计算:
在这里插入图片描述

三、优缺点分析

优点:
高精度测量

硬件级时间戳捕获,分辨率可达1μs(1MHz定时器时钟),适合高精度应用(如电机转速检测)。

支持双边沿触发,单次捕获即可计算周期和占空比。

低CPU开销

DMA模式无需CPU干预,适合多通道或高频信号(如超声波测距)。

中断响应快,实时性强。

抗噪声能力

数字滤波器(ICFilter)可抑制短时脉冲干扰,提升信号稳定性。

缺点:
配置复杂度高

需协调定时器分频、捕获极性、DMA通道映射,配置错误易导致数据异常。

多通道同步捕获时,需处理数据对齐和溢出问题。

硬件资源限制

定时器通道有限,多路PWM捕获需分配多个定时器(如TIM2+TIM3+TIM4)。

高频信号(>1MHz)可能导致计数器溢出,需缩短自动重载值(ARR)。

中断延迟影响

高频率信号下,中断处理延迟可能导致数据丢失,需优化代码或使用DMA。

四、关键注意事项

定时器溢出处理

若信号周期超过ARR值,需启用溢出中断并计算总周期:

c

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
    overflow_count++; // 溢出计数器
}
// 总周期 = (overflow_count * ARR) + captured_value
信号边沿抖动

启用输入滤波器(ICFilter)抑制噪声:

c

sConfigIC.ICFilter = 0x6; // 6个时钟周期的滤波
多通道协同工作

使用从模式(Slave Mode)同步多个定时器,实现多路信号精确对齐。

DMA缓冲区管理

循环DMA模式下,需双缓冲区切换防止数据覆盖:

c

uint32_t buffer1[2], buffer2[2];
HAL_TIM_IC_Start_DMA(&htim3, TIM_CHANNEL_1, buffer1, 2);
// 在DMA完成回调中切换缓冲区

五、适用场景

电机控制:测量编码器信号、转速反馈。

电源管理:监测开关电源的PWM调制信号。

通信解码:解析红外遥控器或无线模块的PWM编码。

传感器接口:超声波测距、舵机控制信号检测。

六、常见问题与解决方案

捕获值始终为0

原因:GPIO未正确配置或信号未到达。

解决:

检查GPIO复用功能和外部信号连接。

使用示波器验证信号是否输入到MCU引脚。

测量结果波动大

原因:输入信号噪声或未启用滤波。

解决:

增加ICFilter值(如0x6)。

在硬件端添加RC低通滤波器。

DMA传输不连续

原因:DMA缓冲区长度不足或未启用循环模式。

解决:

确保DMA配置为循环模式(DMA_CIRCULAR)。

增大缓冲区长度或使用双缓冲策略。

高频信号测量溢出

原因:ARR值过小导致频繁溢出。

解决:

降低定时器分频系数(如Prescaler=0,定时器时钟=84MHz)。

使用32位定时器(如TIM2/TIM5)扩展计数范围。

通过合理配置,PWM捕获功能能够高效实现信号参数测量,但在高频或多通道场景中需精细优化硬件和软件设计。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

承接电子控制相关项目

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值