打印
[应用相关]

实例讲解之STM32的高级捕获模式

[复制链接]
963|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
简单介绍一下stm32的输入捕获模式

STM32的通用定时器具备基本的输入捕捉功能。所谓输入捕捉功能,是指通用定时器可以通过检测输入信号的跳变沿,检测到跳变沿的同时将计数器的当前值写入相应的寄存器。我们可以利用定制器的输入捕捉模式可以测量输入信号的高电平时间、占空比和频率。

这是定时器的内部框图


我们STM32的定时器有两种捕获模式普通输入模式和高级捕获模式(PWM输入模式)
需要注意的问题:定时器的时基频率不能太高,如果定时器工作于36M,采集50Hz的信号就会出现偏差(实测),所以程序中将定时器的时基频率配置为了1M;如果存在两个以上中断,需要设置中断优先级,否则容易出问题。

一、PWM输入模式的基本原理
PWM输入模式是输入捕捉模式的高级应用,对于测量频率较高的输入信号的频率特别精确,当然,为了实现这个模式,也得做出一点牺牲。相比于基本输入捕捉功能的实现来说,PWM输入模式中,一路输入信号同时映射到两个引脚,而且只有第一和第二通道可以配置为这种模式,换句话说,每个通用定时器只能测量一路输入信号。

PWM模式捕获方法:利用TIM2_CH1作PWM输出,TIM3_CH2捕获上述PWM信号,并测出频率和占空比。设置PWM频率为1KHz,占空比50%。

具体步骤:
1.      为了实现PWM输入捕获,TIM3占用了2个通道。第2通道的电平变化会被第一通道和第二通道引脚检测到,其中第一通道被设置为从机模式(如何快速判别主从机模式,规则如下:如果设置的是第二通道作为PWM输入捕获,则剩余的第一通道都为从机,反之亦然)。
2.      假设输入的PWM从低电平开始跳变,在第一个上升沿到来时,1,2通道同时检测到上升沿。而从机设置为复位模式,所以将TIM3的计数值复位至0,此时不会产生一个中断请求。
3.      下一个到来的电平是下降沿,此时通道1发生捕获事件,将计数值存入通道1的CCR1里。
4.      然后是第二个上升沿到来后,此时通道2发生捕获事件,将此时的计数值存入通道2的CCR2里。复位模式此时又将TIM3计数值复位至0,等待第二个下降沿到来。
5.      一次捕获过程完成,则PWM的频率f=72M/CCR2;占空比:duty=(CCR1/CCR2) X100%

二、具体看看怎么配置

单片机是stm32f103,如上述所示用TIM3的CH2通道捕获PWM波,注释非常详细,可以直接调用
  • void  tim3_pwmin_cfg(void)
  • {
  •         TIM_ICInitTypeDef TIM_ICInitStructure;
  •         TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  •         TIM_DeInit(TIM3);
  •          /* 定时器基本参数设置 */
  •   /* 定时周期: TIM_Period+1 */
  •         TIM_TimeBaseStructure.TIM_Period = 0xffff;
  •         /* 设置预分频TIM_Prescaler,输出脉冲频率:72MHz/(TIM_Prescaler+1)/(TIM_Period+1) */
  •         TIM_TimeBaseStructure.TIM_Prescaler = 7200;
  •         /* 向上计数模式 */
  •         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  •         /* 设置时钟分频系数:不分频(这里用不到) */
  •         TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  •         /*设置重复溢出次数,就是多少次溢出后进入中断,一般为0,只有高级定时器才有用*/
  • //        TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
  •         TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
  •      /* TIM3通道2*/
  •         TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
  •         /* 上升沿捕获*/
  •         TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  •         /* 映射到 TI1 上*/
  •         TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  •         /* 预分频系数,不分频*/
  •         TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  •         TIM_ICInitStructure.TIM_ICFilter = 0x0;
  •         /* PWM输入捕获模式是输入捕获模式的特例,初始化TIM3输入捕获参数 */
  •         TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);
  •         /*选择IC2为时钟触发源*/
  •         TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);
  •         /*启动定时器的被动触发*/
  •         TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);
  •         /*从模式控制器被设置为复位模式-选中的触发信号上升沿重新初始化计数器并产生一个更新信号
  •         (上升沿一到,TIM4->CNT被清零,每次上升沿来到,CNT都会被清零)*/
  •         TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
  •         /*捕获中断打开*/
  •         TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);
  •         /*使能定时器*/
  •         TIM_Cmd(TIM3, ENABLE);
  •     /*捕获中断清除标志位*/
  •         TIM_ClearFlag(TIM3,TIM_IT_CC2);
  • }

[color=rgb(51, 102, 153) !important]复制代码


