STM-32:TIM输入捕获—输入捕获模式测频率/PWMI模式同时测量频率和占空比

这篇具有很好参考价值的文章主要介绍了STM-32:TIM输入捕获—输入捕获模式测频率/PWMI模式同时测量频率和占空比。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、输入捕获简介

IC(Inpute Capture)输入捕获
输入捕获模式下,当通道输入引脚出现指定电平跳变,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数
每个高级定时器和通用定时器都拥有4个输入捕获通道
可配合PWMI模式,同时测量频率和占空比
可配合主从触发模式,实现硬件全自动测量
stm32 tim1 输入捕获,STM-32学习,stm32,单片机

二、频率测量

stm32 tim1 输入捕获,STM-32学习,stm32,单片机
首先,测频法适合测量高频信号,测周法适合测量低频信号
然后是测频法测 量结果更新慢一些,数值相对稳定,测周法更新的快,数据跳变也非常快
当待测信号频率小于中界频率时测周法误差更小, 当待测信号频率大于中界频率时测频法误差更小

三、电路实现测周法

3.1看图说话

stm32 tim1 输入捕获,STM-32学习,stm32,单片机
从左到右,最左边,是四个通道的引脚,参考引脚定义表就能知道引脚是复用在那个引脚,引脚进来,有一个三输入的异或门,这个异或门的输入接在了通道1、2、3端口,异或门的执行逻辑是,当输入引脚的任何一个有电平翻转时,输出引脚就产生一次电平翻转,之后输出通过数据选择器,到达输入捕获通道1,数据选择器如果选择上面一个,那输入捕获通道一的输入就是3个引脚的异或值,如果选择下面一个,那异或门就没有用,4个通道各用各的引脚。

输入信号过来,来到滤波器和边缘检测器,输入滤波器可以对信号进行滤波,避免一些高频的毛刺信号误触发,然后边沿检测器,这就和外部中断那里是一样的了,可以选择高电平触发,或者低电平触发,当出现指定的电平时,边缘检测电路就会触发后续电路执行动作

另外,其实设计了两套滤波和边沿检测电路,第一套电路经过滤波和极性选择得到TIFP1,输入给通道1的后续电路,第二套电路,经过另一个滤波和极性选择得到TIFP2,输入给下面通道2的后续电路,同理下面TI2信号进来,也经过两套滤波和极性选择得到TI2FP1和TI2FP2,其中TI2FP1输入给上面。TI2FP2输入给本路.在这里通道1和通道2可以各走各的也可以进行一个交叉(交叉的目的1、可以灵活切换后续捕获电路的输入,2、可以把一个引脚的输入,同时映射到两个捕获单元,这也是PWMI模式的经典结构)

然后经过预分频器就可以触发捕获电路进行工作了,每来一个触发信号,CNT的值就会向CCR转运一次,转运的同时,会发生一个捕获事件,这个事件会在状态寄存器置标志位,同时也可以产生中断,如果需要在捕获的瞬间去处理一些事情的话就可以开启这个捕获中断

(设计这个异或门,其实还是为三相无刷电机服务的,无刷电机有3个霍尔传感器检测转子的位置,可以根据转子的位置进行换相,有了这个异或门,就可以在前三个通道上接上无刷电机的霍尔传感器,然后这个定时器就作为无刷电机的接口定时器去驱动换相电路工作)

3.2详细的电路

stm32 tim1 输入捕获,STM-32学习,stm32,单片机
引脚进来,经过一个滤波器,滤波器的输入是TI1,就是CH1的引脚,输出的是TI1F,就是滤波后的信号,FDTS是滤波器的采样时钟来源,下面CCMR1寄存器里的ICF位可以控制滤波器的参数,(滤波器的主要工作是:以采样频率对输入信号进行采样,当连续N个值为高电平,输出才为高电平,连续N个值为低电平,输出才为低电平,采样频率越低,采样个数越大,滤波效果越好)滤波后的信号通过边沿检测器捕获上升沿或者下降沿,用CCER寄存器里的CC1P位就可以选择极性了,最终得到TI1FP1触发信号,通过数据选择器进入通道1的后续捕获电路,当然,应该还有一套相同的电路得到TI1FP2触发信号,连到通道2的后续电路,同样,通道2有TI2FP1连到通道一的后续电路,通道2也还有TI2FP2,共四种连接电路

