Всем привет, уже пару дней ломаю голову над этой проблемой - не выходит настроить TIM1 input capture (для измерения длины импульсов, посылаемых HC-SR04 - ультразвуковым дальнометром). Плата - stm32vldiscovery, для разработки использую CMSIS и STDPeriph. Я новичок, если что.
Вкратце для тех кто не в курсе, как устроен протокол HC-SR04 - данный дальнометр располагает двумя пинами - Trigger и Echo. Получив на Trigger 10-микросек. сигнал, дальнометр активируется и определяет расстояние до ближайшей преграды с помощью ультразвука. Далее, он отвечает - на пин Echo посылается сигнал, длительность которого пропорциональна определенному расстоянию. (150-2500 мкс)
Вот скриншот с логического анализатора, как весь этот процесс выглядит: https://imgur.com/a/MXN13ZP. Как видно на этом фото, первая часть (триггер) у меня отлично работает (взят TIM4 CH4).
Проблема выходит со второй частью - я пытаюсь настроить TIM1 для определения длительности импульса Echo, вот код:
static void echo_init()
{
// reconfigure PA8 to alternative function push-pull
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef Gpio;
GPIO_StructInit(&Gpio);
Gpio.GPIO_Pin = GPIO_Pin_8;
Gpio.GPIO_Mode = GPIO_Mode_AF_PP;
//Gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &Gpio);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
// enable timer clock
RCC_APB1PeriphClockCmd(RCC_APB2Periph_TIM1 , ENABLE);
// configure timer
// PWM frequency = 10 hz with 24,000,000 hz system clock
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Prescaler = SystemCoreClock/100000 - 1; // 10 hz or 100 ms cycle
TIM_TimeBaseStructure.TIM_Period = 10000 - 1; // 0..9999
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
// Channel 1 latches the timer on a rising input on t1
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = 0;
TIM_ICInitStructure.TIM_ICFilter = 0;
TIM_ICInit(TIM1, &TIM_ICInitStructure);
// Channel 2 latches the timer on a falling input on t2
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_IndirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = 0;
TIM_ICInitStructure.TIM_ICFilter = 0;
TIM_ICInit(TIM1, &TIM_ICInitStructure);
// Configure the timer slave mode with TI1FP1 as reset signal
TIM_SelectInputTrigger(TIM1, TIM_TS_TI1FP1);
TIM_SelectSlaveMode(TIM1, TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
// Enable Timer
TIM_Cmd(TIM1, ENABLE);
}
При этом, по идее, таймер должен быть полностью сконфигурирован, но каждый раз, когда я заглядываю в регистры TIM1->CCR1
и TIM1->CCR2
, они пусты! Т.е. хранят 0. Что я делаю не так, может кто-то подскажет?
int ultrasonic_get_distance()
{
return TIM1->CCR2 - TIM1->CCR1 * 17/100;
//is supposed to return distance in mm
//always returns zero for some reason
}
ЗЫ: конфиг взят из этой книги, глава 10.2, ну и частично дописан мной.