TIM输入捕获及其应用场景

news2024/10/6 5:49:48

一,TIM输入捕获介绍(IC(Input Capture)输入捕获)

  • 定义:输入捕获模式下,当通道输入引脚出现指定电平跳变(如上升沿或下降沿)时,当前定时器的计数值(CNT)会被锁存到对应的捕获/比较寄存器(CCR)中。这一过程可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数。
  • 工作原理:预设分频系数和捕获沿,检测定时器通道输入的边沿信号。当信号发生跳变并且满足预设条件时,将定时器当前值寄存器CNTx的值存入捕获比较寄存器CCRx中。
  • 作用:
  • 可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数
  • 每个高级定时器和通用定时器都拥有4个输入捕获通道
  • 可配置为PWMI模式,同时测量频率和占空比
  • 可配合主从触发模式,实现硬件全自动测量

二、TIM输入捕获的基本步骤

  1. 开启时钟:使能定时器和相关GPIO端口的时钟。
  2. 初始化GPIO:将GPIO端口配置为输入模式,并根据需要选择上拉输入或浮空输入。
  3. 配置时钟源:选择定时器的时钟源,通常是内部时钟。
  4. 初始化时基单元:配置定时器的预分频器(PSC)、自动重装载值(ARR)等参数,以控制定时器的计数频率和周期。
  5. 初始化输入捕获单元:配置输入捕获通道、极性、滤波器、分频器等参数。例如,选择捕获通道、设置捕获极性(上升沿或下降沿)、配置输入捕获映射通道、设置预分频系数等。
  6. 触发源选择以及从模式配置:选择定时器的触发源,并配置从模式(如复位模式),以便在捕获事件发生时执行特定的操作(如清零计数器)。
  7. 使能定时器:启动定时器,开始捕获外部输入信号。

三、TIM输入捕获的应用场景

1,频率测量

通过测量一定时间内输入信号的上升沿(或下降沿)数量,可以计算出输入信号的频率。常用的方法包括测频法和测周法。

TIM测量频率时,测频法、测周法以及频率测量法(通常指直接的频率测量,不涉及等精度测量等高级方法)各有特点,适用于不同的场景。以下是这三种方法的详细比较及适用场景分析:

1.1、测频法

定义与原理

  • 测频法是在一个固定的闸门时间(如1秒)内,对被测信号的上升沿(或下降沿)进行计数,得到计数值N。然后,通过公式f=N/T计算出被测信号的频率,其中f为被测信号的频率,T为闸门时间。

特点

  • 适合于高频信号的测量
  • 测量结果更新较慢,因为每次测量都需要等待整个闸门时间结束。
  • 测量误差与被测信号的频率成反比,即信号频率越高,相对误差越小。

适用场景

  • 当被测信号的频率较高时,测频法能够提供较为准确的测量结果

1.2、测周法

定义与原理

  • 测周法是通过测量被测信号的一个完整周期的时间T,然后通过公式f=1/T计算出被测信号的频率。在实际应用中,通常使用一个已知的标准频率信号作为计数器的时钟脉冲,测量被测信号周期内的标准频率脉冲数N,再通过公式f=fc/N计算被测信号的频率,其中fc为标准频率信号的频率。

特点

  • 适合于低频信号的测量。
  • 测量结果更新较快,因为每次测量只需要等待一个信号周期结束。
  • 测量误差与被测信号的频率和标准频率信号的频率有关,信号频率越低或标准频率越高,相对误差越小。

适用场景

  • 当被测信号的频率较低时,测周法能够提供较为准确的测量结果

1.3、频率测量法(直接测量法)

定义与原理

  • 频率测量法通常指的是在一段时间内直接对被测信号的脉冲数进行计数,然后根据计数结果和测量时间计算出被测信号的频率。这种方法可以视为测频法的一种简化形式,但不涉及等精度测量等高级技术。

特点

  • 适用于频率范围较宽的信号测量,但精度可能受限于测量时间和信号稳定性。
  • 测量误差与被测信号的频率、测量时间以及信号稳定性等因素有关。

适用场景

  • 在对测量精度要求不高,且信号频率范围较宽的情况下,可以使用频率测量法进行初步的频率估算。

1.4、总结与选择建议

  • 在选择测量方法时,需要根据被测信号的频率范围、测量精度要求以及测量设备的性能等因素进行综合考虑。
  • 对于高频信号,测频法通常更为适用;而对于低频信号,测周法则更具优势。
  • 如果需要进一步提高测量精度,可以考虑采用等精度测量等高级方法,这些方法通常结合了测频法和测周法的优点,能够在宽频率范围内提供高精度的测量结果。