3.3主从触发模式

stm32 tim1 输入捕获,STM-32学习,stm32,单片机
CCR对CNT进行捕获之后,需要对CNT进行一次清0操作,这样每次捕获得到的值才是测周法两个上升沿(下降沿)之间的时间间隔。这个清0操作,就需要用到主从触发模式来自动完成。由输入捕获通道1的详细框图可得:经过滤波和极性选择的TI1FP1信号和经过滤波的边沿信号TI1F_ED都可以通向从模式控制器,之后便可以通过硬件电路自动完成CNT的清0操作。
  主从触发模式,即主模式、从模式和触发源选择三个功能的简称。主模式可以将定时器内部的信号映射到TRGO引脚,用于触发其他外设的操作;从模式可以接收其他外设或自身外设的一些信号,用于触发自己的一些操作(定时器的运行);触发源选择,即选择从模式的触发信号源功能,也可以认为它是从模式的一部分。
  在从模式下,可以通过触发源选择功能选择一个信号产生TRGI信号,之后去触发从模式。关于主从模式的详细说明可以参见手册
stm32 tim1 输入捕获,STM-32学习,stm32,单片机
stm32 tim1 输入捕获,STM-32学习,stm32,单片机

3.4输入捕和PWMI基本结构

下图是输出捕获模式测频率的基本结构图。下图清晰地展示了输入捕获模式测量频率的过程,同时也是编程的逻辑基础。在这里我们只使用了一个通道,所以它只能测量频率。
  首先,配置时基单元,启动寄存器,则CNT就会在时钟驱动下不断自增。我们使用CNT来计数,间接实现计时的功能。经过预分频后的时钟频率,就是测周法的标准频率F
之后,GPIO输入一个待测的方波信号,经过TI1FP1为上升沿触发,之后数据选择器选择直连通道,分频器选择不分频。当TI1FP1出现上升沿之后,CNT的值就会被CCR1捕获;同时触发源选择模块选择TI1FP1为触发信号,从模式选择复位操作。则TI1FP1信号完成两个操作:捕获CNT的值到CCR1中、清零CNT。当然这里存在先后顺序,先进行捕获后进行清0;或者存在非阻塞的同时转移。当电路不断工作是,CCR1中的值始终是最新一个周期的计数值,即测周法的计次数 N
stm32 tim1 输入捕获,STM-32学习,stm32,单片机
stm32 tim1 输入捕获,STM-32学习,stm32,单片机
这里需要注意以下两点:

1、CNT的计数值是有上限的。由于ARR最大为65535,故CNT最大也只能计65535个数。如果信号频率太低,CNT的计数值可能会溢出。

2、从模式的触发源选择中有TI1FP1和TI2FP2,但是没有TI3和TI4的信号。所以如果要使用从模式自从清零CNT,就必须使用CH1或CH2作为输入。对于CH3和CH4,就只能开启捕获中断,在中断中手动清0了(程序会处于频繁中断的状态,比较占用软件资源)。

四、程序代码

4.1输入捕获相关函数

4.1.1输入捕获初始化配置

// 输入捕获IC初始化函数
// 输入捕获有四个通道,但是只有一个初始化函数,通道选择在结构体成员变量中,这一点与输出比较不同
void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
 
// 给IC初始化函数中的结构体参数赋一个默认值
void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct);
 
// 快速配置PWMI模式(自动将另一个通道配置为相反的模式)
void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
 
// 单独写入时基单元的PSC,第三个参数与预装载有关
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);
 
// 单独配置四个通道的预分频器,结构体中也可以配置,效果相同
void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
 
// 分别读取四个通道的CCR的值(与输出比较中的TIM_SetComparex函数对应)
uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx);
 

4.1.2主从触发模式配置

// 选择输入(从模式)触发源TRGI
void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
 
// 选择输入(主模式)触发源TRGO
void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource);
 
// 选择从模式需要执行的操作
void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);

4.2输入捕获模式测频率

4.2.1接线图

stm32 tim1 输入捕获,STM-32学习,stm32,单片机

4.2.2程序

PWM.c

#include "stm32f10x.h"                  // Device header
 
/**
  * @brief  PWM输出初始化函数
  * @param  无
  * @retval 无
  */
