
如何实现STM32的输入捕获功能?
硬件连接
将外部信号源连接到 STM32 的定时器通道引脚上,例如将编码器的 A 相连接到 TIM2 的 CH1(PA0),B 相连接到 TIM2 的 CH2(PA1)。
软件配置

使能时钟:开启定时器和对应 GPIO 引脚的时钟,如使用 TIM2,需调用RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE)
使能 TIM2 时钟,以及RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE)
使能 GPIOA 时钟。
GPIO 初始化:将捕获信号对应的 GPIO 引脚配置为复用功能,并根据需要配置上拉、下拉电阻等,如配置 PA0 引脚为复用功能,可设置为 AF2(具体值根据芯片手册确定)。
初始化定时器:设置定时器的自动重装载值、预分频值、计数模式等参数,如TIM_TimeBaseInitTypeDef
结构体的TIM_Period
设定计数器自动重装值,TIM_Prescaler
设置预分频值,TIM_CounterMode
选择计数模式。
配置输入捕获模式:设置捕获通道、触发极性、输入选择、输入分频、输入滤波等参数,如将 TIM2 的通道 1 配置为上升沿捕获,不分频,不滤波,可通过设置TIM_ICInitTypeDef
结构体的相关参数实现。
使能捕获和更新中断:若需在捕获事件发生时产生中断,调用TIM_ITConfig
函数开启捕获中断和更新中断,如TIM_ITConfig(TIMx, TIM_IT_Update | TIM_IT_CC1, ENABLE)
。
设置中断分组并编写中断服务函数:使用NVIC_Init
函数设置中断分组及优先级,在中断服务函数中判断中断类型并进行相应处理,如读取捕获寄存器的值、处理定时器溢出等。
使能定时器:调用TIM_Cmd
函数使能定时器,开始输入捕获,如TIM_Cmd(TIMx, ENABLE)
。
代码示例
以下是一个使用 STM32F4 测量 PA0 引脚上输入信号高电平脉宽的程序示例:
#include "stm32f4xx.h" #include <stdio.h> // 定义捕获状态和捕获值变量 volatile uint16_t captureValue = 0; void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { // 处理更新中断 } if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) { // 处理捕获中断 // 读取捕获寄存器的值,进行数据处理 captureValue = TIM_GetCapture1(TIM2); // 清除中断标志位 TIM_ClearITPendingBit(TIM2, TIM_IT_CC1 | TIM_IT_Update); } } int main(void) { // 系统初始化代码... // 使能 TIM2 时钟和 GPIOA 时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // GPIO 初始化 GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 定时器初始化 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period = 0xFFFF; TIM_TimeBaseStructure.TIM_Prescaler = 0x0; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // 输入捕获配置 TIM_ICInitTypeDef TIM_ICInitStructure; TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x00; TIM_ICInit(TIM2, &TIM_ICInitStructure); // 使能捕获和更新中断 TIM_ITConfig(TIM2, TIM_IT_Update | TIM_IT_CC1, ENABLE); // 设置中断分组并使能中断 NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // 使能定时器 TIM_Cmd(TIM2, ENABLE); while (1) { // 主循环代码... } }
作者:豆面本文地址:https://www.jerry.net.cn/articals/20611.html发布于 2025-01-23 08:33:30
文章转载或复制请以超链接形式并注明出处杰瑞科技发展有限公司