TIM-Eingangserfassung – STM32

TIM-Eingangserfassung – STM32

IC (Input Capture)
Im Eingangserfassungsmodus wird der aktuelle CNT-Wert im CCR gespeichert, wenn der Kanaleingangspin einen bestimmten Pegelsprung aufweist, der zum Messen der Frequenz, des Arbeitszyklus und des Pulses der PWM verwendet werden kann Wellenform. Parameter wie Intervall, Pegeldauer usw.
Jeder erweiterte Timer und Allzweck-Timer verfügt über 4 Eingangserfassungskanäle, die als PWMI-Modus konfiguriert werden können, und die Frequenz und das Tastverhältnis können gleichzeitig gemessen werden. Der Master- Der Slave-Trigger-Modus kann verwendet werden, um die automatische Hardware-Messausgabe zu realisieren.
Fügen Sie hier eine Bildbeschreibung ein
Der Unterschied zwischen Vergleich und Eingangserfassung:
Ausgangsvergleich, der Pin ist ein Ausgangsport; Eingangserfassung, der Pin ist ein Eingangsport.
Der Ausgangsvergleich besteht darin, die Ausgangsaktion gemäß der Größenbeziehung zwischen CNT und CCR durchzuführen. Die Eingabeerfassung besteht darin, das Eingangssignal zu empfangen und die Aktion des Zwischenspeicherns des CNT im CCR durchzuführen.
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Im Allgemeinen können wir den ARR zunächst anhand der Auflösungsanforderungen bestimmen. Beispielsweise reicht 1 % der Auflösung aus, dann beträgt der ARR 100-1, sodass der PSC die Frequenz und der CCR den Arbeitszyklus bestimmt.
Fügen Sie hier eine Bildbeschreibung ein
Schritt 1: RCC schaltet die Uhr ein und schaltet die Uhren von GPIO und TIM ein.
Schritt 2: GPIO initialisieren, GPIO als Eingabemodus konfigurieren, im Allgemeinen Pull-Up-Eingang oder Floating-Eingabemodus wählen.
Schritt 3: Zeitbasiseinheit konfigurieren, CNT lassen Der Zähler wird durch die interne Uhr so ​​gesteuert, dass er automatisch läuft
. Der vierte Schritt besteht darin, die Eingabeerfassungseinheit zu konfigurieren. Einschließlich Parameter wie Filter, Polarität, Direktkanal oder Kreuzkanal und Frequenzteiler kann es einheitlich mit einer Struktur konfiguriert werden. Im fünften Schritt wird
die Triggerquelle des Slave-Modus ausgewählt. Wählen Sie die Triggerquelle als TI1FP1 aus, rufen Sie hier eine Bibliotheksfunktion auf und geben Sie einfach einen Parameter an
. Der sechste Schritt besteht darin, die Operation auszuwählen, die nach dem Trigger ausgeführt werden soll. Um den Reset-Vorgang auszuführen, genügt es, hier eine Bibliotheksfunktion aufzurufen. Rufen Sie
die TIM_Cmd-Funktion auf, um den Timer zu starten.

Wenn wir die Frequenz des letzten Zyklus lesen müssen, können wir das CCR-Register direkt lesen und es dann gemäß fc/N berechnen.
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Testhäufigkeit

#include "stm32f10x.h"                  // Device header

void IC_Init(void)
{
	//第一步开启时钟,初始化RCC,选择TIM2
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);	
	//设置输出PWM的GPIO端口
		//使能GPIOA的时钟 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	
	//GPIOA模式初始化
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
		
	//第二步选择时基单元的时钟,选择内部时钟,选择TIM2
	TIM_InternalClockConfig(TIM3);
	
	//第三步配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分频系数 1分频
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//计数的模式 向上计数
	//频率为1KHz,占空比为50%的PWM波形
	//计数器溢出频率:CK CNT_OV = CKCNT /(ARR + 1)= CK PSC /(PSC + 1)/(ARR +1)
	//配置定时为1s,则CK CNT_OV=1;CKCNT=72MHz=72000000;
	TIM_TimeBaseInitStruct.TIM_Period = 65536 - 1;//周期,ARR自动重装器的值 范围0~65536 设置为最大值,防止溢出
	TIM_TimeBaseInitStruct.TIM_Prescaler = 72 - 1;//PSC预分频器的值 范围0~65536 最后1Mhz
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; //重复计数器的值 高级计数器才有
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
	
	//第四步,配置输入捕获单元。包括滤波器、极性、直连通道还是交又通道、分频器这些参数
	TIM_ICInitTypeDef TIM_ICInitStruct;
	TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;//选择通道 选择TIM3的通道1
	TIM_ICInitStruct.TIM_ICFilter = 0xF;//用来配置输入捕获的滤波器。数越大滤波效果越好
	TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;//上升沿触发
	TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;//配置分频器,不分频
	TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;//配置数据选择器,直连通道
	TIM_ICInit(TIM3,&TIM_ICInitStruct);
	
	//第五步,选择从模式的触发源。触发源选择为TI1FP1,这里调用一个库函数,给一个参数就行了
	TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);
	
	//第六步,选择触发之后执行的操作。执行Reset操作,这里也是调用一个库函数就行了
	TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);
	
	//调用TIM_Cmd函数,开启定时器
	TIM_Cmd(TIM3,ENABLE);
}

