单片机
返回首页

关于STM32精准采频率的实现

2019-03-13 来源:eefocus

这次做训练题遇到了采频率的问题,做单项并网问题,需要实时了解频率的相关信息。 


尝试直接用他们提供的输入捕获,发现并不是很好用,琢磨了半天,实现了自己的部分采用。 


这里就不一步一步的分析了,估计看的情况也比较少。 


直接上手,不过,博主是从正点原子那里直接得到的库里面查找的信息。 


一般定时器的配置


pwm_in_mode.h文件

这里介绍了两个配置函数


#ifndef __TIMER_H

#define __TIMER_H

#include 'stm32f4xx.h'


void TIM2_CH2_Cap_Init(void);

void TIM2_IRQHandler(void);


#endif


看自己的爱好,我这里把一般的(u16 arr,u16 psc)省略到里面去了,大家可以直接改掉也行,加在函数头里面传参。


pwm_in_mode.c文件

有几种模式,大家可以直接抄过去


时间设定初始化

TIM_ICInitTypeDef  TIM_ICInitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); 


TIM_TimeBaseStructure.TIM_Prescaler=84-1;                       

TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; 

TIM_TimeBaseStructure.TIM_Period=0xffffffff;//对应下面                         

TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1;

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);


引脚初始化

GPIO_InitTypeDef GPIO_InitStructure;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //GPIOA1      

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

GPIO_Init(GPIOA,&GPIO_InitStructure);   

GPIO_PinAFConfig(GPIOA,GPIO_PinSource1,GPIO_AF_TIM2);


中断优先级

NVIC_InitTypeDef NVIC_InitStructure;


NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01;

NVIC_InitStructure.NVIC_IRQChannelSubPriority =0x03;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 

NVIC_Init(&NVIC_InitStructure); 


使能和其他配置

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;


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_ICInit(TIM2,&TIM_ICInitStructure);

TIM_ICInitStructure.TIM_ICFilter = 0x0;//   


TIM_PWMIConfig(TIM2,&TIM_ICInitStructure);


/* Select the TIM4 Input Trigger: TI2FP2 */

TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2);


 /* Select the slave Mode: Reset Mode */

TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);

TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);


/* TIM enable counter */

TIM_Cmd(TIM2,ENABLE);

TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);



中断函数处理

这里就可以计算出周期和时间了,也可以直接复制过去。


void TIM2_IRQHandler(void)

    TIM_ClearITPendingBit(TIM2, TIM_IT_CC2); //Çå±ê־λ 


    IC2Value=TIM_GetCapture2(TIM2);

    IC1Value=TIM_GetCapture1(TIM2);


    if(IC2Value!=0){

        DutyCycle=(float)IC1Value*100/IC2Value;

        Frequency =(float)1000000/IC2Value;//对应上面的1Mhz

    }

    else{

        DutyCycle=0;

        Frequency=0;

    }

}


显示和现象对比

OLED_Refresh_Gram();

if(print_mode==0)

{       

   OLED_ShowString(0,0,'MeasureResult:',16);

   OLED_ShowString(0,16,'IC2Value:',16);

   OLED_ShowNum(72,16,IC2Value,7,16);

   OLED_ShowString(0,32,'DutyCycle:',16);

   OLED_ShowFloatNum(80,32,DutyCycle,7,16); 

   OLED_ShowString(0,48,'Frequency:',16);

   OLED_ShowFloatNum(80,48,Frequency,7,16);

}

aaa

精度与误差

这里定时器读到的IC1Value和IC2Value精度的限制,博主试过,最小可识别刻度在0.002hz,暂时还是够用的。 

 z'z'z 

如果做的过程中没能实现,可以直接下载参考我的.c文件,这里是文件链接。 

注意,博主的单片机型号是STM32F4系列的,时钟配置的TIM2是168M,如果不懂时钟的计算可以参考我前面的文章有讲解。

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 家用电源无载自动断电装置的设计与制作

  • 短波AM发射器电路设计图

  • 带有短路保护系统的5V直流稳压电源电路图

  • 如何调制IC555振荡器

  • 基于ICL296的大电流开关稳压器电源电路

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章