STM32学习6

TIM输入捕获

概念

IC(Input Capture)输入捕获 输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数

每个高级定时器和通用定时器都拥有4个输入捕获通道

可配置为PWMI模式,同时测量频率和占空比

可配合主从触发模式,实现硬件全自动测量

频率测量

测频法:在闸门时间T内,对上升沿计次,得到N,则频率 f_x=N / T,适合于高频信号

测周法:两个上升沿内,以标准频率fc计次,得到N ,则频率 f_x=f_c / N,适合于低频信号

中界频率:测频法与测周法误差相等的频率点 f_m=√f_c / T

都以上升沿为一个周期的开始进行描述

输入捕获通道

主从触发模式 

输入捕获基本结构

右上角图解释:当第一次遇到上升沿时,CCR1=CNT,CNT自动复位清零。之后CNT++,在第二次遇到上升沿时候,再次执行CCR1=CNT,CNT=0的操作,这时候CCR1=CNT的值就是CNT++的值,也就是一个周期的时间

CNT有上限65535,根据ARR=65535得出

PWMI基本结构

右上角图解释:当第一次遇到上升沿时,CCR1=CNT,CNT自动复位清零。之后CNT++,在遇到下降沿的时候,CCR2=CNT也就是CCR2为高电平期间的计数值,但是不触发CNT清零,CNT仍继续++,在第二次遇到上升沿时候,再次执行CCR1=CNT,CNT=0的操作,这时候CCR1=CNT的值就是CNT++的值,也就是一个周期的时间。

代码

IC代码

#include "stm32f10x.h"                  // Device header

void IC_Init(void)
{
	/*开启时钟*/
	RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM3 ,ENABLE );//开启TIM3的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);//开启GPIOA的时钟
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitSturcture;
	GPIO_InitSturcture.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitSturcture.GPIO_Pin=GPIO_Pin_6;
	GPIO_InitSturcture.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitSturcture);//将PA6引脚初始化为上拉输入

	/*配置时钟源*/
	TIM_InternalClockConfig(TIM3);	//选择TIM2为内部时钟,若不调用此函数,TIM默认也为内部时钟
	/*时基单元初始化*/
	TIM_TimeBaseInitTypeDef TIM_TimebaseinitStructure;//定义结构体变量
	TIM_TimebaseinitStructure.TIM_ClockDivision=TIM_CKD_DIV1 ;//时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能
	TIM_TimebaseinitStructure.TIM_CounterMode=TIM_CounterMode_Up ;//计数器模式,选择向上计数
	TIM_TimebaseinitStructure.TIM_Period=65536-1;//计数周期,即ARR的值
	TIM_TimebaseinitStructure.TIM_Prescaler=72-1;//预分频器,即PSC的值
	TIM_TimebaseinitStructure.TIM_RepetitionCounter=0;//重复计数器,高级定时器才会用到
	TIM_TimeBaseInit(TIM3,&TIM_TimebaseinitStructure);	//将结构体变量交给TIM_TimeBaseInit,配置TIM2的时基单元
	
	TIM_ICInitTypeDef TIM_ICInitstructure;//定义结构体变量
	TIM_ICInitstructure.TIM_Channel=TIM_Channel_1;//选择配置定时器通道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_ICInit,配置TIM3的输入捕获通道
	
	TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//触发源选择TI1FP1
	TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//从模式选择复位
																								//即TI1产生上升沿时,会触发CNT归零
	TIM_Cmd (TIM3,ENABLE );
}

uint32_t IC_Getfreq(void)
{
	return 10000000/TIM_GetCapture1(TIM3);//测周法得到频率fx = fc / N,这里不执行+1的操作也可
	
}

main代码

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"
uint8_t i;


int main(void)
{
	
	OLED_Init();
	PWM_Init ();
	IC_Init();
	OLED_ShowString(1,1,"Freq00000Hz");//1行1列显示字符串Freq:00000Hz
	Pwm_SetPrescaler(720-1); //freq=72M/(psc+1)/100
	pwm_setcompare(50);			 //duty=CRR/100
	while(1)
	{
		OLED_ShowNum(1,6,IC_Getfreq(),5);//不断刷新显示输入捕获测得的频率
	}

}

