你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32 PWM捕获 两种方法详解

[复制链接]
STMCU-管管 发布时间:2021-6-18 12:48
STM32 的TIM的捕获PWM波,是为了频率和占空比,这两种数据结果!它 的最基本的原理就是(打个比方):例如一个高电平上升沿过来,捕获的数值就是上升为的高电平的TIM的计数值(TIM定时器,CNT不断增加,再重新装载),这点是最基本的内容!后面就是通过前后的数值计算可以获得占空比 频率。


第一种方法:
11.png
官方的正统方法
   IC1和IC2为一组通道,IC3和IC4为一组通道,以上图为例可以得到上升沿是IC1的值为600(假设),此时TIMx_CCR2不变,计数器复位为0,然后在下降沿的时候,IC2读取计数值 即为高电平时间300(假设),当道下一个周期的上升沿时,IC1读取为600,计数器复位为0;
————————————————
  1. void pwmIC_Init()
  2. {
  3.        
  4.                 GPIO_InitTypeDef GPIO_InitStructure;
  5.                 NVIC_InitTypeDef NVIC_InitStructure;

  6.                 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  7.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

  8.                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  9.                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  10.                 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  11.                 GPIO_Init(GPIOA, &GPIO_InitStructure);


  12.                 TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
  13.                 TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  14.                 TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  15.                 TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  16.                 TIM_ICInitStructure.TIM_ICFilter = 0x0;

  17.                 TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);

  18.                 TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);

  19.                 TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);

  20.                 TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);

  21.                 TIM_Cmd(TIM3, ENABLE);

  22.                 TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);

  23.                 NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  24.                 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  25.                 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  26.                 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  27.                 NVIC_Init(&NVIC_InitStructure);

  28. }
复制代码
这里最关键的就是TIM_ICPolarity_Rising 为上升沿开始捕获,TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);
选择IC2为有效的输入端,就是IC2获得的就是周期了,而IC1就是在这里就是高电平的时间! 假设周期:600,高电平时间:300
可以计算的得到占空比  = 300/600, 可以得到频率 =72M/ 600;

  1. void TIM3_IRQHandler(void)
  2. {

  3.   TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);

  4.   IC2Value = TIM_GetCapture2(TIM3);

  5.   if (IC2Value != 0)
  6.   {

  7.     DutyCycle = (TIM_GetCapture1(TIM3) * 100) / IC2Value;


  8.     Frequency = SystemCoreClock / IC2Value;
  9.   }
  10.   else
  11.   {
  12.     DutyCycle = 0;
  13.     Frequency = 0;
  14.   }
  15. }
复制代码
以上就可以看出IC2为周期,IC1为高电平时间!


第二种方法:
     第二种方法显得比较裸,采用的就只是获取前后两次上升沿中断的计数值差,来计算周期,从而计算频率!

  1. void TIM_Cap_Init(u16 arr,u16 prc)//²¶»ñƵÂʳõʼ»¯  
  2. {  //PA1 PA2 ¶¨Ê±Æ÷TIM2 ͨµÀ2 3
  3.         TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
  4.         GPIO_InitTypeDef GPIO_InitStructure;
  5.         TIM_ICInitTypeDef TIM_ICInitStructure;
  6.         NVIC_InitTypeDef  NVIC_InitStructure;
  7.        
  8.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
  9.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
  10.        
  11.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1 | GPIO_Pin_2;
  12.         GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
  13.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
  14.         GPIO_Init(GPIOA,&GPIO_InitStructure);
  15.         GPIO_ResetBits(GPIOA,GPIO_Pin_1 | GPIO_Pin_2);
  16.        
  17.         NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;
  18.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
  19.         NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
  20.         NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
  21.         NVIC_Init(&NVIC_InitStructure);
  22.        
  23.         TIM_TimeBaseInitStructure.TIM_Prescaler=71;
  24.         TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up ;
  25.         TIM_TimeBaseInitStructure.TIM_Period=arr;
  26.         TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
  27.         TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
  28.        
  29.         TIM_ICInitStructure.TIM_Channel=TIM_Channel_2;
  30.         TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;
  31.         TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;  
  32.         TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;   
  33.         TIM_ICInitStructure.TIM_ICFilter=0x0;
  34.         TIM_ICInit(TIM2,&TIM_ICInitStructure);
  35.        
  36.         TIM_ICInitStructure.TIM_Channel=TIM_Channel_3;
  37.         TIM_ICInit(TIM2,&TIM_ICInitStructure);
  38.        
  39.         TIM_Cmd(TIM2,ENABLE);
  40.         TIM_ITConfig(TIM2, TIM_IT_CC2 | TIM_IT_CC3,ENABLE);
  41.        
  42. }
复制代码
配置了IC2,和IC3来采集两路的周期值!

  1. void TIM2_IRQHandler(void)
  2. {
  3.        
  4.         if(TIM_GetITStatus(TIM2,TIM_IT_CC2)==SET)
  5.         {
  6.           TIM_ClearITPendingBit(TIM2,TIM_IT_CC2);
  7.                 if(flag1==0)
  8.             {
  9.                one=TIM_GetCapture2(TIM2);
  10.                    flag1=1;       
  11.             }
  12.            else if(flag1==1)
  13.            {
  14.              two=TIM_GetCapture2(TIM2);
  15.                if(two>one)
  16.                    {
  17.                         value1=(two-one);   
  18.                    }
  19.               else
  20.                   {  
  21.                           value1=((0xffff-one)+two);
  22.                   }
  23.            Get_pinlv1=36000000/value1/36;
  24.                 flag1=0;  
  25.        
  26.            }
  27.         }

  28.   if(TIM_GetITStatus(TIM2,TIM_IT_CC3)==SET)
  29.         {
  30.           TIM_ClearITPendingBit(TIM2,TIM_IT_CC3);
  31.                 if(flag2==0)
  32.             {
  33.                three=TIM_GetCapture3(TIM2);
  34.                    flag2=1;       
  35.             }
  36.            else if(flag2==1)
  37.            {
  38.              four=TIM_GetCapture3(TIM2);
  39.                if(four>three)
  40.                    {
  41.                         value2=(four-three);   
  42.                    }
  43.               else
  44.                   {  
  45.                           value2=((0xffff-three)+four);
  46.                   }
  47.            Get_pinlv2=36000000/value2/36;
  48.                 flag2=0;  
  49.        
  50.            }
  51.         }
  52.        
  53. }
复制代码
采用了点小操作,来计算前后两次上升沿的差!当然了,如果想要获取占空比的画,可以配置一个通道下降沿捕获,配合上升沿捕获即可,这里就不再示范了。




收藏 评论0 发布时间:2021-6-18 12:48

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版