STM32-TIM输入捕获测量频率和占空比

涉及知识点:

1.输入捕获模式

2.频率的测量方法

3.主从触发模式

4.PWMI测量占空比

正文:

1.输入捕获(Input Capture)简称为IC,在输入捕获模式下,当通道输入引脚出现指定电平跳变时(可以为上升沿,下降沿或都触发),当前的CNT的值被锁存到CCR中,通过读取当前状态CCR的值我们可以得知从开始计数到指定状态时CNT所计的值。如果CNT每次被锁存之后立即清0,则可以实现实时测量频率。

 

2.频率的测量方法:

测频法:在指定时间内求得对上升沿的计次,则f=N/T,如果指定时间为单位时间,那么N就等于f。

测周法:利用标准频率在两个上升沿之内计次,T=(1/fc)*N => f=fc/N

中界频率为测频法与测周法误差相等的频率点,令上面两式相等得到的频率即为中界频率。

 

3.主从触发模式

主模式:自己作为控制端去控制其他外设

从模式:用于接收其他外设或者自身引脚的信息,产生指定动作

在本实验中,可以通过从模式进行CNT清0的操作

4.PWMI基本结构

使用两个通道,一个通道与上述输入捕获模式相同,用于测量频率,第二个通道的区别在于为下降沿触发,提前将CNT锁存到对应CCR寄存器内,并且不会清0,而是等到下一个上升沿再清0,所以第二个通道的计次就代表着高电平对应的频率或周期。

代码部分:

 首先配置GPIO口和开启时钟

然后配置输出PWM波形产生一定频率的波,跟上一节相同,配置时基单元,配置输出比较通道

然后配置输入捕获通道,需要配置时基单元,设定自动重装值和预分频值得到标准频率,设置主从触发模式进行CNT清0,GPIO口与时钟相对应。

PWM波形:

#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_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);
	TIM_InternalClockConfig(TIM2);
	
	TIM_TimeBaseInitTypeDef TIM_InitStructure;
	TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;  //时钟分频,主要控制滤波系数
	TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数
	TIM_InitStructure.TIM_Period = 100-1;  //ARR
  TIM_InitStructure.TIM_Prescaler = 720-1;  //PSC预分频值
  TIM_InitStructure.TIM_RepetitionCounter =0x00;	
	TIM_TimeBaseInit(TIM2,&TIM_InitStructure);
	
	TIM_OCInitTypeDef TIM_OCInitStucture;  //配置输出比较模块
	TIM_OCStructInit(&TIM_OCInitStucture);
	TIM_OCInitStucture.TIM_OCMode= TIM_OCMode_PWM1;  //输出模式
	TIM_OCInitStucture.TIM_OCPolarity = TIM_OCPolarity_High;  //极性选择
	TIM_OCInitStucture.TIM_OutputState = TIM_OutputState_Enable;  //使能
	TIM_OCInitStucture.TIM_Pulse =0 ;  //配置CCR
	TIM_OC1Init(TIM2,&TIM_OCInitStucture);
	
	TIM_Cmd(TIM2,ENABLE);
}

void PWM_SetCompare1(uint16_t Compare)  //用于在运行钟调节CCR,compare为比较值
{
   TIM_SetCompare1(TIM2,Compare);
}

void PWM_SetPrescaler(uint16_t Prescalar)  //用于改变频率
{
	TIM_PrescalerConfig(TIM2,Prescalar,TIM_PSCReloadMode_Immediate);
}

输入捕获:

#include "stm32f10x.h"                  // Device header


void IC_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  //开启定时器3
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);  //配置GPIO
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;  //上拉输入
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;  //PA6的通道1
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz ;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	TIM_InternalClockConfig(TIM3);  //
	
	TIM_TimeBaseInitTypeDef TIM_InitStructure;          		 //时基单元的配置
	TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1; 		 //时钟分频,主要控制滤波系数
	TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;  //向上计数
	TIM_InitStructure.TIM_Period = 65536-1; 								 //ARR
  TIM_InitStructure.TIM_Prescaler = 72-1;  								 //PSC预分频值
  TIM_InitStructure.TIM_RepetitionCounter =0x00;	
	TIM_TimeBaseInit(TIM3,&TIM_InitStructure);
	
	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_PWMIConfig(TIM3,&TIM_ICInitStructure);                         //快捷配置PWMI模式,意为将上述参数取反配置
	
	TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);     //选择触发源
	TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);  //配置从模式
	
	
	TIM_Cmd(TIM3,ENABLE);

}

uint32_t  IC_GetFreq(void)  //获取频率
{
		return 1000000/ TIM_GetCapture1(TIM3);
}

uint32_t  IC_GetDuty(void)  //获取占空比
{
	return 100*(TIM_GetCapture2(TIM3)/TIM_GetCapture1(TIM3));
}

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是STM32F103 TIM1输入捕获测量频率,周期和占空比的代码示例: 1. 配置TIM1为输入捕获模式: ```c TIM_ICInitTypeDef TIM_ICInitStructure; TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_ICInit(TIM1, &TIM_ICInitStructure); TIM_Cmd(TIM1, ENABLE); ``` 2. 定义变量存储捕获的值: ```c uint16_t IC1Value = 0; uint16_t IC2Value = 0; ``` 3. 在TIM1输入捕获中断处理函数中获取捕获的值: ```c void TIM1_CC_IRQHandler(void) { if(TIM_GetITStatus(TIM1, TIM_IT_CC1) != RESET) { TIM_ClearITPendingBit(TIM1, TIM_IT_CC1); IC1Value = TIM_GetCapture1(TIM1); } else if(TIM_GetITStatus(TIM1, TIM_IT_CC2) != RESET) { TIM_ClearITPendingBit(TIM1, TIM_IT_CC2); IC2Value = TIM_GetCapture2(TIM1); } } ``` 4. 计算测量值: ```c uint32_t TIM1Freq = SystemCoreClock / (TIM_GetPrescaler(TIM1) + 1); uint32_t TIM1Period = (IC2Value - IC1Value + 0xFFFF) % 0xFFFF; float TIM1DutyCycle = 100.0 * (IC2Value - IC1Value) / TIM1Period; ``` 其中,`SystemCoreClock`为系统时钟频率。 完整代码示例: ```c #include "stm32f10x.h" uint16_t IC1Value = 0; uint16_t IC2Value = 0; int main(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period = 0xFFFF; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); TIM_ICInitTypeDef TIM_ICInitStructure; TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; TIM_ICInitStructure.TIM_ICFilter = 0x0; TIM_ICInit(TIM1, &TIM_ICInitStructure); TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling; TIM_ICInit(TIM1, &TIM_ICInitStructure); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_ITConfig(TIM1, TIM_IT_CC1 | TIM_IT_CC2, ENABLE); TIM_Cmd(TIM1, ENABLE); while(1); } void TIM1_CC_IRQHandler(void) { if(TIM_GetITStatus(TIM1, TIM_IT_CC1) != RESET) { TIM_ClearITPendingBit(TIM1, TIM_IT_CC1); IC1Value = TIM_GetCapture1(TIM1); } else if(TIM_GetITStatus(TIM1, TIM_IT_CC2) != RESET) { TIM_ClearITPendingBit(TIM1, TIM_IT_CC2); IC2Value = TIM_GetCapture2(TIM1); } uint32_t TIM1Freq = SystemCoreClock / (TIM_GetPrescaler(TIM1) + 1); uint32_t TIM1Period = (IC2Value - IC1Value + 0xFFFF) % 0xFFFF; float TIM1DutyCycle = 100.0 * (IC2Value - IC1Value) / TIM1Period; } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值