在实际应用中,还需要考虑信号的稳定性、噪声水平以及测量设备的精度和分辨率等因素对测量结果的影响。

2,脉宽测量

通过测量输入信号高电平(或低电平)的持续时间,可以计算出脉宽。这通常涉及到两次捕获操作,分别记录脉宽的开始和结束时刻。

3,PWM输入模式

在PWM输入模式下,定时器可以同时测量PWM波形的频率和占空比。这通常需要使用两个捕获通道,一个用于测量周期,另一个用于测量占空比。

四、TIM输入捕获的注意事项

  • 滤波设置:为了避免高频噪声的干扰,可以配置输入捕获滤波器。滤波器可以对输入信号进行采样和平均处理,从而滤除高频噪声。
  • 中断处理:如果需要在捕获事件发生时执行特定的操作(如数据处理、状态更新等),可以配置捕获中断。当中断发生时,微控制器会跳转到中断服务程序进行处理。
  • 资源共享:高级定时器和通用定时器通常拥有多个输入捕获通道和输出比较通道,这些通道共用CCR寄存器。因此,对于同一个定时器来说,输入捕获和输出比较功能不能同时使用同一个通道。

综上所述,TIM输入捕获是STM32等微控制器中定时器的一个强大功能,它允许处理器精确地捕获外部输入信号的时间特性。通过合理配置和使用输入捕获功能,可以实现各种复杂的测量和控制任务。

五,输入捕获通道流程

 

它允许用户捕获外部信号的特定事件(如上升沿或下降沿),并记录下此时定时器的计数值。输入捕获的基本结构主要包括以下几个部分:

一、输入通道

每个定时器都拥有多个输入捕获通道(如CH1到CH4),这些通道可以连接到微控制器的不同GPIO引脚上。当外部信号通过GPIO引脚输入到定时器时,输入捕获功能开始工作。

二、输入滤波器

输入滤波器用于滤除外部信号中的噪声和干扰,确保输入捕获的准确性。用户可以通过配置滤波器的参数(如采样率和判定次数)来调整滤波效果。

三、边沿检测器

边沿检测器用于检测外部信号的边沿变化(如上升沿或下降沿)。当检测到边沿变化时,边沿检测器会触发输入捕获操作。

四、捕获/比较寄存器(CCR)

捕获/比较寄存器用于存储输入捕获时定时器的计数值。每当发生输入捕获时,当前定时器的计数值会被锁存到对应的CCR中,供用户读取。

五、分频器

分频器用于控制输入捕获的触发频率。用户可以通过设置分频系数来降低输入捕获的触发频率,从而避免过高的中断频率对系统性能的影响。

六、触发模式和从模式

STM32的定时器还支持多种触发模式和从模式,这些模式可以与其他定时器的输入捕获或输出比较功能配合使用,实现更复杂的定时和控制功能。例如,主从触发模式允许一个定时器作为主定时器控制另一个定时器的计数和捕获操作。

七、配置与初始化

在使用输入捕获功能之前,用户需要对定时器进行配置和初始化。这包括设置定时器的时钟源、预分频器、自动重装载寄存器、输入捕获通道的参数(如滤波器、边沿极性、分频系数等)以及启动定时器。

六,输入捕获模式测频率

 1,相关库函数解释

void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);//初始化定时器输入捕获功能的函数
void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);//通常用于配置定时器的PWM输入捕获(PWMI)功能。
void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);//用于主模式触发源选择
void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource);//选择输出触发源
void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);//选择从模式

void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);//分别单独配置通道1,2,3,4的分频器
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);

uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx);//分别读取四个通道的CCR
uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx);

2,输入捕获模式测量频率代码

我们需要根据输入捕获基本结构来进行配置,流程如下:

  • 1,RCC开启时钟,把GPIO和TIM的时钟打开
  • 2,GPIO初始化,把GPIO配置成输入模式,一般选择上拉模式或者浮空输入模式
  • 3,配置时基单元,让CNT计数器在内部时钟的驱动下自增运行
  • 4,配置输入捕获单元,包括滤波器,极性,直连通道还是交叉通道,分频器这些参数
  • 5,选择从模式的触发源,触发源选择为TI1FP1,可以直接调用一个库函数
  • 6,选择触发源之后执行Reset操作,这里也是直接调用一个库函数
  • 7,当所有电路配置好后,调用TIM_Cmd函数,开启定时器

