- IC介绍
- 频率的测量方法
- IC基本结构以及PWMI基本结构,以及基本使用步骤
- 相关函数的介绍
- 目标代码
一.IC介绍
1.IC(Input Capture)输入捕获,输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数
2.每个高级定时器和通用定时器都拥有4个输入捕获通道。可配置为PWMI模式,同时测量频率和占空比
二.频率的测量方法
1.测频法:在闸门开启时间T内,对上升沿(下降沿)计次,得到次数N。频率f = N / T。
2.测周法:在两个上升沿内,对经过的标准频率Fc计次得到N,频率f = Fc / N。(两个上升沿是一个周期,记一次数是1 / Fc秒,计N次得到周期T = N / Fc)
- 在使用上1.适合于高频信号,2.适合低频信号
三.IC基本结构以及PWMI基本结构
1.IC的基本结构
2.执行顺序(以输入捕获单元1为例):经过TI1FP1之后CNT值锁存到CCR1中,同时触发源选择,选中TI1FP1为触发信号,在从模式可以做到CNT清0
- 注:触发源选择中只有TI1FP1和TI2FP2,没有TI3和TI4
3.使用测周法进行计算,CCR1中存储的CNT的值就是N,Fc通过PSC预分频器得到
1.PWMI基本结构
2.与IC区别是使用了两个通道同时捕获一个引脚的信号
- CCR1依旧不变,CCR2捕获的是高电平的时间,不触发清0.
- 通过CCR2/CCR1就可以得到占空比
- 在使用上,一个配置成上升沿触发一个下降沿触发,一个直连输入一个交叉输入(了解一下就行,具体见下方代码直接配置好了)
3.使用步骤:RCC开启时钟->配置GPIO->配置时基单元->配置输入捕获单元->触发源->从模式->启动TIM定时器
四.相关函数的介绍
- TIM_ICInit,TIM_PWMIConfig,从Init和Config可以知道是初始化,开启对应功能的代码
- 注:TIM_PWMIConfig与Init一样但是可以初始化两个通道,只支持通道1,2
- TIM_SelectInputTrigger:选择输入触发源
- TIM_SelectSlaveMode:选择从模式
- TIM_GetCapture1:读出CCR1的值(别的通道更换对应数字)
没有介绍的函数大概率在前面有过介绍
五.目标代码
- 使用PWMI模式测量频率和占空比
1.RCC开启时钟
/*开启时钟*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//这里用的TIM3进行输入,是APB1的外设
/*注意pwm的波形输出在引脚上,这里再初始一下GPIOA*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//TIM3的通道1在PA6
2.配置GPIO和时基单元(前有介绍),注意一下GPIO的的输入模式
/*配置时基单元以及需要用到的GPIO口*/
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自动重装器的值
TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1;//PSC预分频器值,决定计数计数标准频率
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//重复计数器的值,高级计时器用的
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//需要结构体参数,记得取地址符
/*GPIO用*/
GPIO_InitTypeDef GPIO_InitStruture;
GPIO_InitStruture.GPIO_Mode = GPIO_Mode_IPU;//上拉输入模式
GPIO_InitStruture.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStruture.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruture);
3.配置输入捕获单元
/*配置输入捕获单元*/
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;//选择通道,通道1
TIM_ICInitStructure.TIM_ICFilter = 0xF;//滤波器,增大滤波器参数可以有效避免干扰
TIM_ICInitStructure.TIM_ICPolarity =TIM_ICPolarity_Rising;//边沿极性选择,上升沿触发
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;//输入捕获单元里的PSC(不是时基单元那个),
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//选择触发信号从那个引脚输入,直连通道
TIM_PWMIConfig(TIM3,&TIM_ICInitStructure);//更换ICInit使用PWMIConfig,直接配置好两个通道
4.配置触发源和从模式
/*配置触发源*/
TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//TIM3通道1的TF1FP1触发
/*配置从模式*/
TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//将对应的CNT清0
5.最后启动定时器
/*启动定时器*/
TIM_Cmd(TIM3,ENABLE);
- 补充函数:
-
/** *@brief 使用测周法计算频率,之后获取频率 *@param 无 *@retval 频率值 */ uint32_t IC_GetFrqe(void) { return 1000000 / TIM_GetCapture1(TIM3);//返回频率值,Frqe = Fc / N }
-
/** *@brief 获取占空比,但占空比是0到1的数,乘100方便观测 *@param 无 *@retval 占空比 */ uint32_t IC_GetDuty(void) { return TIM_GetCapture2(TIM3)*100 / TIM_GetCapture1(TIM3);//返回频率值,Duty = CCR2 / CCR1 }
6.主函数以及接线图如下(IC的工程部分省略了)
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "pwm.h"
#include "IC.h"
int main(void)
{
PWM_Init();
IC_Init();
OLED_Init();
OLED_ShowString(1,1,"Freq:00000Hz");
OLED_ShowString(2,1,"Duty:00%");
/*将PWM信号输出到PA0,再通过导线输出到PA6*/
PWM_SetPSC(720 - 1); //frqe = 72M /(PSC + 1) / (ARR + 1)
PWM_SetCompare1(50); //占空比 = CCR / 100
while(1)
{
OLED_ShowNum(1,6,IC_GetFrqe(),5);//显示频率
OLED_ShowNum(2,6,IC_GetDuty(),5);//显示占空比
}
}