void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	TIM_InternalClockConfig(TIM2);
	
	// 时基单元初始化
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;	
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;	
	TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;	// ARR,确定后即确定了分辨率,这里分辨率为1%
	TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;	// PSC(调节ARR和PSC都可以改变频率,而ARR同时影响占空比,故这里通过调节PSC来调节PWM波形的频率)
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;	
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	// GPIO初始化,输出端口为PA0
	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);
	
	// OC初始化
	TIM_OCInitTypeDef TIM_OCInitStruct;	
	TIM_OCStructInit(&TIM_OCInitStruct);	// 结构体成员赋初始值
	TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;	// OC输出极性(有效电平为高电平)
	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;	// OC输出使能
	TIM_OCInitStruct.TIM_Pulse = 0;	// CCR
	TIM_OC1Init(TIM2, &TIM_OCInitStruct);
	
	TIM_Cmd(TIM2, ENABLE);
}
 
/**
  * @brief  更改比较/捕获寄存器的值CCR(当 ARR + 1 == 100 时 CCR 即为占空比)
  * @param  Compare 无符号16位整型数,注意:它只能是正数
  * @retval 无
  */
void PWM_SetCompare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM2, Compare);
}
 
/**
  * @brief  更改与分频器的值
  * @param  Prescaler 	写入的新预分频器的值
  * @retval 无
  */
void PWM_SetPrescaler(uint16_t Prescaler)
{
	TIM_PrescalerConfig(TIM2, Prescaler, TIM_PSCReloadMode_Immediate);	// 单独设置PSC(立刻生效)
}
 

InputCaputure.c

#include "stm32f10x.h"                  // Device header
 
/**
  * @brief  输入捕获初始化函数
  * @param  无
  * @retval 无
  */
void IC_Init(void)
{
	// 1. 开启时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);	// 使用TIM2输出PWM波形,TIM3进行输入捕获
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	// 2. GPIO初始化
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	// 上拉输入模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// 3. 配置时基单元
	TIM_InternalClockConfig(TIM3);	// 选择内部时钟
	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,它的值决定了测周法的标准频率fc,它的值要根据测量信号的频率范围来调整,这里fc为1MHz
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;	
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	
	// 4. 配置输入捕获单元
	TIM_ICInitTypeDef TIM_ICInitStruct;
	TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;					// IC通道
	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);
	
	// 5. 选择从模式的触发源
	TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
	
	// 6. 选择从模式触发后执行的操作
	TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
	
	// 7. 开启定时器
	TIM_Cmd(TIM3, ENABLE);
}
 
/**
  * @brief  获取测得的频率
  * @param  无 
  * @retval 测得的频率
  */
uint32_t IC_GetFreq(void)
{
	// 测周法标准频率为1MHz
	return 1000000 / TIM_GetCapture1(TIM3);
	//	return 1000000 / (TIM_GetCapture1(TIM3) + 1)	// 面向结果编程否则逼死强迫症(?)
}
 

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "InputCapture.h"
 
int main()
{
	OLED_Init();
	IC_Init();
	
	PWM_Init();
	PWM_SetPrescaler(720 - 1);			// Freq = 72M / (PSC + 1) / (ARR + 1),这里ARR + 1 == 100
	PWM_SetCompare1(50);				// Duty = CCR / (ARR + 1)
	
	OLED_ShowString(1, 1, "Freq:00000Hz");
	
	while(1)
	{
		OLED_ShowNum(1, 6, IC_GetFreq(), 5);
	}
}
 

4.3PWMI模式同时测量频率和占空比

4.3.1接线图

stm32 tim1 输入捕获,STM-32学习,stm32,单片机

4.3.2程序

PWM.c

#include "stm32f10x.h"                  // Device header
 
/**
  * @brief  PWM输出初始化函数
  * @param  无
  * @retval 无
  */
void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	TIM_InternalClockConfig(TIM2);
	
	// 时基单元初始化
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;	
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;	
	TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;	// ARR,确定后即确定了分辨率,这里分辨率为1%
	TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;	// PSC(调节ARR和PSC都可以改变频率,而ARR同时影响占空比,故这里通过调节PSC来调节PWM波形的频率)
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;	
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	// GPIO初始化,输出端口为PA0
	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);
	
	// OC初始化
	TIM_OCInitTypeDef TIM_OCInitStruct;	
	TIM_OCStructInit(&TIM_OCInitStruct);	// 结构体成员赋初始值
	TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;	// OC输出极性(有效电平为高电平)
	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;	// OC输出使能
	TIM_OCInitStruct.TIM_Pulse = 0;	// CCR
	TIM_OC1Init(TIM2, &TIM_OCInitStruct);
	
	TIM_Cmd(TIM2, ENABLE);
}
 
