przem312 Napisano Lipiec 26, 2012 Udostępnij Napisano Lipiec 26, 2012 Witam,mam zbudowane menu na klawiaturze czteroprzyciskowej, której obsługę zaprogramowałem w przerwaniach EXTI. Przykładowy przycisk defioniowany jest w następujący sposób: #ifdef KB1 //Konfiguracja NVIC - ustawienia priorytetow przerwania EXTI0 Dla przycisku OK (KB1) NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //Wybor modelu grupowania przerwan NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //Wybor konfigurowanego IRQ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //Priorytet grupowy NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //Podpriorytet NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //Wlaczenie obslugi IRQ NVIC_Init(&NVIC_InitStructure); GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource0); //Ustawienie zrodla przerwania //Konfiguracja przerwania EXTI0 na linie 0 EXTI_InitStructure.EXTI_Line = EXTI_Line0; //Wybor linii EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //Ustawienie generowania przerwania (a nie zdarzenia) EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //Wyzwalanie zboczem opadajacym (wcisniecie przycisku) EXTI_InitStructure.EXTI_LineCmd = ENABLE; //Wlaczenie przerwania EXTI_Init(&EXTI_InitStructure); #endif Problem polega na tym, że gdy uruchamia się urządzenie (w sumie niezależnie od tego czy przez reset w debuggerze, hard reset czy przywrócenie zasilania) program przeskakuje wszystkie możliwe przerwania i je wykonuje. Skutkuje to tym, że jeden przycisk, odpowiadający za start pomiaru (jest to urządzenie mierzące przy napięciu sieciowym) od włączenia zasilania jest odpalany. Wszystko niestety póki co montowane jest na płytkach uniwersalnych łączonych kenarem, więc nie wykluczam zimnych lutów. Co może być przyczyną takiego stanu rzeczy? Link do komentarza Share on other sites More sharing options...
danioto Lipiec 26, 2012 Udostępnij Lipiec 26, 2012 Mógłbyś pokazać jeszcze procedurę obsługi przerwania? W jaki sposób zadeklarowałeś pin PD0? Link do komentarza Share on other sites More sharing options...
przem312 Lipiec 26, 2012 Autor tematu Udostępnij Lipiec 26, 2012 Dzięki za zainteresowanie 😉 Procedura przerwania: void EXTI0_IRQHandler(void) { if (EXTI_GetITStatus(EXTI_Line0) != RESET) { if(submenu==0) { submenu=1; if(pozycja==0) { submenu=0; onPomiar=1; } else{ opcja=pozycja; pozycja=0; } } } EXTI_ClearITPendingBit(EXTI_Line0); //wyzeruj flage obslugi przerwania } W niej zaimplementowałem poruszanie się po menu. Wydawało mi się to sensowniejsze niż wyciąganie na zewnątrz zmiennych do nieskończonej pętli. Sam klawisz miałem z początku zdefiniowany jako IN_FLOATING z pull-upem do 3v3, potem, by wyeliminować możliwość zbierania się ładunku na lucie (wtedy dotknięcie czymkolwiek metalowym płytki skutkowało przerwaniem...) zastosowałem wewnętrzny pullup. Zegary dla wejść mam skręcone do 2MHz. Link do komentarza Share on other sites More sharing options...
danioto Lipiec 27, 2012 Udostępnij Lipiec 27, 2012 Hejo 🙂 Po pierwsze czyszczenie flagi raczej powinno się znajdować wewnątrz warunku istnienia przerwania, taki zabieg kosmetyczny - bez sensu czyścić flagę, jak jest ona pusta. Następnie warto też ustawić w pamięci tablicę wektorów przerwań: #ifdef VECT_TAB_RAM NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); #else NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); #endif Aha, częstym błędem jest też, że ludzie zapominają włączyć zegar dla funkcji alternatywnych: RCC_APB2Periph_AFIO, przynajmniej ja usilnie na początku o tym zapominałem 😋 Daj znać, czy cokolwiek pomogło, jeśli nie to będziemy myśleć dalej 🙂 Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
przem312 Lipiec 27, 2012 Autor tematu Udostępnij Lipiec 27, 2012 Niestety nic nie pomogło. Próbowałem też oznaczyć trigger na zbocze narastające. Ale też nic to nie dało. zaczynam tracić koncepcje 😉 Link do komentarza Share on other sites More sharing options...
danioto Lipiec 27, 2012 Udostępnij Lipiec 27, 2012 W takim razie na podstawie tego kawałka kodu co pokazałeś ja nie widzę błędu programistycznego. Może spróbuj napisać bardzo prymitywny program tylko i wyłącznie z obsługą przycisków i wrzuć to do funkcji, bo makra czasami bywają zawodne. A jakbyś miał oscyloskop (wiem, wiem, burżujsko, ale może akurat masz dostęp) to sprawdź, czy na pewno nic się nie dzieje na pinie PD0. Link do komentarza Share on other sites More sharing options...
tymon_x Lipiec 30, 2012 Udostępnij Lipiec 30, 2012 Następnie warto też ustawić w pamięci tablicę wektorów przerwań: Jakiś konkretny powód ? Jeśli kolega nie ma w planach bootloadera jest to zabieg zbyteczny czy modyfikacji adresu funkcji przerwań na inne w czasie działania programu. Nie ma sensu przenosić ją do RAM. Domyślnie jest to i tak początek flash. przem312 - Twoim przyjacielem powinień raczej zostać Timer niż Exti. Zobacz że drgania zestyków mogą trwać ponad kilka ms i mieć różny rozkład częstotliwości i napięcia w czasie. Skręcenie zegara GPIO do 2MHz niewiele się zda. Trzeba próbkować sygnał. Powiedzmy minimum 20 ms dwie próbki określą stabilność stanu. Jeśli chcesz, możesz zbierać informację z GPIO nie wykorzystując w ogóle przerwania, wystarczy zaprzęgnąć DMA z GPIO do RAM oraz Timer do próbkowania i sprawdzasz tylko w głównym programie. Korzystanie z tej śmiesznej biblioteki ST to... słaby pomysł. Szczególnie w przerwaniach, to już przynajmniej mogłeś wywołać ten rejestr normalnie 🙁 Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Bądź aktywny - zaloguj się lub utwórz konto!
Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony
Utwórz konto w ~20 sekund!
Zarejestruj nowe konto, to proste!
Zarejestruj się »Zaloguj się
Posiadasz własne konto? Użyj go!
Zaloguj się »