目录

一、输入捕获

1.1 输入捕获简介

1.2 频率测量

1.3 输入捕获通道

1.4 主从触发模式

二、输入捕获模拟测频率

2.1 输入捕获基本结构

2.2 接线图

2.3 程序源码

三、PWMI测量频率和占空比

3.1 PWMI的基本结构

3.2 程序:


一、输入捕获

1.1 输入捕获简介

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

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

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

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

1.2 频率测量

测频法:在时间T内,测得N个上升沿,说明有N个周期的波形。每一个周期的时间就是T/N。频率就是N/T;

测周法:在两个上升沿内,以标准频率fx计数,得到N,那么两个上升沿内的时间是N/fx。那么频率是fx/N;

测频法适合频率大的,测周法适合频率小的。

1.3 输入捕获通道

1.4 主从触发模式

二、输入捕获模拟测频率

2.1 输入捕获基本结构

就一个通道,只能用来测频率


 

2.2 接线图

2.3 程序源码

配置步骤:

  • RCC开启TIM2和GPIOA的时钟
  • 初始化GPIO,设置输入模式为上拉输入或浮空输入模式
  • 配置时基单元,让CNT在内部时钟的作用下开始计数
  • 配置输入捕获单元
  • 选择从模式的触发源
  • 选择触发后执行的操作,列入RESET操作
  • TIM_Cmd();

源代码:

IC.h文件

#ifndef __IC__H
#define __IC__H

void IC_Init(void);
uint32_t IC_GetFreq(void);

#endif

IC.c文件:

#include "stm32f10x.h"                  // Device header

void IC_Init(void)
{
	//1.开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	
	//2.初始化GPIO
	GPIO_InitTypeDef GPIOA_InitStruction;
	GPIOA_InitStruction.GPIO_Mode = GPIO_Mode_IPU;
	GPIOA_InitStruction.GPIO_Pin = GPIO_Pin_6;
	GPIOA_InitStruction.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIOA_InitStruction);
	
	//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 = 65535 - 1;   //ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;   //PSC
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	
	//4.配置输入捕获通道
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;   //选择通道1~4
	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);
	
	//5.配置主从模式,这里是配置从模式的触发源
	//  人话:告诉TIM3,以后TIM_TS_TI1FP1来触发它
	TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
	
	//6.配置从模式为RESET
	//  人话:TIM_TS_TI1FP1这个通道来触发源后,执行RESET的操作
	TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
	
	TIM_Cmd(TIM3, ENABLE);
}

//读取CCR函数
uint32_t IC_GetFreq(void)
{
	return 1000000 / (TIM_GetCapture1(TIM3) + 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();
	PWM_Init();
	IC_Init();
	
	PWM_SetPrescaler(720 - 1);
	PWM_SetCompare1(39);

	OLED_ShowString(1,1,"Freq:00000Hz");

	while(1)
	{
		OLED_ShowNum(1,6,IC_GetFreq(),5);
	}
}

配置输入捕获代码:

//4.配置输入捕获通道
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;   //选择通道1~4
	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);

第三个参数TIM_ICPolarity:

参数:

第四个参数TIM_ICPrescaler:

参数:

第五个参数TIM_ICSelection:

参数:

三、PWMI测量频率和占空比

3.1 PWMI的基本结构

3.2 程序:

lc.h模块:

#ifndef __IC__H
#define __IC__H

void IC_Init(void);
uint32_t IC_GetFreq(void);
uint32_t IC_GetDuty(void);

#endif

lc.c模块:

#include "stm32f10x.h"                  // Device header

void IC_Init(void)
{
	//1.开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	
	//2.初始化GPIO
	GPIO_InitTypeDef GPIOA_InitStruction;
	GPIOA_InitStruction.GPIO_Mode = GPIO_Mode_IPU;
	GPIOA_InitStruction.GPIO_Pin = GPIO_Pin_6;
	GPIOA_InitStruction.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIOA_InitStruction);
	
	//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 = 65535 - 1;   //ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;   //PSC
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	
	//4.配置输入捕获通道
	TIM_ICInitTypeDef TIM_ICInitStructure;
	TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;   //选择通道1~4
	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);
	
	//5.配置主从模式,这里是配置从模式的触发源
	//  人话:告诉TIM3,以后TIM_TS_TI1FP1来触发它
	TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);
	
	//6.配置从模式为RESET
	//  人话:TIM_TS_TI1FP1这个通道来触发源后,执行RESET的操作
	TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
	
	TIM_Cmd(TIM3, ENABLE);
}

//读取CCR函数
uint32_t IC_GetFreq(void)
{
	return 1000000 / (TIM_GetCapture1(TIM3) + 1);
}

uint32_t IC_GetDuty(void)
{
	return (TIM_GetCapture2(TIM3) + 1) * 100 / (TIM_GetCapture1(TIM3) + 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();
	PWM_Init();
	IC_Init();
	
	PWM_SetPrescaler(720 - 1);
	PWM_SetCompare1(39);

	OLED_ShowString(1,1,"Freq:00000Hz");
	OLED_ShowString(2,1,"Duty:000%");
	
	while(1)
	{
		OLED_ShowNum(1,6,IC_GetFreq(),5);
		OLED_ShowNum(2,6,IC_GetDuty(),3);
	}
}

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