/**
  * @brief  更改比较/捕获寄存器的值CCR(当 ARR + 1 == 100 时 CCR 即为占空比)
  * @param  Compare 无符号16位整型数,注意:它只能是正数
  * @retval 无
  */
void PWM_SetCompare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM2, Compare);
}
 
/**
  * @brief  更改与分频器的值
  * @param  Prescaler 	写入的新预分频器的值
  * @retval 无
  */
void PWM_SetPrescaler(uint16_t Prescaler)
{
	TIM_PrescalerConfig(TIM2, Prescaler, TIM_PSCReloadMode_Immediate);	// 单独设置PSC(立刻生效)
}

InputCaputure.c

#include "stm32f10x.h"                  // Device header
 
/**
  * @brief  输出捕获PWMI模式初始化函数
  * @param  无
  * @retval 无
  */
void IC_Init(void)
{
	// 1. 开启时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);	// 使用TIM2输出PWM波形,TIM3进行输入捕获
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	// 2. GPIO初始化
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;	// 上拉输入模式,防止信号干扰,且单片机为强下拉,弱上拉
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// 3. 配置时基单元
	TIM_InternalClockConfig(TIM3);	// 选择内部时钟
	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,它的值决定了测周法的标准频率fc,它的值要根据测量信号的频率范围来调整,这里fc为1MHz
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;	
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	
	// 4. 配置输入捕获单元
	// 通道1测量频率
	TIM_ICInitTypeDef TIM_ICInitStruct;
	TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;					// IC通道,通道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);
	// 通道2测量占空比
	TIM_PWMIConfig(TIM3, &TIM_ICInitStruct);	// 在该函数中会快捷地将另一个通道初始化为“相反”的配置,这个函数执行的操作和下面的操作是等价的
//	TIM_ICInitStruct.TIM_Channel = TIM_Channel_2;					// IC通道,通道2
//	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);
	
	// 5. 选择从模式的触发源
	TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
	
	// 6. 选择从模式触发后执行的操作
	TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
	
	// 7. 开启定时器
	TIM_Cmd(TIM3, ENABLE);
}
 
/**
  * @brief  获取测得的频率
  * @param  无 
  * @retval 测得的频率
  */
uint32_t IC_GetFreq(void)
{
	// 测周法标准频率为1MHz
	return 1000000 / TIM_GetCapture1(TIM3);
//	return 1000000 / (TIM_GetCapture1(TIM3) + 1);	// 面向结果编程否则逼死强迫症(?)
}
 
/**
  * @brief  获取测得的占空比
  * @param  无 
  * @retval 测得的占空比(百分之)
  */
uint32_t IC_GetDuty(void)
{
	return TIM_GetCapture2(TIM3) * 100 / TIM_GetCapture1(TIM3);
//	return (TIM_GetCapture2(TIM3) + 1) * 100 / (TIM_GetCapture1(TIM3) + 1);
}
 

main.c文章来源地址https://www.toymoban.com/news/detail-545767.html

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "InputCapture.h"
 
int main()
{
	OLED_Init();
	IC_Init();
	
	PWM_Init();
	PWM_SetPrescaler(720 - 1);			// Freq = 72M / (PSC + 1) / (ARR + 1),这里 ARR + 1 == 100
	PWM_SetCompare1(80);				// Duty = CCR / (ARR + 1)
	
	OLED_ShowString(1, 1, "Freq:00000Hz");
	OLED_ShowString(2, 1, "Duty:00%");
	
	while(1)
	{
		OLED_ShowNum(1, 6, IC_GetFreq(), 5);
		OLED_ShowNum(2, 6, IC_GetDuty(), 2);
	}
}
 

