打印
[STM32F4]

stm32f4 PWM捕获 (上升沿/下降沿/高低电平时间)详解

[复制链接]
737|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wangtaohui|  楼主 | 2023-12-26 16:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
需要实现一个小功能,使用PWM捕获到一个信号的上升沿,并在这个信号的上升沿进行一些操作

一开始我有尝试过读取管脚的高低电平,但是由于这个信号的速度过快,高低电平是读取不到的,只能采用PWM捕获的方式,其实也比较好操作!

与以往需要两个通道来进行PWM捕获不同,这个代码只需要一个通道就可以实现

首先依然是PWM捕获的配置,代码如下:TIM_ICInitTypeDef  TIM5_ICInitStructure;


void TIM5_CH2_Cap_Init(u32 arr,u16 psc)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
        TIM_ICInitTypeDef  TIM5_ICInitStructure;

       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);            
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);                
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //修改IO口
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;       
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
        GPIO_Init(GPIOA,&GPIO_InitStructure);

        GPIO_PinAFConfig(GPIOA,GPIO_PinSource1,GPIO_AF_TIM5);

          
        TIM_TimeBaseStructure.TIM_Prescaler=psc;
        TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
        TIM_TimeBaseStructure.TIM_Period=arr;   
        TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
       
        TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure);
       
       
       
       
        TIM5_ICInitStructure.TIM_Channel = TIM_Channel_2;  //修改通道
  TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;       
  TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV2;       
  TIM5_ICInitStructure.TIM_ICFilter = 0x00;
  TIM_ICInit(TIM5, &TIM5_ICInitStructure);
               
        TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC2,ENABLE);        //通道对应着CC几
       
  TIM_Cmd(TIM5,ENABLE );        

  NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;               
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                       
        NVIC_Init(&NVIC_InitStructure);       
       
       
}


u32  TIM5CH2_CAPTURE_STA=0;                                                           
u32        TIM5CH2_CAPTURE_VAL;


void TIM5_IRQHandler(void)
{                     
        if((TIM5CH2_CAPTURE_STA&0X80)==0)       
        {
                if(TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)       
                {             
                        if(TIM5CH2_CAPTURE_STA&0X40)                                       
                        {
                                if((TIM5CH2_CAPTURE_STA&0X3F)==0X3F)
                                {
                                        TIM5CH2_CAPTURE_STA|=0X80;                               
                                        TIM5CH2_CAPTURE_VAL=0XFFFFFFFF;
                                }
                                else
                                        TIM5CH2_CAPTURE_STA++;
                        }         
                }
                if(TIM_GetITStatus(TIM5, TIM_IT_CC2) != RESET)
                {       
                        if(TIM5CH2_CAPTURE_STA&0X40)                               
                        {                                 
                                TIM5CH2_CAPTURE_STA|=0X80;                               
                            TIM5CH2_CAPTURE_VAL=TIM_GetCapture2(TIM5);//修改通道       
                                 TIM_Cmd(TIM5,DISABLE );                                        
                            TIM_SetCounter(TIM5,0);                                               
                        }else                                                                                                         
                        {
                                TIM5CH2_CAPTURE_STA=0;                               
                                TIM5CH2_CAPTURE_VAL=0;
                                TIM5CH2_CAPTURE_STA|=0X40;               
                                TIM_Cmd(TIM5,ENABLE );
                        }                    
                }                                                                                   
        }
        TIM_ClearITPendingBit(TIM5, TIM_IT_CC2|TIM_IT_Update);
}

比较需要注意的是,除了基本的IO口修改,PWM捕获一共4个通道,还需要根据使用的IO口定义自己的通道,我这里用的是TIM5的2通道,对应着stm32f4的话是PA1

配置完成之后,TIM5CH2_CAPTURE_STA==0x40的时候,就是上升沿的时刻了


使用特权

评论回复
沙发
wangtaohui|  楼主 | 2023-12-26 16:41 | 只看该作者
如果想要捕获下降沿,配置的时候TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;  就修改成下降沿

这里还需要注意的一点是,STA和VAL都需要定义成extern

extern u32  TIM5CH2_CAPTURE_STA;                                                           
extern u32        TIM5CH2_CAPTURE_VAL;       

使用特权

评论回复
板凳
wangtaohui|  楼主 | 2023-12-26 16:41 | 只看该作者
在main里面,配置PWM捕获的速度
int main(void)
{
       
                        TIM5_CH2_Cap_Init(0XFFFFFFFF,84-1);  //1M

        while(1)
        {
               
                if(TIM5CH2_CAPTURE_STA&0X80)        
                {
                        temp=TIM5CH2_CAPTURE_STA&0X3F;
                        temp*=0XFFFFFFFF;                                         
                        temp+=TIM5CH2_CAPTURE_VAL;                               
                       

                        TIM5CH2_CAPTURE_STA=0;                             
                }
    }
}

使用特权

评论回复
地板
wangtaohui|  楼主 | 2023-12-26 16:41 | 只看该作者
如果想要获取PWM的高低电平时间,就需要定义temp,在这里temp是高电平的时间,如果想要获取低电平时间,前面配置成获取低电平就行了

使用特权

评论回复
5
wangtaohui|  楼主 | 2023-12-26 16:42 | 只看该作者
之后,我们将进行PWM捕获的管脚(这里是PA1),连接到需要进行PWM捕获的信号管脚上(而不是用输出信号的管脚直接去PWM捕获)。我只需要获取高电平,在debug里面,我们可以看到STA会0x40--0x00不断变化,说明捕获成功

使用特权

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

本版积分规则

43

主题

482

帖子

0

粉丝