本章要学习的PWM输入捕获是定时器又一重要应用,使用PWM输入捕获可以测量输入PWM的频率和占空比。
PWM输入只能使用定时器的两个通道:通道1和通道2,且一路PWM输入要占用两个捕获寄存器,一个用于捕获周期,一个用于捕获占空比。
本章我们使用固件库例程中的“TIM_PWM_Input”工程,来为大家讲解如何配置TIM完成PWM输入捕获的功能。
12.1 PWM输入捕获配置
12.1.1 开启对应端口和功能时钟
本例程主要使用到GPIOA Pin8的复用功能TIM_ CH1,因此需要使能GPIOA、AFIO与TIM1的时钟。
void RCC_Configuration(void)
{
/* 使能TIM1 GPIOA AFIO 时钟*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BMX1 |
RCC_APB1Periph_TIM1 |
RCC_APB1Periph_GPIOA |
RCC_APB1Periph_AFIO ,
ENABLE);
}
12.1.2 初始化端口引脚
本例程主要使用到PA8的复用功能TIM_ CH1作为PWM输入引脚。
void GPIO_Configuration(void)
{
GPIO_Init(GPIOA, GPIO_Pin_8, GPIO_MODE_AF | GPIO_AF1);
}
12.1.3 定时器基本结构体配置
/* 初始化定时器参数 */
TIM_TimeBaseStructure.TIM_Period = 0xFFFF; //配置定时器周期为0xFFFF,即65535,可设置范围为0x00000~oxFFFFF。
//自动重装载寄存器(ARR)的值累计TIM_Period个频率后产生一个更新或中断。
TIM_TimeBaseStructure.TIM_Prescaler = 0; //配置预分频器为0。
//驱动CNT计数器的时钟CK_CNT = CK_INT /(TIM_Prescaler+1)
//例:本例程中 CK_CNT = 72M/(0+1) = 72M
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //配置时钟分频因子为0。
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //配置定时器计数模式为向上计数
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //初始化定时器基本结构体
细心的朋友可以发现没有配置结构体成员TIM_RepetitionCounter,这是因为没有用到,也可以将其配置为0。
12.1.3 输入捕获结构体配置
想要配置TIM为输入捕获模式,我们需要配置输入捕获结构体:
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //配置捕获的通道为通道1。
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //配置捕获的边沿为上升沿。
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //设置捕获通道的信号来自输入通道1,可选三种方式,具体看参数定义。
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //输入捕获通道预分频器配置为1分频,即捕获信号每个有效边沿都捕获。
TIM_ICInitStructure.TIM_ICFilter = 0x0; //配置输入捕获滤波器为不滤波,可设置范围为0x0到0xF。
TIM_PWMIConfig(TIM1, &TIM_ICInitStructure); //初始化PWM输入捕获结构体。
注意:
1)当工作于PWM输入模式时,只需要设置触发信号的那一路即可(用于测量周期),另外一路(用于测量占空比)硬件会自动配置。
2)到目前为止,除了对TIM定时器的基本配置外,我们已经了解了“定时器输出比较结构体配置”,“刹车和死区结构体配置”和今天学习的“输入捕获结构体配置”,希望大家在学习完TIM部分后能够对这些结构体“怎么用?”、“何时用?”有清晰的认识。
12.1.4 TIM输入捕获功能其他项目配置
/* 选择TIM1 触发信号来源: TI1FP1 */
TIM_SelectInputTrigger(TIM1, TIM_TS_TI1FP1);
/* 选择从模式: 复位模式 */
/* 使用PWM输入模式时,必须将从模式设置为复位模式,当捕获开始时,计数器CNT会被复位 */
TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset);
/* 使能主从模式 */
TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
/* 使能TIM1计数器 */
TIM_Cmd(TIM1, ENABLE);
/* 使能TIM1通道1中断请求 */
TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);
12.1.5 TIM高级定时器中断配置
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure; //将NVIC_InitTypeDef宏定义为NVIC_InitStructure
/* 使能TIM1全局中断 */
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn; //配置中断源为TIM1捕获比较中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //配置抢占优先级为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //配置子优先级为1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能中断
NVIC_Init(&NVIC_InitStructure); //初始化中断初始化结构体
}
12.1.6 TIM1捕获比较中断服务函数配置
void TIM1_CC_IRQHandler(void)
{
/* 清除TIM1通道1中断标志位 */
TIM_ClearITPendingBit(TIM1, TIM_IT_CC1);
/* 获取输入捕获值 */
IC1Value = TIM_GetCapture1(TIM1);
IC2Value = TIM_GetCapture2(TIM1);
/* 占空比计算 */
DutyCycle = ((float)(IC2Value + 1) * 100) / (IC1Value + 1);
/* 频率计算 */
Frequency = (float)72000000 / (IC1Value + 1);
}
注意:
1)因为是 PWM 输入模式,只能使用通道 1 和通道 2 ,假如我们使用的是通道 1,即 TI1。
输入的 PWM 信号会被分成两路,分别是TI1FP1 和 TI1FP2,两路都可以是触发信号。如果选择 TI1FP1 为触发信号,那么 IC1 捕获到的是 PWM 信号的周期, IC2 捕获到的是占空比 ,这 种 输 入 通 道 TI 和 捕获通道 IC 的映射关系叫直连,输入捕获结构体的TIM_ICSelection 要配置为 TIM_ICSelection_DirectTI。
如果选择 TI1FP2 为触发信号,则IC2 捕获到的是周期,IC1 捕获到的是占空比,这种输入通道 TI 和捕获通道 IC 的映射关系叫非直连,输入捕获结构体的 TIM_ICSelection 要配置为 TIM_ICSelection_IndirectTI。
2)请熟悉并推算占空比计算公式和频率计算公式。
12.2 小结
本章节内容为大家分析了PWM输入捕获的配置方法,但是我们仅仅是学会了如何配置,我们将在下节内容中为大家介绍如何使用串口将测试的信息打印出来。