到了这里,关于STM-32:TIM输入捕获—输入捕获模式测频率/PWMI模式同时测量频率和占空比的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32——输入捕获IC(测试频率以及PWMI测试频率占空比)

    目录 一、IC介绍 1.1、IC作用 1.2、电路部分  1.2.1、详细电路作用  1.2.2、从模式控制器 1.3、输入捕获配置基本结构 1.3.1、PWMI模式 二、代码配置 2.1、从模式函数 2.1.1、TIM_SelectInputTrigger() 2.1.2、TIM_SelectSlaveMode() 2.1.3、TIM_SelectSlaveMode() 2.2.输入捕获及时基单元函数 2.2.1、

    2024年01月25日
    浏览(42)
  • STM32 TIM输入捕获测频率占空比库函数

    目录 一、输入捕获初始化函数 TIM_ICInit TIM_PWMIConfig TIM_ICStructInit 二、主从触发模式对应函数 TIM_SelectInputTrigger TIM_SelectOutputTrigger TIM_SelectSlaveMode 三、配置分频器函数 TIM_SetIC1Prescaler TIM_SetIC2Prescaler TIM_SetIC3Prescaler TIM_SetIC4Prescaler 四、读取CCR函数 TIM_GetCapture1 TIM_GetCapture2 TIM_GetCap

    2024年02月20日
    浏览(35)
  • STM32—TIM:基本定时器(输入捕获:测频率、周期)(标准库)

     频率测量:  频率中界频率:适用测周法                                                           频率中界频率:适用测频法 第一步:配置GPIO,TIM的时基单元              在配置TIM的时基单元参数有些许不同。 初始化输入捕获单元:void TIM_ICInit();   配置触发

    2024年02月13日
    浏览(50)
  • 输入捕获模式测频率&PWM输入模式(PWMI)测占空比

    输出比较: 比较电路输入的CNT、CCR大小关系 ,在通道引脚输出高低电平 N/fc得到标准频率的时长,也就是待测频率的周期 测频法代码实现:修改对射式红外传感器计次(上升沿计次)、定时器外部时钟(1s中断)  测频法:定时器中断,并记录捕获次数;测周法:捕获中断

    2024年02月19日
    浏览(43)
  • STM32笔记——定时器输入捕获功能(测量PWM的频率和占空比)

    目录 一、概述 二、输入捕获功能 2.1 输入捕获简介 2.2 输入捕获通道  三、输入捕获功能测量PWM波的频率和占空比 3.1 测量频率的方法 3.2 测量过程         主要介绍通用定时器的输入捕获功能,输入信号由GPIO口进入输入捕获通道,之后输入部分对相应的TIx输入信号采样,并

    2024年02月06日
    浏览(85)
  • STM32 输入捕获模式测频率

    单片机学习! 目录 文章目录 前言 一、输入捕获测频率配置步骤 二、代码示例及注意事项 2.1 RCC开启时钟 2.2 GPIO初始化 2.3 配置时基单元 2.4 配置输入捕获单元 2.5 选择从模式的触发源 2.6 配置从模式为Reset 2.7 开启定时器 总结         博文介绍如何配置输入捕获电路来测

    2024年03月10日
    浏览(42)
  • 基于HAL库的STM32的单定时器的多路输入捕获测量脉冲频率(外部时钟实现)

    目录 写在前面 一般的做法(定时器单通道输入捕获) 以外部时钟的方式(高低频都适用) 测试效果 STM32的定时器本身有输入捕获的功能。可选择双端捕获,上升沿捕获或者是下降沿捕获。对应捕获频率来说,连续捕获上升沿或下降沿的时间间隔就是其脉冲的周期. 定时器设置频率

    2024年02月08日
    浏览(49)
  • stm32输入捕获测频率&PWM模式测频率占空比

    本文章转自B站江科大自化协    1,输入捕获测频率 接线图  目录结构 IC.h IC.c pwm.c PWM.h      main.c 编译下载出结果   2.PWM模式测频率占空比 接线图同上 目录结构同上 IC.c  IC.h main.c 编译下载测试     PS:测h   

    2024年02月15日
    浏览(37)
  • 基于HAL库的STM32单定时器多路输入捕获测量PWM的频率和占空比实现(状态机方式实现)

    目录  写在前面 先回顾下定时器的单路捕获PWM 多路捕获PWM的频率和占空比(状态机实现) 我的思路: 状态图 配置 给出示例代码 测试效果         先有了这篇文章实现了单定时器的多通道测量频率,以外部时钟的方式可测量任意频率的方波),奈何不能多路测试PWM波的频率,

    2024年02月12日
    浏览(51)
  • STM32——TIM输入捕获

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

    2023年04月08日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包