历史上的今天
返回首页

历史上的今天

今天是: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;  

   }

}

}

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

推荐阅读

史海拾趣

Daniel Woodhead公司的发展小趣事

随着公司业务的不断发展壮大,Daniel Woodhead公司开始关注社会责任和可持续发展。公司积极参与公益事业,捐赠资金和技术支持教育、环保等领域。同时,公司还注重环保和节能技术的研发与应用,努力减少生产过程中的环境污染和资源浪费。这些举措不仅提升了公司的社会形象,也为公司的长期发展奠定了坚实基础。

Global Communications公司的发展小趣事
温度传感器的输出与温度之间的线性关系也很重要,因为这直接影响到补偿电路的准确性和稳定性。
DETCO公司的发展小趣事

在电子产品行业日益关注环保和可持续发展的背景下,ElectronicsCorp采取了一系列积极措施。公司开始使用环保材料制造产品,并优化生产流程以减少能源消耗和废物排放。此外,ElectronicsCorp还推出了一系列回收计划,鼓励消费者将旧电子产品回收再利用。这些措施不仅提高了公司的环保形象,还增强了消费者对公司品牌的忠诚度。

Ambersil公司的发展小趣事

随着电子行业的竞争日益激烈,Ambersil公司意识到,要想在市场中立足,必须注重产品质量。公司加大了对生产线的投入,引进了先进的生产设备和技术,严格把控产品质量。同时,公司还建立了完善的售后服务体系,及时解决客户在使用过程中遇到的问题。这些举措使得Ambersil公司的产品在市场上赢得了良好的口碑。

Cogent_Computer_Systems公司的发展小趣事

在电子行业的发展过程中,Cogent_Computer_Systems公司深知合作共赢的重要性。公司积极与上下游企业建立紧密的合作关系,共同推动产业升级。通过与供应商的深度合作,公司确保了原材料的稳定供应和质量保障;同时,与客户的紧密沟通也帮助公司更好地把握市场需求,推出更符合消费者期望的产品。这种合作共赢的模式不仅提升了公司的竞争力,也为整个电子行业的发展注入了新的活力。

bb-smartworx公司的发展小趣事

Cogent_Computer_Systems公司在成立之初,便以其独特的技术创新在电子行业中崭露头角。公司研发团队成功开发出一款高性能的计算机芯片,该芯片在运算速度和能效比方面均达到了行业领先水平。这一技术突破迅速吸引了众多客户的关注,Cogent_Computer_Systems公司也因此获得了大量的订单。随着市场需求的不断增长,公司逐渐扩大生产规模,优化供应链管理,实现了业务的快速扩张。

问答坊 | AI 解惑

关于TI 6000系列DSP优化经验(转帖)

看到网上很多网友对TI 6000系列DSP优化工作感到苦恼,在此我总结下我的优化经验,希望对大家有帮助。 一、首先考虑从系统结构上优化,比如尽量减少待处理数据的无谓搬移,考虑你DSP片内存储量和每次处理数据量对系统结构优化,这部分的优化应该最 ...…

查看全部问答>

【ATMEL技术问题】关于KEIL下AT91R40008启动代码问题

用KEIL 软件建立一个工程,自动生成一个启动代码STartup.S ; 但是问题来了,这个代码有点不知所云,编译出错哦啊,请大侠指点!下面是代码 /*****************************************************************************/;/* STARTUP.S: Start ...…

查看全部问答>

菜鸟提问:SHBrowseForForlder()不能用,怎么代替

我是个初学者,我这个平台不能使用SHBrowseForForlder()这个方法,想找另外一个方法来代替SHBrowseForFolder,达到相同的效果, 或者可以不用打开浏览文件夹着个对话框,直接可以保存文件到指定目录也可以。劳驾各位帮忙啊…

查看全部问答>

求助:蓝牙和WIFI共存的问题

关于BT与WIFI共存时的设计,小弟有些问题,实在是不太明白,请教各位高手。 1. 我在网上看到有人说如果蓝牙和WIFI的物理隔离达到30dB以上,则两者之间的相互影响可以基本忽略。请问如果才能做到物理隔离达到30dB以上呢?是否天线距离远一些就可以 ...…

查看全部问答>

关于pc104总线驱动的制作

小弟刚刚做了一块基于pc104总线的DA板卡,但是现在要与基于pc104总线的3350主板进行交互,主要是对pc104总线的数据进行读取,需要制作驱动,小弟第一次开发,有那位大侠能够给一个例子或其他的资料,多谢…

查看全部问答>

螺纹的检测技术

各位大虾,有什么方法可以检测孔内的螺纹?只要检测孔内是否有螺纹就可以了。…

查看全部问答>

向大家请教一下uc/os-II多任务的运行机制?

有一个如下的uc/os-II源代码,就是采用信号量机制使两个任务共享一个串口com1,去打印一条字符串。 [code] #include \"config.h\" #define        Task0StkLengh        64       ...…

查看全部问答>

【课后练习】LaunchPad课后练习七之定时器

课后练习七之定时器   (定时器看起来简单,却搞了好久,和之前的430定时器不太一样,看了很多次,还有很多没弄出来的地方,有几个地方还是没懂) 1.TIMER_A由以下部分组成 [1] 计数器部分 输入的时钟源具有4种选择,所选择的时钟源又可 ...…

查看全部问答>

4位半的AD达到5位半分辨率的讨论,欢迎跟进一起探讨。

5位半的数字万用表没有一千块RMB是拿不下来的,本帖想讨论能否设计一种廉价的方案实施一个5位半表呢? ICL7135是4位半AD转换器,价格低廉,才4块钱多些,如果采用过采样编程技术,是否可以做出一个5位半分辨率的万用表呢? 欢迎讨论。 如果经研 ...…

查看全部问答>