历史上的今天
返回首页

历史上的今天

今天是:2025年01月29日(星期三)

2019年01月29日 | STM32 PWM捕获 两种方法详解

2019-01-29 来源:eefocus

前言:

     

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


第一种方法:

 官方的正统方法

   IC1和IC2为一组通道,IC3和IC4为一组通道,以上图为例可以得到上升沿是IC1的值为600(假设),此时TIMx_CCR2不变,计数器复位为0,然后在下降沿的时候,IC2读取计数值 即为高电平时间300(假设),当道下一个周期的上升沿时,IC1读取为600,计数器复位为0;

void pwmIC_Init()

{

GPIO_InitTypeDef GPIO_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

 

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

 

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

 

 

TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;

TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;

TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;

TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;

TIM_ICInitStructure.TIM_ICFilter = 0x0;

 

TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);

 

TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);

 

TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);

 

TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable);

 

TIM_Cmd(TIM3, ENABLE);

 

TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);

 

NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

 

}

这里最关键的就是TIM_ICPolarity_Rising 为上升沿开始捕获,TIM_SelectInputTrigger(TIM3, TIM_TS_TI2FP2);

选择IC2为有效的输入端,就是IC2获得的就是周期了,而IC1就是在这里就是高电平的时间! 假设周期:600,高电平时间:300

可以计算的得到占空比  = 300/600, 可以得到频率 =72M/ 600;

void TIM3_IRQHandler(void)

{

 

  TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);

 

  IC2Value = TIM_GetCapture2(TIM3);

 

  if (IC2Value != 0)

  {

 

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

 

 

    Frequency = SystemCoreClock / IC2Value;

  }

  else

  {

    DutyCycle = 0;

    Frequency = 0;

  }

}


以上就可以看出IC2为周期,IC1为高电平时间!


第二种方法:

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

void TIM_Cap_Init(u16 arr,u16 prc)//²¶»ñƵÂʳõʼ»¯  

{  //PA1 PA2 ¶¨Ê±Æ÷TIM2 ͨµÀ2 3

TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

TIM_ICInitTypeDef TIM_ICInitStructure;

NVIC_InitTypeDef  NVIC_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1 | GPIO_Pin_2;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;

GPIO_Init(GPIOA,&GPIO_InitStructure);

GPIO_ResetBits(GPIOA,GPIO_Pin_1 | GPIO_Pin_2);

NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;

NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;

NVIC_Init(&NVIC_InitStructure);

TIM_TimeBaseInitStructure.TIM_Prescaler=71;

TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up ;

TIM_TimeBaseInitStructure.TIM_Period=arr;

TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;

TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);

TIM_ICInitStructure.TIM_Channel=TIM_Channel_2;

TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;

TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;  

TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;   

TIM_ICInitStructure.TIM_ICFilter=0x0;

TIM_ICInit(TIM2,&TIM_ICInitStructure);

TIM_ICInitStructure.TIM_Channel=TIM_Channel_3;

TIM_ICInit(TIM2,&TIM_ICInitStructure);

TIM_Cmd(TIM2,ENABLE);

TIM_ITConfig(TIM2, TIM_IT_CC2 | TIM_IT_CC3,ENABLE);

}

配置了IC2,和IC3来采集两路的周期值!


void TIM2_IRQHandler(void)

{

if(TIM_GetITStatus(TIM2,TIM_IT_CC2)==SET)

{

  TIM_ClearITPendingBit(TIM2,TIM_IT_CC2);

if(flag1==0)

    {

       one=TIM_GetCapture2(TIM2);

   flag1=1;

    }

   else if(flag1==1)

   {

     two=TIM_GetCapture2(TIM2);

       if(two>one)

   { 

value1=(two-one);   

   }

      else

  {  

  value1=((0xffff-one)+two);

  }

   Get_pinlv1=36000000/value1/36;

flag1=0;  

   }

}

 

  if(TIM_GetITStatus(TIM2,TIM_IT_CC3)==SET)

{

  TIM_ClearITPendingBit(TIM2,TIM_IT_CC3);

if(flag2==0)

    {

       three=TIM_GetCapture3(TIM2);

   flag2=1;

    }

   else if(flag2==1)

   {

     four=TIM_GetCapture3(TIM2);

       if(four>three)

   { 

value2=(four-three);   

   }

      else

  {  

  value2=((0xffff-three)+four);

  }

   Get_pinlv2=36000000/value2/36;

flag2=0;  

   }

}

}

采用了点小操作,来计算前后两次上升沿的差!当然了,如果想要获取占空比的画,可以配置一个通道下降沿捕获,配合上升沿捕获即可,这里就不再示范了。

推荐阅读

史海拾趣

CAO Group Inc公司的发展小趣事

