当想检测高电平或低电平的持续时间的时候,就可以使用定时器输入捕获。例如示波器就是用到这个功能。这里就讲解一下定时器到底是如何输入捕获的:
由上图我们可以知道,周期 是每次连续的上升沿的时间差(例如: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);
}