TIM输入捕获

一、IC(Input Capture)输入捕获

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

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

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

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

5、频率测量

测频法:在闸门时间T内,对上升沿计次,得到N,则频率 fx=N / T

测周法:两个上升沿内,以标准频率fc计次,得到N ,则频率 fx=fc / N

中界频率:测频法与测周法误差相等的频率点 fm=\sqrt{fc/T}

6、输入捕获通道

7、主从触发模式

8、输入捕获基本结构

9、PWMI基本结构

二、输入捕获模式测频率

1、按照以下接线方式连接,并将STLINK插到电脑上

2、输入捕获驱动函数模块

(1)输入捕获库函数功能

(2)输入捕获驱动函数模块

        IC.c

#include "stm32f10x.h"                  // Device header

void IC_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);		//开启时钟 TIM2:需要输出PWM 通道1引脚为PA0 TIM3:输入捕获 通道1引脚为PA6
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;			//配置GPIO
	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);
	
	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 设置大一些,防止计数溢出 PWM频率=更新频率=72M/(PSC+1)/(ARR+1)
	TIM_TimeBaseInitStructure.TIM_Prescaler=72 -1;		//PSC 决定测周法的标准频率fc	通过PSC调节频率,不会影响占空比
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
	
	TIM_ICInitTypeDef TIM_ICInitStructure;				//配置输入捕获
	TIM_ICInitStructure.TIM_Channel=TIM_Channel_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_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);			//配置TRGI的触发源为TI1FP1
	TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);		//配置从模式为Reset
	
	TIM_Cmd(TIM3,ENABLE);		//启动定时器
}

uint32_t IC_GetFreq(void)
{
	return 1000000  / (TIM_GetCapture1(TIM3) +	1);	//返回一个最新一个周期的频率值 fc=72M/(PSC+1),N=读取CCR的值 fx=fc/N
}

        IC.h

#ifndef __IC_H
#define __IC_H

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


#endif

(3)PWM驱动函数模块

        PWM.c

#include "stm32f10x.h"                  // Device header

void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
		
	GPIO_InitTypeDef GPIO_InitStructure;	//配置GPIO
	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);
	
	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  PWM频率=更新频率=72M/(PSC+1)/(ARR+1)
	TIM_TimeBaseInitStructure.TIM_Prescaler=720 - 1;	//PSC	通过PSC调节频率,不会影响占空比
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	
	TIM_OCInitTypeDef TIM_OCInitStructure;
	TIM_OCStructInit(&TIM_OCInitStructure);	//给所有参数赋初始值
	TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;		//输出模式
	TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;	//输出比较极性
	TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;	//输出使能
	TIM_OCInitStructure.TIM_Pulse=0;	//设置CCR寄存器值  占空比=CCR/(ARR+1)
	TIM_OC1Init(TIM2,&TIM_OCInitStructure);
	
	TIM_Cmd(TIM2,ENABLE);
}

/*
	改变占空比
*/
void PWM_SetCompare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM2,Compare);
}

/*
	改变频率
*/
void PWM_SetPrescaler(uint16_t Prescaler)
{
	TIM_PrescalerConfig(TIM2,Prescaler,TIM_PSCReloadMode_Immediate);
}

        PWM.h

#ifndef __PWM_H
#define __PWM_H

void PWM_Init(void);
void PWM_SetCompare1(uint16_t Compare);
void PWM_SetPrescaler(uint16_t Prescaler);

#endif

3、编写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();
	
	OLED_ShowString(1,1,"Freq:00000Hz");
	
	PWM_SetPrescaler(720 - 1);		//Freq=72M / (psc + 1) / 100
	PWM_SetCompare1(50);			//Duty= CCR / 100
	
	while(1)
	{
		OLED_ShowNum(1,6,IC_GetFreq(),5);
	}
}

4、实现效果

三、PWMI模式测频率占空比

1、输入捕获驱动函数模块

(1)输入捕获驱动函数模块

        IC.c