随着公司的发展壮大,CAO Group开始面临来自各方面的竞争压力,其中包括知识产权的争议。近期,公司针对其在美国注册的三项专利——Lumist美白贴、SPRAY BOTTLE HEAD喷雾瓶头和透明氟塑料,发起了维权行动。公司积极应对,通过法律手段保护自身的知识产权,展示了其维护合法权益的决心和实力。

Achronix Semiconductor Corporation公司的发展小趣事

CAO Group并未满足于在牙科行业的成功,而是积极寻求多元化的发展道路。公司开始涉足医疗、执法和光电市场,通过不断推出创新产品和技术,成功拓展了新的业务领域。同时,公司还积极寻求与国际知名企业的合作,通过技术交流和资源共享,不断提升自身的竞争力和影响力。

Dresden Elektronik公司的发展小趣事

在Dresden Elektronik公司创立之初,其创始人看中了电子行业中嵌入式系统技术的巨大潜力。他们凭借对技术的深刻理解和敏锐的市场洞察力,开发出了一系列高性能、低成本的嵌入式系统解决方案。这些创新产品迅速在市场上获得了认可,为公司赢得了第一桶金,也为后续的发展奠定了坚实的基础。

BERGQUIST公司的发展小趣事

随着电子设备的不断发展和性能提升,热管理问题变得日益突出。BERGQUIST公司凭借其在热管理领域的深厚积累,成功研发出了一系列具有革命性的热管理产品。这些产品不仅有效解决了电子设备散热问题,还大大提高了设备的稳定性和可靠性。其中,BERGQUIST的柔性石墨散热片凭借其优异的导热性能和良好的适应性,在市场上获得了广泛认可。

Bud Industries公司的发展小趣事

BERGQUIST公司的故事始于上世纪,当时创始人敏锐地洞察到电子设备热管理的重要性。公司从研发高效热传导材料开始,逐渐在热管理技术领域建立起自己的声誉。初创时期,BERGQUIST面临着资金和技术双重挑战,但团队凭借对技术的执着追求和对市场的深刻洞察,成功开发出了一系列具有创新性的热管理产品,为公司的长远发展奠定了坚实基础。

Aeroflex Metelics / Hi-Rel Components公司的发展小趣事

随着电子设备的不断发展和性能提升,热管理问题变得日益突出。BERGQUIST公司凭借其在热管理领域的深厚积累,成功研发出了一系列具有革命性的热管理产品。这些产品不仅有效解决了电子设备散热问题,还大大提高了设备的稳定性和可靠性。其中,BERGQUIST的柔性石墨散热片凭借其优异的导热性能和良好的适应性,在市场上获得了广泛认可。

问答坊 | AI 解惑

嵌入式处理器简单介绍-医疗影像领域的技术推动者

DSP研发应用不断发展,嵌入式处理器在过去几年来技术也在不断进步,在医疗影像领域之中有广泛的应用。随着技术的不断发展,嵌入式处理器能帮助医疗仪器达到更快的诊断速度、更高的准确度,同事护理的成本也相应降低,使患者自我护理逐渐成 ...…

查看全部问答>

通过2104和h电桥控制电机遇到的问题

手工制作,有时候电机不转,有时候电机只能正转不能反转。PWM信号没问题,貌似总是DIR信号也就是2104的2号引脚上信号出现问题。通常是什么问题呢?还有2104控制电机的时候,是在上升沿和下降沿的时候切换正反转?那也就是说我有可能上升沿的电压不 ...…

查看全部问答>

准备搞一套DevKit8000了,看上去很好很强大的样子

Tegra没有jtag,玩起来大大受限制。有人有兴趣一起买么?…

查看全部问答>

弱!!ARM汇编的问题

小弟在看ARM的汇编的时候,发现里面的指令用法不明白!! 如: MOVEQ R0,#1 BEQ POW_END 这里的执行条件EQ,什么意思? MOVHS R0,#0 这条语句中HS什么意思? 望大侠赐教!!!…

查看全部问答>

上网本/MID/PMP等设备的朋友,请加入群!

我现在做eepc ARM 开发,建了一个MID/上网本/PMP等设备的开发群! 方便大家交流技术和市场。 群号:60587325 …

查看全部问答>

EVC 在编译时提示 ras.h 没找到?

EVC4在编译时提示 ras.h 没找到?搜了一下Include 目录,发现没有,从VC6把ras.h拷Include目录下面还是提示找不到?…

查看全部问答>

关于实时数据采集

   麻烦各位大侠们了    自己要做的是现场AD,然后光纤传输,之后接收还原DA输出,只是一个实时的采集,处理的部分用的不多,整个过程要求在1个微秒左右,选用的是Cyclone EP1C6.但是问题是,AD是12位并行输出,采样时钟大体准 ...…

查看全部问答>

STM32F10xx时钟

                                 STM32F10xx有内部时钟,启动后采用内部时钟,检查到外部时钟稳定后切换外部时钟,是这样吗?假如是这样,内部高速 ...…

查看全部问答>