概要
捕获输入信号脉冲的宽度。
捕获的概念是,捕获边沿信号,同时将定时器的计数值存储下牢。
通过检测输入通道(TIMx_CHx)上的边沿信号,在边沿信号发生跳变(上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存入对应的捕获/比较寄存器(TIMx_CCRx)中,完成一次捕获。
定时器的输入通道,就是定时器框图的左下部分
输入捕获的内部结构
操作步骤
- 使能定时器时钟,配置对应的输入引脚,复用
- 设置计数值
- 设置定时器捕获模式
- 使能输入捕获,设置边沿类型
- 使能捕获
- 设置中断
- 使能定时器
实验要求
捕获 TIM5_CH1( PA0)上的高电平脉宽, 通过 KEY_UP 按键输入高电平,并从串口打印高电平脉宽。
void TIM5_CH1_Cap_Init(u32 arr, u16 psc)
{
RCC->APB1ENR |= 1<<3;
RCC->AHB1ENR |= 1<<0;
GPIO_Set(GPIOA, PIN0, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_100M, GPIO_PUPD_PD);
GPIO_AF_Set(GPIOA, 0, 2);
TIM5->ARR = arr;
TIM5->PSC = psc;
TIM5->CCMR1 |= 1<<0;
TIM5->CCMR1 |= 0<<4;
TIM5->CCMR1 |= 0<<10;
TIM5->CCER |= 0<<1;
TIM5->EGR = 1<<0;
TIM5->DIER |= 1<<1;
TIM5->DIER |= 1<<0;
TIM5->CR1 |= 0x01;
MY_NVIC_Init(2, 0, TIM5_IRQn, 2);
}
u8 TIM5CH1_CAPTURE_STA = 0;
u32 TIM5CH1_CAPTURE_VAL;
void TIM5_IRQHandler(void)
{
u16 tsr;
tsr = TIM5->SR;
if((TIM5CH1_CAPTURE_STA&0x80) == 0)
{
if(tsr&0x01)
{
if(TIM5CH1_CAPTURE_STA&0x40)
{
if((TIM5CH1_CAPTURE_STA&0x3F)==0x3F)
{
TIM5CH1_CAPTURE_STA |= 0x80;
TIM5CH1_CAPTURE_VAL = 0xFFFFFFFF;
}
else
{
TIM5CH1_CAPTURE_STA++;
}
}
}
if(tsr&0x02)
{
if(TIM5CH1_CAPTURE_STA&0x40)
{
TIM5CH1_CAPTURE_STA |= 0x80;
TIM5CH1_CAPTURE_VAL = TIM5->CCR1;
TIM5->CCER &= ~(1<<1);
}
else
{
TIM5CH1_CAPTURE_STA = 0;
TIM5CH1_CAPTURE_VAL = 0;
TIM5CH1_CAPTURE_STA |=0x40;
TIM5->CR1 &= ~(1<<0);
TIM5->CNT = 0;
TIM5->CCER |= 1<<1;
TIM5->CR1 |= 0x01;
}
}
}
TIM5->SR = 0;
}
int main(void)
{
long long temp = 0;
sys_init();
while(1)
{
delay_ms(10);
LED0_PWM_VAL++;
if(LED0_PWM_VAL == 300) LED0_PWM_VAL = 0;
if(TIM5CH1_CAPTURE_STA&0x80)
{
temp = TIM5CH1_CAPTURE_STA&0x3F;
temp*=0xFFFFFFFF;
temp+=TIM5CH1_CAPTURE_VAL;
printf("HIGH:%lld us\r\n", temp);
TIM5CH1_CAPTURE_STA = 0;
}
}
}
static void sys_init(void)
{
Stm32_Clock_Init(336, 8, 2, 7);
delay_init(168);
TIM14_PWM_Init(500-1, 84-1);
uart_init(84, 115200);
TIM5_CH1_Cap_Init(0xFFFFFFFF, 84-1);
}
参考
STM32F3与 F4 系列 Cortex M4 内核编程手册
STM32F4xxx中文参考手册
STM32F4xxx英文参考手册
STM32F4 开发指南(寄存器版)