GPIO ustawiam:
GPIOA->CRL &= ~GPIO_CRL_CNF0_0; // floating input to pull-down
GPIOA->CRL |= GPIO_CRL_CNF0_1;Puszczam zegar do EXTI (w tym procku AFIO):
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;Zdejmuję maskę z interesujących pinów:
EXTI->IMR |= EXTI_IMR_MR0 | EXTI_IMR_MR1 | EXTI_IMR_MR2 | EXTI_IMR_MR3 | EXTI_IMR_MR4;Ustawiam reakcję na zbocze narastające:
EXTI->RTSR |= EXTI_RTSR_TR0 | EXTI_RTSR_TR1 | EXTI_RTSR_TR2 | EXTI_RTSR_TR3 | EXTI_RTSR_TR4;Dodaję priorytety przerwania i uruchamiam przerwania (tu tylko po jednym żeby nie mnożyć):
NVIC_SetPriority(EXTI0_IRQn, 1);
NVIC_EnableIRQ(EXTI0_IRQn);Przykładowe przerwanie:
__attribute__((section(".after_vectors"))) void EXTI0_IRQHandler()
{
printf("++ \r\n");
EXTI->PR |= EXTI_PR_PR0;
}
Co bym nie robił tak działa tylko jedno przerwanie i to z PA2. Wiązać pinów z EXTI niby nie muszę (po resecie akurat się zgrywają), ale robię to dla pewności, nie widzę już gdzie szukać. W komentarzu dla czytelności wrzucam cały kod okrojony do obsługi EXTI.
Co mogę robić źle albo gdzie szukać? Do debugowania mam UART i LEDa ( ͡° ͜ʖ ͡°)
#stm32 #embedded #programowanie #baremetal
@macgajster miłej zabawy z drgającymi stykami ¯\_( ͡° ͜ʖ ͡°)_/¯
Takie rzeczy się robi na przerwaniu od timera. Co 5 - 10 ms timer odpala przerwanie i w nim sprawdzasz czy przycisk był naciśnięty przez kilka cykli po zmianie stanu. Jeśli tak to wywołujesz funkcje onButton i ustawiasz jakiś "cooldown", żeby nie odpaliła się kilka razy przy jednym naciśnięciu.
Obsługa przycisku na przerwaniu wymaga kasowania flagi przerwania przed wyjściem z niego i pewnie jakiegoś dodatkowego timera albo delaya, żeby obsługa przerwania nie wywołała się kilka razy.
P.S. daj znać czy udało się odpalić pozostałe przerwania.