中断配置,中断分组
  • voidnvic_TIM3_cfg(void)
  • {
  •     NVIC_InitTypeDef NVIC_InitStructure;
  •    /* 使用优先级组0,0位抢占,4位响应 */
  •     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  •     NVIC_InitStructure.NVIC_IRQChannel                   = TIM3_IRQn;
  •     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ST_NVIC_TIM3GL_P;
  •     NVIC_InitStructure.NVIC_IRQChannelSubPriority        = ST_NVIC_TIM3GL_S;
  •     NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
  •     NVIC_Init(&NVIC_InitStructure);
  • }

[color=rgb(51, 102, 153) !important]复制代码


中断服务函数
  • void st_tim3_irq_service(void)
  • {
  •     if(TIM3->SR & TIM_IT_Update)        //if ( TIM_GetITStatus(TIM3 , TIM_IT_Update) != RESET )
  •     {
  •         TIM3->SR = ~TIM_FLAG_Update;    //TIM_ClearITPendingBit(TIM3 , TIM_FLAG_Update);   //清除中断标志
  •                 float IC2Value=0;
  •                 float DutyCycle=0;
  •                 float Frequency=0;
  •                 float pulse=0;
  •                 IC2Value=TIM_GetCapture2(TIM3);//读取IC2捕获寄存器的值,即为PWM周期的计数值
  •                 pulse=TIM_GetCapture1(TIM3);//获得占空比的值
  • //                DutyCycle=pulse/IC2Value;
  • //                Frequency=72000000/IC2Value;
  • //                duty=(u32)(DutyCycle*100);
  • //                freq=(Frequency/1000);
  • //                flag=1;
  •     }
  • }

[color=rgb(51, 102, 153) !important]复制代码


看到中断服务函数里有两个函数TIM_GetCapture1(TIM3)和TIM_GetCapture2(TIM3),原理非常方便的就把高电平时间和pwm周期的捕捉到了,原理上面讲的非常详细,并且在高速的PWM波捕捉时非常实用。

但是注意了。对于高级定时器和通过定时器只有通道1和1才可以使用PWM输入模式




使用特权

评论回复
沙发
地下縱情搖擺| | 2022-11-23 15:20 | 只看该作者
这种高级捕获模式是不是应用在编码器方面啊

使用特权

评论回复
板凳
风吻过你的不羁| | 2022-11-23 15:52 | 只看该作者
其实还是PWM输入模式比较好用

使用特权

评论回复
地板
一枝香| | 2022-11-23 16:24 | 只看该作者
这种高级模式好像只能应用在定时器1

使用特权

评论回复
5
銀河| | 2022-11-23 16:56 | 只看该作者
挺好的,但是这种捕获应用在什么场景呢?

使用特权

评论回复
6
岁月反驳| | 2022-11-23 17:28 | 只看该作者
一般应用场景就用一般的定时器捕获就行了吧

使用特权

评论回复
7
晚晚皆安| | 2022-11-23 18:00 | 只看该作者
我觉得我好像用不到这种高级模式呢,因为我一般都是控制类的比较多

使用特权

评论回复
8
偷吻月亮| | 2022-11-23 18:32 | 只看该作者
讲的挺好的,其实ST的很多特殊功能,如果用好了,工作效率翻倍

使用特权

评论回复
9
林间有新绿| | 2022-11-23 19:04 | 只看该作者
这种捕获是为了驱动电机是吧

使用特权

评论回复
10
热爱童话世界| | 2022-11-23 19:36 | 只看该作者
调节占空比和调速来说,可能会用到捕获操作吧

使用特权

评论回复
11
极客晨星| | 2022-11-23 20:08 | 只看该作者
除了定时器1,其他都不行啊?是因为这种高级捕获用的不多吗?

使用特权

评论回复
12
Bblythe| | 2023-10-29 07:15 | 只看该作者

钳位二极管最常用于集成电路中

使用特权

评论回复
13
Uriah| | 2023-10-29 09:11 | 只看该作者

它迅速由高阻态变为低阻态

使用特权

评论回复
14
Bblythe| | 2023-10-29 10:14 | 只看该作者

减少反射,避免振荡,方便调试

使用特权

评论回复
15
Uriah| | 2023-10-29 12:10 | 只看该作者

得到正常工作状态下的输出电压和电流。

使用特权

评论回复
16
Bblythe| | 2023-10-29 13:13 | 只看该作者

在电路中有部分电子元器件比较“脆弱”

使用特权

评论回复
17
Uriah| | 2023-10-29 15:09 | 只看该作者

可能还需要进行一些额外的测试

使用特权

评论回复
18
Wordsworth| | 2023-10-29 16:12 | 只看该作者

产生一个充电放电的过程

使用特权

评论回复
19
周半梅| | 2023-10-29 17:15 | 只看该作者

齐纳二极管作为ESD保护与单向TVS原理相同

使用特权

评论回复
20
Uriah| | 2023-10-29 18:08 | 只看该作者

并在必要时进行去毛刺。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

41

主题

3747

帖子

0

粉丝