使用STM32-TIM进行频率和占空比的输入捕获测量

涉及知识点:

1.输入捕获模式

2.频率的测量方法

3.主从触发模式

4.PWMI测量占空比

正文:

1.输入捕获(Input Capture)简称为IC,在输入捕获模式下,当通道输入引脚出现指定电平跳变时(可以为上升沿,下降沿或都触发),当前的CNT的值被锁存到CCR中,通过读取当前状态CCR的值我们可以得知从开始计数到指定状态时CNT所计的值。如果CNT每次被锁存之后立即清0,则可以实现实时测量频率。

 

2.频率的测量方法:

测频法:在指定时间内求得对上升沿的计次,则f=N/T,如果指定时间为单位时间,那么N就等于f。

测周法:利用标准频率在两个上升沿之内计次,T=(1/fc)*N => f=fc/N

中界频率为测频法与测周法误差相等的频率点,令上面两式相等得到的频率即为中界频率。

 

3.主从触发模式

主模式:自己作为控制端去控制其他外设

从模式:用于接收其他外设或者自身引脚的信息,产生指定动作

在本实验中,可以通过从模式进行CNT清0的操作

4.PWMI基本结构

使用两个通道,一个通道与上述输入捕获模式相同,用于测量频率,第二个通道的区别在于为下降沿触发,提前将CNT锁存到对应CCR寄存器内,并且不会清0,而是等到下一个上升沿再清0,所以第二个通道的计次就代表着高电平对应的频率或周期。

代码部分:

 首先配置GPIO口和开启时钟

然后配置输出PWM波形产生一定频率的波,跟上一节相同,配置时基单元,配置输出比较通道

然后配置输入捕获通道,需要配置时基单元,设定自动重装值和预分频值得到标准频率,设置主从触发模式进行CNT清0,GPIO口与时钟相对应。

PWM波形:

#include "stm32f10x.h"                  // Device header

void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP ;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz ;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	TIM_InternalClockConfig(TIM2);
	
	TIM_TimeBaseInitTypeDef TIM_InitStructure;
	TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;  //时钟分频,主要控制滤波系数
	TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数
	TIM_InitStructure.TIM_Period = 100-1;  //ARR
  TIM_InitStructure.TIM_Prescaler = 720-1;  //PSC预分频值
  TIM_InitStructure.TIM_RepetitionCounter =0x00;	
	TIM_TimeBaseInit(TIM2,&TIM_InitStructure);
	
	TIM_OCInitTypeDef TIM_OCInitStucture;  //配置输出比较模块
	TIM_OCStructInit(&TIM_OCInitStucture);
	TIM_OCInitStucture.TIM_OCMode= TIM_OCMode_PWM1;  //输出模式
	TIM_OCInitStucture.TIM_OCPolarity = TIM_OCPolarity_High;  //极性选择
	TIM_OCInitStucture.TIM_OutputState = TIM_OutputState_Enable;  //使能
	TIM_OCInitStucture.TIM_Pulse =0 ;  //配置CCR
	TIM_OC1Init(TIM2,&TIM_OCInitStucture);
	
	TIM_Cmd(TIM2,ENABLE);
}

void PWM_SetCompare1(uint16_t Compare)  //用于在运行钟调节CCR,compare为比较值
{
   TIM_SetCompare1(TIM2,Compare);
}

void PWM_SetPrescaler(uint16_t Prescalar)  //用于改变频率
{
	TIM_PrescalerConfig(TIM2,Prescalar,TIM_PSCReloadMode_Immediate);
}

输入捕获:

#include "stm32f10x.h"                  // Device header


void IC_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  //开启定时器3
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);  //配置GPIO
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;  //上拉输入
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;  //PA6的通道1
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz ;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	TIM_InternalClockConfig(TIM3);  //
	
	TIM_TimeBaseInitTypeDef TIM_InitStructure;          		 //时基单元的配置
	TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1; 		 //时钟分频,主要控制滤波系数
	TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数
	TIM_InitStructure.TIM_Period = 65536-1; 								 //ARR
  TIM_InitStructure.TIM_Prescaler = 72-1;  								 //PSC预分频值
  TIM_InitStructure.TIM_RepetitionCounter =0x00;	
	TIM_TimeBaseInit(TIM3,&TIM_InitStructure);
	
	TIM_ICInitTypeDef  TIM_ICInitStructure;
	TIM_ICInitStructure.TIM_Channel=TIM_Channel_1 ;               //通道选择
	TIM_ICInitStructure.TIM_ICFilter= 0xF; 											 //滤波器参数选择,数值越大滤波效果越好
	TIM_ICInitStructure.TIM_ICPolarity= TIM_ICPolarity_Rising;  //捕获极性选择,上升沿触发还是下降沿触发
	TIM_ICInitStructure.TIM_ICPrescaler= TIM_ICPSC_DIV1;       //输出捕获模块预分频值,这里选择不分频
	TIM_ICInitStructure.TIM_ICSelection= TIM_ICSelection_DirectTI;     //选择交叉通道还是直连通道
	TIM_ICInit(TIM3,&TIM_ICInitStructure);
	TIM_PWMIConfig(TIM3,&TIM_ICInitStructure);                         //快捷配置PWMI模式,意为将上述参数取反配置
	
	TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);     //选择触发源
	TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);  //配置从模式
	
	
	TIM_Cmd(TIM3,ENABLE);

}

uint32_t  IC_GetFreq(void)  //获取频率
{
		return 1000000/ TIM_GetCapture1(TIM3);
}

uint32_t  IC_GetDuty(void)  //获取占空比
{
	return 100*(TIM_GetCapture2(TIM3)/TIM_GetCapture1(TIM3));
}

作者:ttal6688

物联沃分享整理
物联沃-IOTWORD物联网 » 使用STM32-TIM进行频率和占空比的输入捕获测量

发表回复