PWMI模式测频率占空比

IC代码

#include "stm32f10x.h"                  // Device header

void IC_Init(void)
{
	/*开启时钟*/
	RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM3 ,ENABLE );//开启TIM3的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);//开启GPIOA的时钟
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitSturcture;
	GPIO_InitSturcture.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_InitSturcture.GPIO_Pin=GPIO_Pin_6;
	GPIO_InitSturcture.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitSturcture);//将PA6引脚初始化为上拉输入

	/*配置时钟源*/
	TIM_InternalClockConfig(TIM3);				//选择TIM2为内部时钟,若不调用此函数,TIM默认也为内部时钟
	/*时基单元初始化*/
	TIM_TimeBaseInitTypeDef TIM_TimebaseinitStructure;					//定义结构体变量
	TIM_TimebaseinitStructure.TIM_ClockDivision=TIM_CKD_DIV1 ;							//时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能
	TIM_TimebaseinitStructure.TIM_CounterMode=TIM_CounterMode_Up ;					//计数器模式,选择向上计数
	TIM_TimebaseinitStructure.TIM_Period=65536-1;				//计数周期,即ARR的值
	TIM_TimebaseinitStructure.TIM_Prescaler=72-1;				//预分频器,即PSC的值
	TIM_TimebaseinitStructure.TIM_RepetitionCounter=0;					//重复计数器,高级定时器才会用到
	TIM_TimeBaseInit(TIM3,&TIM_TimebaseinitStructure);					//将结构体变量交给TIM_TimeBaseInit,配置TIM2的时基单元
	
	TIM_ICInitTypeDef TIM_ICInitstructure;						//定义结构体变量
	TIM_ICInitstructure.TIM_Channel=TIM_Channel_1;					//选择配置定时器通道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_ICInit,配置TIM3的输入捕获通道
	TIM_PWMIConfig(TIM3,&TIM_ICInitstructure);						//将结构体变量交给TIM_PWMIConfig,配置TIM3的输入捕获通道
																	//此函数同时会把另一个通道配置为相反的配置,实现PWMI模式
	
	TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);							//触发源选择TI1FP1
	TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);					//从模式选择复位
																													//即TI1产生上升沿时,会触发CNT归零
	TIM_Cmd (TIM3,ENABLE );
}

uint32_t IC_Getfreq(void)
{
	return 1000000/TIM_GetCapture1(TIM3);//测周法得到频率fx = fc / N,这里不执行+1的操作也可
	
}
uint32_t IC_getDuty(void)
{
	return (TIM_GetCapture2(TIM3)+1)*100/(TIM_GetCapture1(TIM3)+1);//占空比Duty = CCR2 / CCR1 * 100,这里不执行+1的操作也可
}






main代码

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"
uint8_t i;


int main(void)
{
	
	OLED_Init();
	PWM_Init ();
	IC_Init();
	OLED_ShowString(1,1,"Freq:00000Hz");//1行1列显示字符串Freq:00000Hz
	OLED_ShowString(2,1,"Duty:00%");//1行1列显示字符串Freq:00000Hz
	Pwm_SetPrescaler(7200-1); //freq=72M/(psc+1)/100
	pwm_setcompare(80);			 //duty=CRR/100
	while(1)
	{
		OLED_ShowNum(1,6,IC_Getfreq(),5);//不断刷新显示输入捕获测得的频率
		OLED_ShowNum(2,6,IC_getDuty(),2);//不断刷新显示输入捕获测得的频率
	}

}

后续补充

1.测频率的范围

最低频率为1M/65535=15Hz,如果要降低最低频率的限制可以将预分频(PSC)加大,使得标准频率降低,所支持测量的最低频率也就更低。

最大频率无明显界限,随着待测频率的增加误差会增大。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值