Во-первых, я полный n00b и только начинаю работать с STM32. Я столкнулся с каким-то странным поведением при настройке TIM1, а также при использовании внешнего прерывания EXTI3. Я пытаюсь измерить низкую входную частоту внешнего прерывания и использую TIM1 для увеличения счетчика на 1 МГц, поэтому я могу измерять в микросекундах. Я делаю это, так как кажется, что SysTick недостаточно быстр (1 мс), чтобы дать мне точное измерение.
Тактовая частота ядра составляет 16 МГц, а TIM1 настроен следующим образом:
htim1.Instance = TIM1;
htim1.Init.Prescaler = 16; // 16 MHz / 16 = 1 MHz
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 1; // 1Mhz no sub-dividing
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
...
HAL_NVIC_SetPriority(EXTI3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI3_IRQn);
...
void TIM1_UP_TIM10_IRQHandler(void)
{
timerTicks++;
HAL_TIM_IRQHandler(&htim1);
}
...
void EXTI1_IRQHandler(void)
{
previousTimerTicks = currentTimerTicks;
currentTimerTicks = timerTicks;
}
...
// Start the timer as interrupt
HAL_TIM_Base_Start_IT(&htim1);
...
while(1){
// Blink a light so we know the program is running
HAL_GPIO_TogglePin(GPIOB, Led_Green_Pin);
HAL_Delay(100);
}
Однако программа в значительной степени блокируется, и цикл выполнения while(), похоже, не выполняется. Тем не менее, я вижу, что счетчик TIM1 увеличивается. Если я замедляю период, скажем, до 100, основной цикл приложения работает нормально.
Это проблема с TIM1 и EXTI3, конфликтующими на этой скорости, или здесь происходит что-то еще? Я полагаю, что у устройства не должно быть проблем со счетчиком 1 МГц, но, возможно, я делаю все это неправильно.
Ты все делаешь неправильно.
Невозможно выполнить обработчик прерывания таймера всего за 16 тактов - не говоря уже о цикле while(1).
Что вы должны делать, так это позволить таймеру работать свободно и обрабатывать прерывания только при его переполнении. Мы скоро вернемся к этому.
Затем настройте обработчик прерывания для вашего EXTI и в нем зафиксируйте значение таймера и сохраните его.
В следующем прерывании вычислите разницу между двумя значениями — и вот оно — время между двумя последовательными событиями EXTI, кратное периоду вашего таймера (1 мкс, если вы оставите его таким же).
Но что, если таймер сбрасывается — вот почему мы хотим обрабатывать прерывания таймера при сбрасывании.
Здесь вы можете установить флаг, чтобы сообщить вашему обработчику EXTI, что таймер перешел, и он должен учитывать это при выполнении вычислений.
ккрамбо
Майкл Браун