PWM.c

#include "stm32f10x.h"                  // Device header

/**
  * 函    数:PWM初始化
  * 参    数:无
  * 返 回 值:无
  */
void PWM_Init(void)
{
	/*开启时钟*/
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);			//开启TIM2的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);			//开启GPIOA的时钟
	
	/*GPIO重映射*/
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);			//开启AFIO的时钟,重映射必须先开启AFIO的时钟
//	GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);			//将TIM2的引脚部分重映射,具体的映射方案需查看参考手册
//	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);		//将JTAG引脚失能,作为普通GPIO引脚使用
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;		//GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);							//将PA0引脚初始化为复用推挽输出	
																	//受外设控制的引脚,均需要配置为复用模式		
	
	/*配置时钟源*/
	TIM_InternalClockConfig(TIM2);		//选择TIM2为内部时钟,若不调用此函数,TIM默认也为内部时钟
	
	/*时基单元初始化*/
	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的值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;				//预分频器,即PSC的值
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;            //重复计数器,高级定时器才会用到
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);             //将结构体变量交给TIM_TimeBaseInit,配置TIM2的时基单元
	
	/*输出比较初始化*/
	TIM_OCInitTypeDef TIM_OCInitStructure;							//定义结构体变量
	TIM_OCStructInit(&TIM_OCInitStructure);							//结构体初始化,若结构体没有完整赋值
																	//则最好执行此函数,给结构体所有成员都赋一个默认值
																	//避免结构体初值不确定的问题
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;				//输出比较模式,选择PWM模式1
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;		//输出极性,选择为高,若选择极性为低,则输出高低电平取反
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	//输出使能
	TIM_OCInitStructure.TIM_Pulse = 0;								//初始的CCR值
	TIM_OC1Init(TIM2, &TIM_OCInitStructure);						//将结构体变量交给TIM_OC1Init,配置TIM2的输出比较通道1
	
	/*TIM使能*/
	TIM_Cmd(TIM2, ENABLE);			//使能TIM2,定时器开始运行
}

/**
  * 函    数:PWM设置CCR
  * 参    数:Compare 要写入的CCR的值,范围:0~100
  * 返 回 值:无
  * 注意事项:CCR和ARR共同决定占空比,此函数仅设置CCR的值,并不直接是占空比
  *           占空比Duty = CCR / (ARR + 1)
  */
void PWM_SetCompare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM2, Compare);		//设置CCR1的值
}

/**
  * 函    数:PWM设置PSC
  * 参    数:Prescaler 要写入的PSC的值,范围:0~65535
  * 返 回 值:无
  * 注意事项:PSC和ARR共同决定频率,此函数仅设置PSC的值,并不直接是频率
  *           频率Freq = CK_PSC / (PSC + 1) / (ARR + 1)
  */
void PWM_SetPrescaler(uint16_t Prescaler)
{
	TIM_PrescalerConfig(TIM2, Prescaler, TIM_PSCReloadMode_Immediate);		//设置PSC的值
}

IC.c

#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_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);							//将PA6引脚初始化为上拉输入
	
	/*配置时钟源*/
	TIM_InternalClockConfig(TIM3);		//选择TIM3为内部时钟,若不调用此函数,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,配置TIM3的时基单元
	
	/*输入捕获初始化*/
	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使能*/
	TIM_Cmd(TIM3, ENABLE);			//使能TIM3,定时器开始运行
}

/**
  * 函    数:获取输入捕获的频率
  * 参    数:无
  * 返 回 值:捕获得到的频率
  */
