1.基本知识
高级控制定时器可用于各种用途,包括测量输入信号的脉冲宽度(输入捕获),或者生成输出波形(输出比较、 PWM 和带死区插入的互补 PWM)。使用定时器预分频器和 RCC 时钟控制器预分频器,可将脉冲宽度和波形周期从几微秒调制到几毫秒。
高级控制定时器( TIM1 和 TIM8)和通用 (TIMx) 定时器彼此完全独立,不共享任何资源。
2. 引脚有关
本次用到到的是TIM1_CH3,涉及到以下对应的引脚 PE13/PA0,注意若想要用LCD显示相关参数时,不能使用PE13,会对LCD显示有影响。(引脚参考英文数据手册)
3.程序设计(测量不准确,只能做参考,电压低于1.7V时几乎测不出来了,本来是想利用高级控制定时器和通用定时器的资源完全独立,避免同时使用定时器之间相互的干扰,但实际表明,在使用通用定时器触发ADC和高级定时器做频率检测时,两者还是有互相影响,还请哪位大佬指点一二)
#include "icapture.h"
#include "usart.h"
u8 TIM1CH3_CAPTURE_STA=0; //输入捕获状态,bit7捕获完成标志,bit6捕获到高电平,bit0-5捕获定时器溢出次数
u16 TIM1CH3_CAPTURE_VAL; //输入捕获值(TIM1是 16 位)
u32 cx=0,cx1=0;
void TIM1_CH3_Capture_Init(u32 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_ICInitTypeDef TIM_ICInitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); //使能TIM1的时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA的时钟
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10; //PA10
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF; //复用模式
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_100MHz; //速度为100MHZ
GPIO_InitStruct.GPIO_OType=GPIO_OType_PP; //推挽复用输出
GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_DOWN; //下拉模式
GPIO_Init(GPIOA,&GPIO_InitStruct); //初始化GPIOA
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_TIM1); //将PA10映射到TIM1
TIM_TimeBaseInitStruct.TIM_Prescaler=psc; //TIM1分频系数
TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInitStruct.TIM_Period=arr; //重载值
TIM_TimeBaseInitStruct. TIM_ClockDivision=TIM_CKD_DIV1; //分频系数为1
TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0; //高级定时器1是用定时器功能配置这个才可以是正常的计数频率一开始的72mhz ,这个参数对重复计数器的设定值
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseInitStruct); //初始化TIM1
TIM_ICInitStruct.TIM_Channel=TIM_Channel_3; //选择TIM1的通道3
TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising; //上升沿捕获
TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI; //IC1映射到TI1
TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1; //不分频
TIM_ICInitStruct.TIM_ICFilter=0000; //不滤波
TIM_ICInit(TIM1,&TIM_ICInitStruct); //初始化TIM1的通道1
TIM_Cmd(TIM1, ENABLE); //使能定时器
TIM_ITConfig(TIM1,TIM_IT_CC3,ENABLE); //使能捕获中断
NVIC_InitStruct.NVIC_IRQChannel=TIM1_CC_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0x02;
NVIC_InitStruct.NVIC_IRQChannelSubPriority=0x00;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
void TIM1_CC_IRQHandler(void)
{
TIM_OC3PolarityConfig(TIM1,TIM_ICPolarity_Rising); //设置为上升沿触发
if((TIM1CH3_CAPTURE_STA&0X80)==0)//还未成功捕获
{
cx++;
if(cx==1)
{
TIM1CH3_CAPTURE_VAL=0XFFFFFFFF;
TIM1CH3_CAPTURE_VAL=0; //清空溢出次数
TIM_SetCounter(TIM1,0);
}
if(cx==9)
{
TIM1CH3_CAPTURE_VAL=TIM_GetCapture3(TIM1);//获取当前的捕获值
TIM1CH3_CAPTURE_STA|=0X80;//记为成功捕获一次
cx1=cx;
}
}
TIM_ClearITPendingBit(TIM1, TIM_IT_CC3 ); //清除中断标志
}
主函数需要操作的部分:
```cpp
if(TIM1CH3_CAPTURE_STA&0X80)//成功捕获到了一次高电平
{
temp1=TIM1CH3_CAPTURE_VAL;
temp=temp1/8.0;
Frequency=(1000.0*1000.0)/temp*2;
TIM1CH3_CAPTURE_STA=0; //开启下一次捕获
cx=0;
}