STM32f4日记2之pwm波输入捕获实验(可以接信号发生器,也可跟上一篇结合起来自己捕获自己)

STM32f4日记2之pwm波输入捕获实验(可以接信号发生器,也可跟上一篇结合起来自己捕获自己)

//
注意:此实验可跟上一篇文章pwm输出结合实验,就不用信号发生器跟示波器了(PF8接到PA1就可自己捕获自己显示占空比和频率)
//
板子:stm32f407zgt6正点原子迷你版
//
用杜邦线接信号发生器
最好将电压调到5v
这样效果明显
//
如果你觉得对你有帮助,请点赞同,这对我很重要,谢谢。
//
用到知识:定时器可以用边沿捕获波
//
timer.c代码如下(运用定时器32位TIM5,此代码部分用正点原子代码改写而成,仅供参考)
再次感谢正点原子

#include "timer.h"
#include "led.h"
#include "usart.h"  

TIM_ICInitTypeDef  TIM5_ICInitStructure;


void TIM5_CH1_Cap_Init(u32 arr,u16 psc)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);  	//使能TIM5  
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 	//
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //GPIOA1
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; 
	GPIO_Init(GPIOA,&GPIO_InitStructure); 

	GPIO_PinAFConfig(GPIOA,GPIO_PinSource1,GPIO_AF_TIM5); //PA1
  
	  
	TIM_TimeBaseStructure.TIM_Prescaler=psc;  //设置分频系数
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //上拉
	TIM_TimeBaseStructure.TIM_Period=arr;   //设置arr
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
	
	TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure);
	


	TIM5_ICInitStructure.TIM_Channel = TIM_Channel_2; //CC1S=01 	
  TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;	//极性上升沿
  TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //
  TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;	 //
  TIM5_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 
  TIM_ICInit(TIM5, &TIM5_ICInitStructure);
		
	TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC2,ENABLE);//更新中断跟cc2
	
 
  TIM_Cmd(TIM5,ENABLE ); 	//

 
  NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//优先级设置
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;		//优先级设置
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//
	NVIC_Init(&NVIC_InitStructure);	//
}



u8  TIM5CH1_CAPTURE_STA=0;	
u8  count = 0;             
u32	TIM5CH1_CAPTURE_UP1;	
u32	TIM5CH1_CAPTURE_UP2;	
u32	TIM5CH1_CAPTURE_DOWN;	


 
void TIM5_IRQHandler(void)//中断服务函数最重要的部分
{ 		    
 	if((TIM5CH1_CAPTURE_STA&0X80)==0)//
	{
		
		if(TIM_GetITStatus(TIM5, TIM_IT_CC2) != RESET)//
		{	
			
			if(TIM5CH1_CAPTURE_STA&0X40)		//
			{	  	
				TIM5CH1_CAPTURE_STA=0;			//		
			  TIM5CH1_CAPTURE_DOWN=TIM_GetCapture2(TIM5);
	 			TIM_OC2PolarityConfig(TIM5,TIM_ICPolarity_Rising); 
				TIM5CH1_CAPTURE_STA|=0X80;
			}
			else  								
			{
				count++;
				if(count == 1)    
				{
				TIM5CH1_CAPTURE_STA=0;			
				TIM5CH1_CAPTURE_UP1=TIM_GetCapture2(TIM5);
				
					
					
				}
				if(count == 2)    
				{
				TIM5CH1_CAPTURE_STA=0;		
				TIM5CH1_CAPTURE_UP2=TIM_GetCapture2(TIM5);
				TIM5CH1_CAPTURE_STA|=0X40;  
				TIM_OC2PolarityConfig(TIM5,TIM_ICPolarity_Falling);		
					

				}
			}	

	    
		}			     	    					   
 	}
	
	TIM_ClearITPendingBit(TIM5, TIM_IT_Update|TIM_IT_CC2); 
}


下面是timer.h内的代码

#ifndef __TIMER_H
#define __TIMER_H
#include "sys.h"

void TIM14_PWM_Init(u32 arr,u32 psc);
void TIM5_CH1_Cap_Init(u32 arr,u16 psc);

#endif

好,接下来是主函数的部分

#include "sys.h"
#include "delay.h"
#include "timer.h"
#include "led.h"
#include "string.h"
#include "pwm.h"
#include "key.h"
#include "usart.h"
#include "oled.h"
 #include "waishekey.h"

extern u8  TIM5CH1_CAPTURE_STA;			
extern u8  count;             
extern u32	TIM5CH1_CAPTURE_UP1;	
extern u32	TIM5CH1_CAPTURE_UP2;	
extern u32	TIM5CH1_CAPTURE_DOWN;	
	

int main(void)
{ 
	u32 temp_f=0;  
	float temp_d=0;
	
	char buffer1[100];
	char buffer2[100];

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	delay_init(168);  
	uart_init(115200);	
 	  OLED_Init();				
	  OLED_Clear();
		
	TIM5_CH1_Cap_Init(0XFFFFFFFF,42-1); //
 
   	
	sprintf(buffer1,"in duty:%5.1f%%",temp_d);
	sprintf(buffer2,"in freq:%.1uHZ",temp_f);
      while(1)
     {     
    if(TIM5CH1_CAPTURE_STA&0X80)    
		{
			
			TIM_Cmd(TIM5,DISABLE ); 	
			TIM_SetCounter(TIM5,0);
			temp_f = TIM5CH1_CAPTURE_UP2  - TIM5CH1_CAPTURE_UP1;		
			temp_d = TIM5CH1_CAPTURE_DOWN - TIM5CH1_CAPTURE_UP2;
			temp_d = temp_d*100.0 / temp_f;
			temp_f = 2000000 / temp_f;
			
			sprintf(buffer1,"in duty:%5.1f%%",temp_d);
	     sprintf(buffer2,"in freq:%.1uHZ", temp_f);
		
      
			OLED_ShowString(0,0,buffer1,16);
	     OLED_ShowString(0,16,buffer2,16);
		
			 		OLED_Refresh();
			
			TIM5CH1_CAPTURE_STA=0;			   
			count = 0;
			TIM_Cmd(TIM5,ENABLE ); 	
			delay_ms(100);
		}
}

此串代码经过实测测量50khz以内的波较为准确
如果以后有改进也会按时分享给大家。
//
思考:将之前一篇跟这一篇结合在一起自己输出,自己捕获,主函数应该怎么写?
//
作者:shawn
可咨询QQ:965798711
2020.12.19
21:46
All rights reserved


//

上一篇:【STM32F4】六、SRAM和DRAM的区别


下一篇:STM32F4-浮点DSP库的MDK开发环境的设置