基于STM32F103RCT6的输入捕获--测量频率和占空比

基于STM32F103RCT6的输入捕获,测量频率和占空比

相关知识

​ 在输入捕获模式下,当通道引脚出现指定电平跳变时,当前的cnt值将会锁存到CCR中,用于测量PWM的波形,频率,占空比,脉冲间隔,电平持续时间。

​ 每个高级计时器和通用计时器拥有4个输入捕获通道;可以配置PWMI模式同时测量频率和占空比;可配合主从模式实现硬件全自动测量。

​ 因此测量策略可以有:

​ 1.固定时间T内,对上升沿计次得到N,则频率 f=N/T ; 通常直接使用系统周期T 测周法 适合高频信号

​ 2.两个上升沿内,以某个标准频率 fc 计次得到N,则频率 f= fc/N; (即数每两次之间能塞下几个已知周期)测频法适合低频信号

​ 3.区分高频低频,需要参考中界频率 fm=(fc/T)^(1/2)

本文以测周法测量频率为例

硬件部分

芯片型号STM32F103RCT6

使用TIM3提供的测量电路,选择TIM3_CH1对应引脚PA6进行信号输入

代码部分

“IC.h”

#ifndef __IC_H
#define __IC_H

void IC_Init(void);
u32 IC_GetFreq(void);

#endif

“IC.c”

#include "stm32f10x.h"                  // Device header
#include "IC.h"

void IC_Init(void)
{	
	//开总线APB1控制的TIM3
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	//查看引脚定义表,开启所需引脚的GPIO时钟,这里TIM3需要用到PA6引脚触发
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    //使用结构体初始化GPIOA
	GPIO_InitTypeDef	GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;			//上拉输入模式	
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
    //内部时钟选择TIM3
	TIM_InternalClockConfig(TIM3);
	//配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;			//1分频
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;		//选择向上计数模式
	TIM_TimeBaseInitStruct.TIM_Period=65536-1;						//ARR-1,给最大值65536-1,防止计数溢出	
	TIM_TimeBaseInitStruct.TIM_Prescaler=72-1;						//PSC-1,预分频器72-1
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);				//时基单元初始化
	
	//初始化输入捕获单元
	TIM_ICInitTypeDef TIM_ICInitStruct;
	TIM_ICStructInit(&TIM_ICInitStruct);			//直接调用库函数粗略地初始化,后面再细改
	
	//TIM_PWMIConfig(TIM1,&TIM_ICInitStruct);
	
    TIM_ICInitStruct.TIM_Channel=TIM_Channel_1;		//选择通道 1 进行捕获
	TIM_ICInitStruct.TIM_ICFilter=0xF;				//滤波器,设定远高于信号频率的值,滤除高频噪声,使得信号更加平滑
	TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising;	//上升沿触发
	TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1;		//1分频,就是保持原有频率
	TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;	//选择触发信号输入引脚,直连,交叉,或者TRC引脚
	TIM_ICInit(TIM3,&TIM_ICInitStruct);				//用上面修改过的结构体初始化TIM3
	
	TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);		//TIM3的触发源选择 滤波时钟输入通道 1
	
	TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);	//选择从模式为Reset
	TIM_Cmd(TIM3,ENABLE);				//设置好了之后,启动定时器TIM3
}
u32 IC_GetFreq(void)
{
	return 10000/TIM_GetCapture1(TIM3);		// 测周法得到f=fc/N   其中fc为系统时钟,N为CCR值
}

“main.c”

#include "stm32f10x.h"                  // Device header

int main()
{
	while(1){
        
    }
}

改进

使用PWMI模式测量频率和占空比

对代码"IC.h"进行更改

#ifndef __IC_H
#define __IC_H

void IC_Init(void);
u32 IC_GetFreq(void);
u32 IC_GetDuty(void);

#endif

对代码"IC.c"进行更改

#include "stm32f10x.h"                  // Device header
#include "IC.h"

void IC_Init(void)
{	

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

	GPIO_InitTypeDef	GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;			
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	

	TIM_InternalClockConfig(TIM3);

	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;			
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;		
	TIM_TimeBaseInitStruct.TIM_Period=65536-1;							
	TIM_TimeBaseInitStruct.TIM_Prescaler=72-1;						
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);				
	
	
	TIM_ICInitTypeDef TIM_ICInitStruct;
	TIM_ICStructInit(&TIM_ICInitStruct);			
	
    TIM_ICInitStruct.TIM_Channel=TIM_Channel_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);	
    
    //直接调用库函数开启PWMI模式
    TIM_PWMIConfig(TIM3,&TIM_ICInitStruct);
    /*效果等价于
    TIM_ICInitStruct.TIM_Channel=TIM_Channel_2;					//改成通道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);	
	*/
    
	TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);		
	
	TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);	
	TIM_Cmd(TIM3,ENABLE);				
}
u32 IC_GetFreq(void)
{
	return 10000/TIM_GetCapture1(TIM3);		
}

u32 IC_GetDuty(void)		
{	//高电平计数CCR2+1.整个周期计数CCR1+1,二者比值得到占空比,乘100得到百分比的数字部分
	return 100*(TIM_GetCapture2(TIM3)+1)/(TIM_GetCapture1(TIM3)+1) ;//
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值