STM32采集频率-外部计数方式

STM32采集频率低频用捕获精度很高,测量高频误差有点大,可能是这种方法我掌握的不够好,决定采用外部计数的方法来测量比较高的频率。我是用一个定时器定时一个定时器计数再根据f=n/t算出频率,这种方法方法原理上是定时时间越长求出的频率越高,但是STM32的定时器是16位的,要考虑到计时溢出的情况。关于误差的产生,测量的信号源的精度也是关键,在进入中断的时候,定时器获取计数值都会延时几个微秒,可能会丢失脉冲。我现在这种测量方法测量100K-130k误差大概8-10hz左右。谁有更好的测量高频的方法可以留言交流一下。
先从main函数开始介绍:

int main(void)
{  
	int i;
	SystemInit();
	COMInit(COM2, 115200);
	RCC_Configuration();    /* System Clocks Configuration*/
	GPIO_Configuration();	  /* Configure the GPIO ports */
	Time_Configuration();   /* Time  configuration */
	Tim2_Timer();
	while(1)
		{   
			   printf("Frequency1 is %d HZ.\r\n",Frequency1);
		   //  printf("Frequency2 is %d HZ.\r\n",Frequency2);
	       //Delayms(10);
		for(i=0;i<1000000;i++)
			{}
	  }
}

下面是时钟配置函数:

/*******************************************************************************
* Function Name  : RCC_Configuration
* Description    : System Clocks Configuration
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RCC_Configuration(void)
{	
	/* TIM2 clock enable */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  /* TIM3 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
	#if 0
	/* TIM4 clock enable */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
	#endif
}

I/O配置函数:

/********************************************************************************
* Function Name  : GPIO_Configuration
* Description    : The I/O configuration function
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void GPIO_Configuration(void)
{	
 GPIO_InitTypeDef GPIO_InitStructure; 
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
 GPIO_Init(GPIOD, &GPIO_InitStructure); 
 #if 0
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
 GPIO_Init(GPIOE, &GPIO_InitStructure); 
 #endif
 }

定时器初始化函数:

/********************************************************************************
* Function Name  : Time_Configuration
* Description    : 定时器3配置函数
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void Time_Configuration()
{ 	
 TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
 TIM_TimeBaseStructure.TIM_Prescaler = 0x00; 
 TIM_TimeBaseStructure.TIM_Period = 0xFFFF; 
 TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; 
 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);  // Time base configuration 
    
 TIM_ETRClockMode2Config(TIM3, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);  
 //TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); 	
 TIM_SetCounter(TIM3, 0);    
 TIM_Cmd(TIM3, ENABLE); 
}

定时器定时函数定时250ms

void Tim2_Timer(void)
{
  TIM_TimeBaseInitTypeDef   TIM2_TimeBaseStructure;
  NVIC_InitTypeDef NVIC_InitStructure;  
  TIM_DeInit(TIM2);
  TIM2_TimeBaseStructure.TIM_Period =2499;
  TIM2_TimeBaseStructure.TIM_Prescaler = (7200-1); 
  TIM2_TimeBaseStructure.TIM_ClockDivision = 0x0;
  TIM2_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM2, &TIM2_TimeBaseStructure); // Time base configuration
  TIM_ClearFlag(TIM2,TIM_FLAG_Update);
  TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); 
  TIM_Cmd(TIM2, ENABLE); 
  
  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);                
}

中断服务函数:

#if 1
void TIM2_IRQHandler(void)   
{
      if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) 
        {
                TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
			   CAPTURE1=(u32)TIM_GetCounter(TIM3); 
                //CAPTURE2=(u32)TIM_GetCounter(TIM4); 					
				}
						sum+=CAPTURE1;
						count++;
						if(count==4)
						{
							Frequency1=sum/4/0.25;
							sum=0;
							count=0;
            }
			 TIM_SetCounter(TIM3,0);							
}
#endif

如果谁有更好的测量频率的方法,可以一起交流一下,共同进步。

更多技术文章浏览请关注:

百家号:
https://author.baidu.com/home?context=%7B%22app_id%22%3A%221646108714303504%22%7D&wfr=bjh

头条号:
https://www.toutiao.com/c/user/8115738721/#mid=1646025109246987

  • 11
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值