uint32_t IC_GetFreq(void)
{
	return 1000000 / (TIM_GetCapture1(TIM3) + 1);		//测周法得到频率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.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"

int main(void)
{
	/*模块初始化*/
	OLED_Init();		//OLED初始化
	PWM_Init();			//PWM初始化
	IC_Init();			//输入捕获初始化
	
	/*显示静态字符串*/
	OLED_ShowString(1, 1, "Freq:00000Hz");		//1行1列显示字符串Freq:00000Hz
	
	/*使用PWM模块提供输入捕获的测试信号*/
	PWM_SetPrescaler(720 - 1);					//PWM频率Freq = 72M / (PSC + 1) / 100
	PWM_SetCompare1(50);						//PWM占空比Duty = CCR / 100
	
	while (1)
	{
		OLED_ShowNum(1, 6, IC_GetFreq(), 5);	//不断刷新显示输入捕获测得的频率
	}
}

 3,PWMI模式测频率占空比代码

我们需要根据此图来编写代码

 主要修改IC.c代码

#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_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);							//将PA6引脚初始化为上拉输入
	
	/*配置时钟源*/
	TIM_InternalClockConfig(TIM3);		//选择TIM3为内部时钟,若不调用此函数,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,配置TIM3的时基单元
	
	/*PWMI模式初始化*/
	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_PWMIConfig(TIM3, &TIM_ICInitStructure);						//将结构体变量交给TIM_PWMIConfig,配置TIM3的输入捕获通道
																	//此函数同时会把另一个通道配置为相反的配置,实现PWMI模式

	/*选择触发源及从模式*/
	TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);					//触发源选择TI1FP1
	TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);					//从模式选择复位
																	//即TI1产生上升沿时,会触发CNT归零
	
	/*TIM使能*/
	TIM_Cmd(TIM3, ENABLE);			//使能TIM3,定时器开始运行
}

/**
  * 函    数:获取输入捕获的频率
  * 参    数:无
  * 返 回 值:捕获得到的频率
  */
