Я экспериментирую с STM32f4
обнаружением, и я пытался использовать задержку (на основе SYSTICK
) в EXTI_IRQ
обработчике, но я понял, что пока EXTI
обработчик запускается, обработчик systick
не срабатывает, вот мой код:
extern volatile int del ;
void EXTI0_IRQHandler(void) {
if (EXTI_GetITStatus(EXTI_Line0) != RESET ) {
/* Do your stuff when PD0 is changed */
del=1000 ;
while(del)
{
//do something
}
/* Clear interrupt flag */
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
И обработчик systick:
void SysTick_Handler(void)
{
if (del--)
;
}
Итак, как я могу решить эту проблему.
Вы можете, если ваш процессор позволяет это (так и должно быть, поскольку я считаю, что все эти серии основаны на Cortex M4), установите прерывание Systick с более высоким приоритетом, чем другие прерывания, а затем выясните, можете ли вы сделать так, чтобы ваш компилятор/процессор не отключить прерывания глобально во время обработки прерывания.
То есть, если вы хотите иметь задержки в ваших прерываниях.
Подсказка: вы не должны этого хотеть.
Прерывания предназначены для эффективной и быстрой обработки важных событий, которые являются критическими. Если для чего-то требуется задержка, превышающая пару ASM("__volatile__ NOP\n NOP\n NOP\n")
, это, вероятно, не то, что вам нужно в прерывании.
Если у вас есть «тяжелая задача», которая запускается прерыванием, гораздо удобнее написать:
uint32_t taskFlags; // semafore register, can also be any other data type that fits your flags (1ul --> uint32_t or larger!)
#define HANDLE_MY_INTERRUPT_STUFF (1ul<<0) // Define a flag for interrupt things.
void main(void) {
while(1) {
if(taskFlags & HANDLE_MY_INTERRUPT_STUFF) { // Check the flag
// Do your interrupt stuff
// Allowed to have many delays and other weird stuff
taskFlags &= ~HANDLE_MY_INTERRUPT_STUFF; // Clear the flag.
}
}
}
InterruptHandler(void) {
taskFlags |= HANDLE_MY_INTERRUPT_STUFF; // set the flag
}
И вдруг вся эта тяжелая обработка выполняется в основном цикле, где ее можно прервать и все такое, и это не повредит никаким другим критичным по времени вещам. Но срабатывает только от источника прерывания, через флаги.
Хотя из-за флагов вы, конечно, рискуете небольшой переменной задержкой выполнения, это всегда уравновешивание.
Между типами процессоров задержка обычно составляет от 4 до 40 тактовых циклов + среднее выполнение другого кода прерывания, поэтому на паре МГц использование задержки в 10 мс обычно уже ограничивает эту задержку и ее вариации.)
Это самое простое решение:
extern __IO uint32_t TimmingDelay;
void Delay(__IO uint32_t time)
{
TimmingDelay = time;
while(TimmingDelay != 0);
}
Это в stm32f4xx_it.c:
void SysTick_Handler(void)
{
if(TimmingDelay != 0)
{
TimmingDelay --;
}
}
В main не забудьте добавить эту строку:
SysTick_Config(SystemCoreClock/1000000);
а затем используйте Delay("AddDelayHere"); и спамить по всему коду.
пользователь3629249