Będę odnosił się do numerów linii kodu z Twojego pierwszego postu.
Pod pin PB3 masz podłączony przycisk zwierający do masy, a w linii
44 wewnątrz funkcji
set_pin_int() masz instrukcję ustawiającą ten pin jako wyjście (komentarz jest nieprawidłowy). Na szczęście obecnie masz zakomentowane ustawianie pinu PB3 w stan wysoki, ale rozumiesz chyba co się stanie, gdybyś wyjście ustawione w stan wysoki zwarł przyciskiem do masy?
Instrukcja w linii 74 nie zeruje bitu 4 w rejestrze PORTB, ona zeruje cały rejestr PORTB. Jeśli chcesz wyzerować tylko bit 4 PORTB, powinieneś zrobić tak:
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Najbardziej istotne jest to, co robisz (a właściwie czego nie robisz) z niewykorzystanymi pinami PB0, PB1 i PB2. Przerwanie PCINT0 (jak już wspomniał wcześniej kolega
SylwekK) reaguje na każdą zmianę stanu, ale reaguje też
nie tylko na stan pinu z podłączonym przyciskiem, ale na pierwsze 4 piny PORTB (czyli PB0, PB1, PB2 i PB3). Kiedy te piny są skonfigurowane jako wejścia bez podłączonego potencjału, czyli są w stanie wysokiej impedancji (takie jest standardowe ustawienie pinów po "power on reset"), są w tzw. stanie nieustalonym, czyli są podatne na zakłócenia i mogą właśnie między innymi generować nieoczekiwane przerwania. Aby temu zapobiec, należy ich stan "ustalić". Najprostszym sposobem (programowym) jest podłączenie ich do VCC przez wewnętrzne rezystory pull-up:
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Ewentualnie można to zrobić sprzętowo poprzez zewnętrzne fizyczne podłączenie rezystorów między tymi pinami a VCC (lub GND).
W związku z tym, że przerwanie to reaguje na kilka pinów i na oba zbocza, należy pamiętać, że procedura obsługi przerwania w zasadzie powinna sprawdzać, który pin wygenerował przerwanie, które zbocze je wygenerowało i na tej podstawie wykonywać określone akcje. U Ciebie (przynajmniej dopóki pozostałe piny nie są używane) nie jest konieczna identyfikacja pinu, za to może być potrzebna identyfikacja zbocza, w zależności od tego, co chcesz osiągnąć.
Pozostaje jeszcze kwestia drgań styków. Sama funkcja
_delay_ms(10) w procedurze obsługi przerwania nie załatwi problemu. W trakcie obsługi przerwania może zostać ustawiona flaga przerwania i zaraz po zakończeniu obsługi przerwania zostanie ono wywołane ponowne. Wyzerowanie flagi przerwania na końcu procedury:
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
być może pomoże, ale też nie daje stuprocentowej pewności, że jedno wciśnięcie przycisku nie wygeneruje większej ilości przerwań.
No i nie rozumiem, po co Ci ta procedura obsługi przerwania INT0, skoro ani na schemacie nie masz pod ten pin nic podłączone, ani nie włączasz zezwolenia na to przerwanie...