uint32_t IC_GetFreq(void)
{
	return 1000000 / (TIM_GetCapture1(TIM3) + 1);		//测周法得到频率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.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"

int main(void)
{
	/*模块初始化*/
	OLED_Init();		//OLED初始化
	PWM_Init();			//PWM初始化
	IC_Init();			//输入捕获初始化
	
	/*显示静态字符串*/
	OLED_ShowString(1, 1, "Freq:00000Hz");		//1行1列显示字符串Freq:00000Hz
	OLED_ShowString(2, 1, "Duty:00%");			//2行1列显示字符串Duty:00%
	
	/*使用PWM模块提供输入捕获的测试信号*/
	PWM_SetPrescaler(720 - 1);					//PWM频率Freq = 72M / (PSC + 1) / 100
	PWM_SetCompare1(50);						//PWM占空比Duty = CCR / 100
	
	while (1)
	{
		OLED_ShowNum(1, 6, IC_GetFreq(), 5);	//不断刷新显示输入捕获测得的频率
		OLED_ShowNum(2, 6, IC_GetDuty(), 2);	//不断刷新显示输入捕获测得的占空比
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2191236.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python画图|步进图基本教程

有些时候,画顺滑的图形不能满足表达需求,可能需要使用步进图形来辅助表达。 【1】官网教程 首先我们乖乖进入官网,使用下述链接直达: Step Demo — Matplotlib 3.9.2 documentation 这里有两个图形作为示例,为高效…

第二百六十九节 JPA教程 - JPA查询OrderBy两个属性示例

JPA教程 - JPA查询OrderBy两个属性示例 以下代码显示如何按两个属性排序,一个升序,另一个降序。 List l em.createQuery("SELECT e FROM Professor e " "JOIN e.department d ORDER BY d.name, e.name DESC").getResultList();例子…

传感器模块编程实践(二)W5500 SPI转以太网模块简介及驱动源码

文章目录 一.概要二.W5500芯片介绍W5500通讯协议介绍 三.W5500模块介绍四.W5500模块原理图五.W5500以太网模通讯实验六.CubeMX工程源代码下载七.小结 一.概要 我们介绍过单片机的以太网系统一般是由:单片机MACPHYRJ45。有些单片机比如STM32F407VET6芯片内部自带MAC…

如何在Allegro中创建实现可以走线但不能铺铜的区域

第一步,点击Setup-Areas-Shape Keepout,在需要禁止铺铜的区域画好禁示区域; 第二步,画好后,此区域内的动态铺铜会自动避让,而走线不会报错。 参考: Cadence allegro软件如何设置区域为禁止铺铜…

十、kotlin的协程

协程 基本概念定义组成挂起和恢复结构化并发协程构建器作用域构建器挂起函数阻塞与非阻塞runBlocking全局协程像守护线程 Job的生命周期 常用函数延时和等待启动和取消启动取消 暂停 协程启动调度器启动方式启动模式线程上下文继承的定义继承的公式 协程取消与超时取消挂起点取…

vite学习教程02、vite+vue2配置环境变量

文章目录 前言1、安装依赖2、配置环境变量3、应用环境变量4、运行和构建项目资料获取 前言 博主介绍:✌目前全网粉丝3W,csdn博客专家、Java领域优质创作者,博客之星、阿里云平台优质作者、专注于Java后端技术领域。 涵盖技术内容&#xff1…

回归树练习,泰坦尼克号幸存者的预测

回归树练习,泰坦尼克号幸存者的预测 数据集下载地址 https://download.csdn.net/download/AnalogElectronic/89846327 我们来看看train.csv文件,它包含了891个样本,每个样本代表一个乘客。这些样本的数据包括乘客的年龄(Age&…

Allegro 中如何关闭DRC检查

setup--constraints--modes 在这里就能选择关闭 Line to Route Keepout Spacing 的DRC检查了

懒洋洋浅谈--机器学习框架

机器学习,这个词汇听起来就像是科幻小说里那些能够自我进化的机器人一样神秘而强大。但别担心,让我用一种更接地气的方式来揭开它的神秘面纱。 关于机器学习,有一个非常有意思的介绍误闯机器学习(第一关-概念和流程)-C…

Redis:set类型

Redis:set类型 set命令SADDSMEMBERSSISMEMBERSCARDSPOPSRANDMEMBERSMOVESREM 集合间操作SINTERSINTERSTORESUNIONSUNIONSTORESDIFFSDIFFSTORE 内部编码intsethashtable 当把一些关联的数据放到一起,就构成一个集合。在Redis中,使用set类型维护…

为何没有Deepin 24了

今天在Deepin社区公布了一则消息,未来将调整Deepin社区版的发布周期和命名规则,原文内容如下: 首先说重点,未来 deepin 社区将推行以“年”为基准单位来界定版本号的策略: 每年发布1个大版本,提供2个重要…

MISC - 第12天(pyc反编译、图片宽高复原、Ziperello暴力破解工具)

前言 各位师傅大家好,我是qmx_07,今天继续讲解MISC的相关知识 喵喵喵 附件信息: 尝试了常规的binwalk,foremost扫描是否有隐藏文件、均失败 在stegsolve工具发现 Red plan 0、 Blue plan 0、 Green plan 0 有问题,怀疑是LSB隐写 Data Extr…

ISO IEC 18004 2015 PDF 文字版下载

ISO_IEC_18004_2015_en-US - 道客巴巴 (doc88.com)https://www.doc88.com/p-67816330893254.html

CPython Internals English PDF 下载地址分享

CPython Internals Your Guide to the Python 3 Interpreter.pdf官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘123云盘为您提供CPython Internals Your Guide to the Python 3 Interpreter.pdf最新版正式版官方版绿色版下载,CPython Internals Your Guide to the Pytho…

【图论】树剖(上):重链剖分

一、前置知识清单 深度优先搜索DFS 点我复习图的存储 复习链接敬请期待树状数组 点我复习 二、树剖简介 树剖(树链剖分),是一种把树划分成链的算法,该算法分为重链剖分和长链剖分。 本文仅讨论重链剖分,长链剖分目前…

基于SpringBoot的学习资源共享平台

运行环境: jdk8tomcat9mysqlIntelliJ IDEAmavennodejs 设计选用前后端分离的单体架构方式 后端:SpringBootMybatis-PluslogbackElasticsearchRedisMySQLJwtsmtp阿里云OSS 前端:WebPackVueJsAnt Designaxios 主要模块:反馈管理、资源管理、…

Django学习笔记二:数据库操作详解

Django框架提供了一个功能强大的ORM(对象关系映射)系统,使得开发者可以使用Python代码来操作数据库,而无需编写复杂的SQL语句。以下是Django数据库操作的一些基本概念和方法: 模型定义 在Django中,模型是…

大模型基础:基本概念、Prompt、RAG、Agent及多模态

随着大模型的迅猛发展,LLM 作为人工智能的核心力量,正以前所未有的方式重塑着我们的生活、学习和工作。无论是智能语音助手、自动驾驶汽车,还是智能决策系统,大模型都是幕后英雄,让这些看似不可思议的事情变为可能。本…

Spring源码-AOP具体源码

1.类ProxyFactory 核心方法:getProxy 1.DefaultAopProxyFactory#createAopProxy 判断使用JDK还是CGLIB动态代理的代码如下: Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {// 如果ProxyFactory的isOp…

北京市大兴区启动乐享生活 寻味大兴 美食嘉年华 系列促销费活动

北京市大兴区启动乐享生活 寻味大兴 系列促销费活动 区商务局副局长 兰莉 致开幕辞 区餐饮行业协会会长 董志明 介绍活动内容 2024年9月30日,由大兴区商务局主办、大兴区餐饮行业协会承办,并得到高米店街道和大兴绿地缤纷城大力支持的“乐享生活 寻味大…