当想检测高电平或低电平的持续时间的时候,就可以使用定时器输入捕获。例如示波器就是用到这个功能。这里就讲解一下定时器到底是如何输入捕获的:
由上图我们可以知道,周期 是每次连续的上升沿的时间差(例如:T=第二个方波的上升沿时间-第一个方波的上升沿时间),高电平时间 是每次连续的上升沿和下降沿的时间差(例如:T高电平=第一个方波的下降沿-第一个方波的上升沿)。
(基本定时器是不具备输入捕获的,通用/高级定时器具备输入捕获)
如何实现输入捕获?
这里选择TIM2_CH2和TIM3_CH1作为讲解示例。先让TIM2_CH2产生PWM脉冲传输到TIM3_CH1(说直白点就是,一个引脚输出PWM脉冲信号然后拿杜邦线插到另一个引脚上面),然后用TIM3_CH1检查一下PWM脉冲有没有问题。
STM32F103C8T6中,PA6:TIM3_CH1,PA7:TIM3_CH2,PB0:TIM3_CH3,PB1:TIM3_CH4。让PA6当做输入捕获。
void TIM3_InputCaputure_Configuration(void)
{GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);TIM_TimeBaseStructure.TIM_Period = 19999;TIM_TimeBaseStructure.TIM_Prescaler = 71;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);}
从上面代码可以看出,频率为1us,周期为20ms。所以我们的计算上限为20ms,如果超过则会进入溢出中断。但是也可以这样用,每溢出一次进入溢出中断,溢出中断计数,如果溢出中断计数为10,则时间为10*20ms=200ms。
正常情况下,我们大多使用在一次周期之内完成计数,而不去频繁进入溢出中断。所以我们把预分配直接拉满:
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
TIM_ICInit:指定的参数初始化外设TIMx。
参数一:TIMx,例如TIM2,TIM3。
参数二:指向结构体TIM_ICInitTypeDef的指针。
TIM_ICInitTypeDef structure
TIM_ICInitTypeDef 定义于文件“stm32f10x_tim.h”:
typedef struct { u16 TIM_Channel; u16 TIM_ICPolarity; u16 TIM_ICSelection; u16 TIM_ICPrescaler; u16 TIM_ICFilter; } TIM_ICInitTypeDef;
TIM_Channel:选择通道。
TIM_Channel | 描述 |
TIM_Channel_1 | 使用TIM通道1 |
TIM_Channel_2 | 使用TIM通道2 |
TIM_Channel_3 | 使用TIM通道3 |
TIM_Channel_4 | 使用TIM通道4 |
TIM_ICPolarity:输入活动沿。
TIM_ICPolarity | 描述 |
TIM_ICPolarity | TIM输入捕获上升沿 |
TIM_ICPolarity | TIM输入捕获下降沿 |
TIM_ICSelection:选择输入。
TIM_ICSelection | 描述 |
TIM_ICSelection_DirectTI | TIM 输入 2 , 3 或 4 选择对应地与 IC1 或 IC2 或 IC3 或 IC4 相连 |
TIM_ICSelection_IndirectTI | TIM 输入 2 , 3 或 4 选择对应地与 IC2 或 IC1 或 IC4 或 IC3 相连 |
TIM_ICSelection_TRC | TIM 输入 2 , 3 或 4 选择与 TRC 相连 |
TIM_ICPrescaler:设置输入捕获预分频器。
TIM_ICPrescaler | 描述 |
TIM_ICPSC_DIV1 | TIM捕获在捕获输入上每探测到一个边沿执行一次 |
TIM_ICPSC_DIV2 | TIM捕获每2个事件执行一次 |
TIM_ICPSC_DIV3 | TIM捕获每3个事件执行一次 |
TIM_ICPSC_DIV4 | TIM捕获每4个事件执行一次 |
TIM_ICFilter:选择输入比较滤波器。该参数值在0x0和0xF之间。
PA6的全部初始化:
void TIM3_InputCaputure_Configuration(void)
{GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_ICInitTypeDef TIM_ICInitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);TIM_TimeBaseStructure.TIM_Period = 0xFFFF;TIM_TimeBaseStructure.TIM_Prescaler = 71;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;TIM_ICInitStructure.TIM_ICFilter = 0x0;TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;TIM_ICInit(TIM3,&TIM_ICInitStructure);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);TIM_ClearFlag(TIM3, TIM_FLAG_CC1);TIM_ITConfig(TIM3, TIM_FLAG_CC1, ENABLE);TIM_Cmd(TIM3,ENABLE);
}