//函数返回的是最新"个周期的频率值,单位是Hz
//Freq = CK_PSC / (PSC + 1) / (ARR + 1) 
//CK_PSC= 72MHz    PSC + 1 =100
uint32_t IC_GetFreq(void)
{
	return 10000000/(TIM_GetCapture1(TIM3)+1);
}

Fügen Sie hier eine Bildbeschreibung ein

#include "stm32f10x.h"                  // Device header

void IC_Init(void)
{
	//第一步开启时钟,初始化RCC,选择TIM2
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);	
	//设置输出PWM的GPIO端口
		//使能GPIOA的时钟 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	
	//GPIOA模式初始化
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
		
	//第二步选择时基单元的时钟,选择内部时钟,选择TIM2
	TIM_InternalClockConfig(TIM3);
	
	//第三步配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分频系数 1分频
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;//计数的模式 向上计数
	//频率为1KHz,占空比为50%的PWM波形
	//计数器溢出频率:CK CNT_OV = CKCNT /(ARR + 1)= CK PSC /(PSC + 1)/(ARR +1)
	//配置定时为1s,则CK CNT_OV=1;CKCNT=72MHz=72000000;
	TIM_TimeBaseInitStruct.TIM_Period = 65536 - 1;//周期,ARR自动重装器的值 范围0~65536 设置为最大值,防止溢出
	TIM_TimeBaseInitStruct.TIM_Prescaler = 72 - 1;//PSC预分频器的值 范围0~65536 最后1Mhz
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; //重复计数器的值 高级计数器才有
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
	
	//第四步,配置输入捕获单元。包括滤波器、极性、直连通道还是交又通道、分频器这些参数
	TIM_ICInitTypeDef TIM_ICInitStruct;
	
	TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;//选择通道 选择TIM3的通道1
	TIM_ICInitStruct.TIM_ICFilter = 0xF;//用来配置输入捕获的滤波器。数越大滤波效果越好
	TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;//上升沿触发
	TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;//配置分频器,不分频
	TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;//配置数据选择器,直连通道
	TIM_ICInit(TIM3,&TIM_ICInitStruct);
	TIM_PWMIConfig(TIM3,&TIM_ICInitStruct);//在函数里,会自动把剩下的一个通道初始化成相反的配置
//	TIM_ICInitStruct.TIM_Channel = TIM_Channel_2;//选择通道 选择TIM3的通道1
//	TIM_ICInitStruct.TIM_ICFilter = 0xF;//用来配置输入捕获的滤波器。数越大滤波效果越好
//	TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Falling;//上升沿触发
//	TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;//配置分频器,不分频
//	TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_IndirectTI;//配置数据选择器,交叉输入
//	TIM_ICInit(TIM3,&TIM_ICInitStruct);
	
	//第五步,选择从模式的触发源。触发源选择为TI1FP1,这里调用一个库函数,给一个参数就行了
	TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);
	
	//第六步,选择触发之后执行的操作。执行Reset操作,这里也是调用一个库函数就行了
	TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);
	
	//调用TIM_Cmd函数,开启定时器
	TIM_Cmd(TIM3,ENABLE);
}

//函数返回的是最新"个周期的频率值,单位是Hz
//Freq = CK_PSC / (PSC + 1) / (ARR + 1) 
//CK_PSC= 72MHz    PSC + 1 =100
uint32_t IC_GetFreq(void)
{
	return 10000000/(TIM_GetCapture1(TIM3)+1);
}

//获取占空比
//Duty = CCR / (ARR + 1)
uint32_t IC_GetDuty(void)
{
	//高电平的计数值存在CCR2里;整个周期的计数值存在CCR1里;用CCR2/CCR1,就能得到占空比了
	return (TIM_GetCapture2(TIM3)+1)*100/(TIM_GetCapture1(TIM3)+1);//范围是0%~100%
}

Supongo que te gusta

Origin blog.csdn.net/qq_45159887/article/details/130474564
Recomendado
Clasificación