STM32定时器输入捕获功能(STM32笔记)
·
目录
一、输入捕获
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);
}
}
更多推荐

所有评论(0)