STM32一个定时器同时捕获4路PWM波

本文介绍了一种使用STM32单片机通过一个定时器的四个通道同时捕获四路PWM信号的方法。这种方法可以有效节省定时器资源,并详细展示了实现这一功能的具体程序代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题的提出:

最近需要用航模遥控器控制遥控车,32单片机做主控,需要用到4个通道即需要捕获4路PWM波。如果用四个定时器来捕获四路PWM波,就太浪费资源了。由于STM32单片机的定时器资源有限,故设想用一个定时器的4个通道同时捕获四路PWM波。

设计思路:

由于接收机输出的PWM波高电平最多就2ms,故可以让4个通道轮流使用定时器捕获PWM波

程序如下:

include "PWMin.h"
void TIM2_2PWMin_Init(u16 arr,u16 psc)
{
RCC->APB1ENR|=1<<0;
RCC->APB2ENR|=1<<2;
GPIOA->CRL&=0XFFFF0000;
GPIOA->CRL|=0X00008888;
TIM2->ARR=arr;
TIM2->PSC=psc;
TIM2->CCMR1=0X0101;
TIM2->CCMR2=0X0101;
TIM2->CCER|=0X0001;
TIM2->DIER|=0X001f;
TIM2->CR1|=0x01;
MY_NVIC_Init(2,0,TIM2_IRQn,2);
}
u16 pwm1=1,pwm2=2,pwm3=2,pwm4=3;
u8 t1=0,t2=0,t3=0,t4=0;
u8 f=1;
void TIM2_IRQHandler(void)
{
u16 TSR;
TSR=TIM2->SR;
if(TSR&(1<<1))
{
if(t1==0)
{
t1=1;
TIM2->CCER|=1<<1;
TIM2->CNT=0;
}
else
{
t1=0;
pwm1=TIM2->CCR1;
TIM2->CCER&=~(3<<0);
f=2;
}
}
else if(TSR&(1<<2))
{
if(t2==0)
{
t2=1;
TIM2->CCER|=1<<5;
TIM2->CNT=0;
}
else
{
t2=0;
pwm2=TIM2->CCR2;
TIM2->CCER&=~(3<<4);
f=3;
}
}
else if(TSR&(1<<3))
{
if(t3==0)
{
t3=1;
TIM2->CCER|=1<<9;
TIM2->CNT=0;
}
else
{
t3=0;
pwm3=TIM2->CCR3;
TIM2->CCER&=~(3<<8);
f=4;
}
}
else if(TSR&(1<<4))
{
if(t4==0)
{
t4=1;
TIM2->CCER|=1<<13;
TIM2->CNT=0;
}
else
{
t4=0;
pwm4=TIM2->CCR4;
TIM2->CCER&=~(3<<12);
f=1;
}
}
else if(TSR&(1<<0))
{
TIM2->CCER&=~(1<<((f-1)*4));
if(f==1)
pwm1=0xffff;
else if(f==2)
pwm2=0xffff;
else if(f==3)
pwm3=0xffff;
else if(f==4)
pwm4=0xffff;
f++;
}
TIM2->CCER|=1<<((f-1)*4);
TIM2->CNT=0;
TIM2->SR=0;
}

### STM32定时器多通道PWM捕获方法及可行性 #### 多通道PWM信号捕获原理 STM32定时器具备强大的输入捕捉功能,可以用于精确测量外部脉冲宽度或周期。对于多通道PWM信号的捕获,可以通过配置多个输入捕捉通道来实现同步采样不同PWM信号的功能[^1]。 具体来说,在使用TIM3和TIM4这样的通用定时器时,这些定时器通常配备有几个独立的输入捕捉通道(如CH1, CH2等),允许同时监控来自不同源的PWM形变化情况。由于PWM输出固有的IO特性,无需额外GPIO配置就能完成这一操作,进一步简化了硬件连接并提高了系统的可靠性。 为了确保准确无误地获取各个PWM通道的信息,应当仔细调整每个通道对应的滤参数与极性设置,从而有效抑制噪声干扰带来的影响;与此同时,合理规划中断优先级和服务程序执行顺序也是至关重要的一步,这有助于及时响应每一个发生的事件而不至于造成数据丢失现象的发生。 #### 实现方案示例 下面给出一段基于C语言编写的简单代码片段作为参考: ```c // 初始化定时器为输入捕获模式 void TIM_Config(void){ // ...省略部分初始化代码... // 设置自动重装载预分频系数ARR=7999;PSC=99; __HAL_TIM_SET_AUTORELOAD(&htim3, 7999); __HAL_TIM_SET_PRESCALER(&htim3, 99); // 配置通道1为上升沿触发输入捕获 sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; HAL_TIM_IC_ConfigChannel(&htim3,&sConfigIC,TIM_CHANNEL_1); // 同理配置其他所需通道... } // 中断服务函数处理捕获到的数据 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){ if(htim->Instance==TIM3){ uint32_t capturedValue; // 获取当前时刻计数值 capturedValue=__HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_1); // 进行后续计算或其他操作 } } ``` 上述代码仅作为一个基础框架展示如何启动特定定时器进入输入捕获状态,并定义了一个简单的回调函数用来读取每次发生边沿跳变后的寄存器值。实际项目中可能还需要考虑更多细节问题,比如防止溢出错误、优化性能等方面的内容。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值