STM32
直播中

切克切克闹

11年用户 467经验值
私信 关注
[问答]

如何利用STM32测量PWM的波频率及占空比?

如何利用STM32测量PWM的波频率及占空比?

回帖(1)

罗宗保

2021-11-18 09:38:22
PWM模式输入

该方式是在STM32输入捕获模式基础上扩展升级的功能,可以测量PWM波的频率及占空比,需要多加一个输入捕获寄存器
基本原理

(1)实现PWM输入捕获需要占用TIMx的两个通道,以IC1、IC2为例,TI1引脚上电平可被第1通道和第2通道同时监测到,两个通道分别被设置为主机和从机,如果设置第1通道为PWM输入捕获功能,则第2通道为从机。(IC1和IC2 IC3和IC4是成对存在的)





(2)输入的PWM从高电平跳变,第1个下降沿来临时,IC1 IC2均可监测到,从机设置为复位模式,将TIMx的计数器复位至0(此时不会产生计数器更新中断,因为无溢出)
(3)下一个上升沿来临时,IC2发生捕获事件,将当前计数器CNT的值存储至CCR2中,记为IC2_DATA2
(4)第二个下降沿来临,IC1发生捕获事件,将当前计数器CNT的值存储至CCR1中,记为IC1_DATA1




5)PWM波信号频率
f=72*10^6 /(psc(预分频系数)+1)/ IC1_DATA1
占空比D=IC2_DATA2/IC1_DATA1

  频率f=72*10^6 /(psc(预分频系数)+1)/ IC1_DATA1
  其中预分频系数这一项可以不加,如果不设置TIM_TimeBaseStructure.TIM_Prescaler这一项,则默认预分频系数为0,即此时:
   频率f=72*10^6 / IC1_DATA1
   此时可监测的频率范围为 72*10^6/65536(1098.6 Hz) ---- 72MHz,低于1098.6 Hz的频率将无法监测
   故设置预分频系数 psc,降低其可监测的范围(最大监测值和最小监测值都会改变)

实验(PWM输入部分代码)
基于STM32F103MiNi开发板(正点原子),以定时器3为例,TIM3_CH1(PA6引脚),由定时器4(TIM4_CH3 PB8引脚)产生PWM波,通过杜邦线外接PB8和PA6引脚


/*定时器3  PWM波输入捕获部分*/
void TIM3_Init(u16 psc)   //形参为分频系数
{
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_ICInitTypeDef  TIM_ICInitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;


        RCC_APB1PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB1Periph_TIM3, ENABLE);  //时钟初始化


        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_6;  
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;  
        GPIO_Init(GPIOA, &GPIO_InitStructure);      //引脚初始化
         
        TIM_TimeBaseStructure.TIM_Period = 65535;         //计数器自动重装值
        TIM_TimeBaseStructure.TIM_Prescaler =psc;         //预分频系数
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分割
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数模式
        TIM_TimeBaseStructure.TIM_RepetitionCounter=0;   //重复溢出次数,设置为0
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
  
        //通道1
        TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //IC1
   TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;        //下降沿捕获
   TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //IC1映射到TI1上
   TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;         //配置分频模式,不分频
   TIM_ICInitStructure.TIM_ICFilter = 0x00;                //配置输入滤波模式,不滤波
   TIM_ICInit(TIM3, &TIM_ICInitStructure);


        //中断优先级
        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);  


        TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);  


        TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);  //选择TIM3输入触发源  TI1


        TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);  /选择从机模式,复位模式


        TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);  //开启复位模式


        TIM_Cmd(TIM3,ENABLE );         //使能计数器


        TIM_ITConfig(TIM3,TIM_IT_CC1,ENABLE);//使能中断
}


//中断部分
void TIM3_IRQHandler(void)
{
  static float  Duty;
  static float IC1_DATA1;   //IC1_DATA1  、IC2_DATA2 定义为float类型,否则Duty会显示0
  static float IC2_DATA2;   //
  static u16 Frequence;
  TIM_ClearITPendingBit(TIM3,TIM_IT_CC1);


IC1_DATA1 = TIM_GetCapture1(TIM3);
  IC2_DATA2 = TIM_GetCapture2(TIM3);
  if (IC1_DATA1 != 0)
  {
    Frequence = (72000000/IC1_DATA1/(psc+1)); //psc为TIM3_Init(u16 psc)初始化的形参,值相同
  }
  else
  {
    Frequence = 0;
  }
  Duty=IC2_DATA2/IC1_DATA1;   //获得占空比
  printf("占空比=%%%.1f rn",(Duty*100));
  printf("PWM波频率=%d Hz rn",Frequence);
}


定时器4产生PWM波部分,直接借鉴正点原子官方 PWM波输出实验即可。


工程:PWM模式输入


测量一段时间内脉冲个数求频率
用TIM3_IRQHandler()中断计数PWM波脉冲个数,此时需要用另外一个定时器TIMx作为时钟计时,此时用定时器7作为计时时钟,定时器4产生PWM波


//TIM3 初始化
void TIM3_Init(u16 arr,u16 psc)   //形参为分频系数
{
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_ICInitTypeDef  TIM_ICInitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;


        RCC_APB1PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB1Periph_TIM3, ENABLE);  //时钟初始化


        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_6;  
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;  
        GPIO_Init(GPIOA, &GPIO_InitStructure);      //引脚初始化
         
        TIM_TimeBaseStructure.TIM_Period =arr;         //计数器自动重装值
        TIM_TimeBaseStructure.TIM_Prescaler =psc;         //预分频系数
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分割
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数模式
        TIM_TimeBaseStructure.TIM_RepetitionCounter=0;   //重复溢出次数,设置为0
        TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
  
        //通道1
        TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //IC1
   TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;        //下降沿捕获
   TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //IC1映射到TI1上
   TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;         //配置分频模式,不分频
   TIM_ICInitStructure.TIM_ICFilter = 0x00;                //配置输入滤波模式,不滤波
   TIM_ICInit(TIM3, &TIM_ICInitStructure);


        //中断优先级
        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);  


    TIM_CtrlPWMOutputs(TIM8,ENABLE);
   
        TIM_Cmd(TIM3,ENABLE );         //使能计数器


        TIM_ITConfig(TIM3,TIM_IT_CC1,ENABLE);//使能中断
}


//中断部分
void TIM3_IRQHandler(void)
{
  static u16 Frequence=0;
  static float time;
  static unsigned int PWMone=0;
  TIM_ClearITPendingBit(TIM3,TIM_IT_CC1);


  Frequence++;  //脉冲个数加1
  if((PWMTimer - PWMOneMinute)>99)  //定时1s更新一次,此处由另一定时器7提供时间基准
        {
                        PWMOneMinute=PWMTimer;                 //重新开始计时
                        time=Frequence/10;                                //计算得到频率(1s内脉冲个数)       
                        Frequence=0;                                                  //重新开始计数
  
                        printf("PWM波频率=%d Hz",Frequence);
          }
}





举报

更多回帖

发帖
×
20
完善资料,
赚取积分