#include "stm32f10x.h"                  // Device header

void IC_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);		//开启时钟 TIM2:需要输出PWM 通道1引脚为PA0 TIM3:输入捕获 通道1引脚为PA6
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;			//配置GPIO
	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);
	
	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 设置大一些,防止计数溢出 PWM频率=更新频率=72M/(PSC+1)/(ARR+1)=1M/65536=15Hz 测频范围15Hz~1MHz
	TIM_TimeBaseInitStructure.TIM_Prescaler=72 -1;		//PSC 决定测周法的标准频率fc	通过PSC调节频率,不会影响占空比
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);
	
	TIM_ICInitTypeDef TIM_ICInitStructure;				//配置输入捕获
	TIM_ICInitStructure.TIM_Channel=TIM_Channel_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_ICInitStructure.TIM_Channel=TIM_Channel_2;
//	TIM_ICInitStructure.TIM_ICFilter=0xF;
//	TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Falling;
//	TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;
//	TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_IndirectTI;
//	TIM_ICInit(TIM3,&TIM_ICInitStructure);
	
	TIM_PWMIConfig(TIM3,&TIM_ICInitStructure);		//可以快捷的把电路配置成PWMI模式的标准结构 只支持通道1和通道2的配置
	
	TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);			//配置TRGI的触发源为TI1FP1
	TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);		//配置从模式为Reset
	
	TIM_Cmd(TIM3,ENABLE);		//启动定时器
}

uint32_t IC_GetFreq(void)
{
	return 1000000  / (TIM_GetCapture1(TIM3) +	1);	//返回一个最新一个周期的频率值 fc=72M/(PSC+1),N=读取CCR的值 fx=fc/N
}

uint32_t IC_GetDuty(void)
{
	return (TIM_GetCapture2(TIM3) + 1)*100 / (TIM_GetCapture1(TIM3) + 1);
}

        IC.h

#ifndef __IC_H
#define __IC_H

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

#endif

(2)PWM驱动函数模块

        PWM.c

#include "stm32f10x.h"                  // Device header

void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
		
	GPIO_InitTypeDef GPIO_InitStructure;	//配置GPIO
	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);
	
	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  PWM频率=更新频率=72M/(PSC+1)/(ARR+1)
	TIM_TimeBaseInitStructure.TIM_Prescaler=720 - 1;	//PSC	通过PSC调节频率,不会影响占空比
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	
	TIM_OCInitTypeDef TIM_OCInitStructure;
	TIM_OCStructInit(&TIM_OCInitStructure);	//给所有参数赋初始值
	TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;		//输出模式
	TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;	//输出比较极性
	TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;	//输出使能
	TIM_OCInitStructure.TIM_Pulse=0;	//设置CCR寄存器值  占空比=CCR/(ARR+1)
	TIM_OC1Init(TIM2,&TIM_OCInitStructure);
	
	TIM_Cmd(TIM2,ENABLE);
}

/*
	改变占空比
*/
void PWM_SetCompare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM2,Compare);
}

/*
	改变频率
*/
void PWM_SetPrescaler(uint16_t Prescaler)
{
	TIM_PrescalerConfig(TIM2,Prescaler,TIM_PSCReloadMode_Immediate);
}

        PWM.h

#ifndef __PWM_H
#define __PWM_H

void PWM_Init(void);
void PWM_SetCompare1(uint16_t Compare);
void PWM_SetPrescaler(uint16_t Prescaler);

#endif

2、编写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();
	
	OLED_ShowString(1,1,"Freq:00000Hz");
	OLED_ShowString(2,1,"Duty:00%");
	
	PWM_SetPrescaler(720 - 1);		//Freq=72M / (psc + 1) / 100
	PWM_SetCompare1(50);			//Duty= CCR / 100
	
	while(1)
	{
		OLED_ShowNum(1,6,IC_GetFreq(),5);
		OLED_ShowNum(2,6,IC_GetDuty(),2);

	}
}

3、实现效果

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值