ATNEL tech-forum
https://forum.atnel.pl/

Zegarek OLED - Problem z obsługą przycisków na INT0.
https://forum.atnel.pl/topic23705.html
Strona 1 z 1

Autor:  Morales [ 4 kwi 2021, o 12:03 ]
Tytuł:  Zegarek OLED - Problem z obsługą przycisków na INT0.

Cześć! Na początku chciałem życzyć wszystkim spokojnych, zdrowych i wesołych świąt! Dla niektórych mogą to być już 2 święta w samotności przez pandemię, ale spokojnie, w końcu wszystko się ułoży! A teraz przechodząc do tematu wątku...

Jestem w trakcie budowy własnego zegarka na rękę z wyświetlaczem OLED opartym na sterowniku SSD1306. Całe oprogramowanie piszę na zestawie uruchomieniowym ATB 1.05a. Program co sekundę otrzymuje przerwanie z RTC PCF8583 umieszczonym na zestawie. Przerwanie podłączyłem do pinu PD3, tak aby wykorzystać INT1. Chciałem na tym mechanizmie oprzeć całe działanie zegarka, czyli co sekundę aktualizowany jest wyświetlacz oraz wykonywany jest pomiar ADC naładowania baterii (na razie wykorzystuję potencjometr dodany w zestawie). Na osobnym Timerze oparty jest odczyt temperatury z DS18B20 (kod wzorowany na tym z bluebooka). Do tego momentu wszystko działa poprawnie. Chciałem dodać obsługę zegarka bazując na 3 micro switchach. Postanowiłem wykorzystać rozwiązanie, które Mirek przedstawił przy okazji tworzenia własnego pilota IR w bluebooku. Jedno wyprowadzenie przycisku podłączone jest do PORTu C, a drugie bezpośrednio do PD2, ponieważ znajduję się tam przerwanie INT0. Z mojego rozumowania i noty ATmegi 32 wynika, że przerwanie INT0 ma większy priorytet niż INT1, a więc wciśnięcie przycisku powinno spowodować natychmiastowe przejście do przerwania INT0_vect i wykonać zawarte w nim operację. Na początku chciałem wykorzystać funkcję SuperDebounce umieszczoną w przerwaniu INT0_vect, jednak program nie działał poprawnie, ponieważ nie reagował na każde wciśnięcie przycisku, a tylko na niektóre. Zrezygnowałem więc z tego rozwiązania i wykorzystałem kod do pilota podczerwieni z bluebooka. Efekt niestety jest ten sam... Gdzieś wyczytałem, że w momencie w którym program już wejdzie w jakieś przerwanie wyłączane jest globalne zezwolenie na przerwanie, więc skoro co sekundę mam przerwanie z RTC, to czy właśnie ono blokuje działanie przerwania INT0? Jeżeli tak to w takim razie po co priorytet przerwań w AVRce, skoro i tak jedno przerwanie blokowałoby inne? Pomyślałem, żeby ten odczyt co sekundę oprzeć na jakimś timerze programowym zamiast na zewnętrznym przerwaniu z RTC, jednak nie jestem przekonany czy to rozwiąże mój problem... Poniżej zamieszczam kod z maina i kilku innych funkcji. Proszę o pomoc i życzę jeszcze raz zdrówka :)

P.S. Od razu napiszę, że wykorzystuję aż 4 bitmapy, ponieważ w mojej wersji wyświetlacza SSD1306 nie działa częściowe odświeżanie ekranu oraz przesuwanie tekstu, które Mirek przedstawiał w swojej serii poradników właśnie na temat tego wyświetlacza. Niestety moje próby naprawy tego okazały się nieskuteczne, najprawdopodobniej przez to, że wykorzystywane są tam komendy: mk_ssd1306_cmd(SSD1306_SETLOWCOLUMN | (col_start & 0x0F)); mk_ssd1306_cmd(SSD1306_SETHIGHCOLUMN | col_start >> 4); mk_ssd1306_cmd(0xB0 + page_cnt); // ustawienie strony

Cytuj:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Miałem też z nimi problem w wątku "SSD1306 - Przesuwanie się bitmap". Jak ktoś ma pomysł jak to rozwiązać to chętnie przeczytam :D.

MAIN:
Cytuj:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


INICJALIZACJA PRZYCISKOW:
Cytuj:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


INICJALIZACJA RTC:
Cytuj:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


RTC_EVENT:
Cytuj:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


INT0_vect:
Cytuj:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Autor:  auers [ 6 kwi 2021, o 19:21 ]
Tytuł:  Re: Zegarek OLED - Problem z obsługą przycisków na INT0.

Popełniłeś dwa błędy

1. W przerwaniu INT0_vect używasz delay. Nie idź tą drogą. Skoro używasz przerwań to nie blokuj ich delay'ami.

2. Źle kasujesz flagę przerwań:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

W ten sposób kasujesz wszystkie aktywne flagi ustawione w rejestrze GIFR a nie tylko tą od INT1.

Autor:  mirekk36 [ 6 kwi 2021, o 20:58 ]
Tytuł:  Re: Zegarek OLED - Problem z obsługą przycisków na INT0.

auers napisał(a):
2. Źle kasujesz flagę przerwań:

Dokładnie, dlatego kasowanie flagi powinno wyglądać w tym wypadku tak

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Autor:  Morales [ 7 kwi 2021, o 16:01 ]
Tytuł:  Re: Zegarek OLED - Problem z obsługą przycisków na INT0.

Zastosowałem się do waszych rad i zmieniłem sposób kasowania flagi przerwania oraz usunąłem delaya z przerwania (dodałem go dlatego, ze służył do wyeliminowania drgań styków w projekcie pilota IR w bluebooku). Niestety działanie programu nie poprawiło się... Z tego co widzę to jednak muszę zrezygnować z cyklicznego przerwania od RTC. Wydaje mi się, że to on blokuje działanie przycisków pod INT0.

Autor:  auers [ 7 kwi 2021, o 18:57 ]
Tytuł:  Re: Zegarek OLED - Problem z obsługą przycisków na INT0.

Przerwanie od RTC nie może blokować przerwań od przycisków.
Obsługę RTC masz w RTC_event w pętli głównej. Każde przerwanie w tym to od INT0 przerwie tą funkcję i wejdzie w kod umieszczony w "sekcji ISR".
To nie RTC blokuje Ci klawisze, prędzej kod z INT0_vect blokuje resztę programu i pozostałe przerwania.
Chyba że kod INT0_vect: masz poza ISR.

Autor:  Morales [ 8 kwi 2021, o 21:06 ]
Tytuł:  Re: Zegarek OLED - Problem z obsługą przycisków na INT0.

No i racja. Przemodelowałem funkcję. Teraz obsługa przycisków jest w while'u, a przerwanie INT0 wystawia tylko flagę. Układ działa lepiej, jednak nadal mam dwa dziwne problemy... Pierwszy to to, że zawsze wykonuje mi się pierwszy warunek IF w obsłudze przycisków, nie ważne jak je zamaskuje i jaki przycisk wcisnę... Drugi to zaczynają reagować dopiero po kilkukrotnym wciśnięcia na początku uruchomienia zegarka. Później już każde kliknięcie jest poprawnie wykonywane. Zmienna, która ma się inkrementować wraz z wciśnięciem nie zmienia swojego stanu przez jakieś 4-5-6 wciśnięć, po czym zaczyna działać poprawnie xd. Strasznie dziwne są te dwa błędy... Składniowo nie widzę problemu, dlatego może ktoś z was coś zauważy. Reszta funkcji się nie zmieniła...

P.S Ogólnie to nie muszę używać tych warunków if, ponieważ sama funkcja SuperDebounce powinna być już w stanie rozpoznać jaki dokładnie przycisk został wciśnięty. Niestety ona tak nie działa :/

Cytuj:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Cytuj:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Cytuj:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Cytuj:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Autor:  auers [ 9 kwi 2021, o 20:27 ]
Tytuł:  Re: Zegarek OLED - Problem z obsługą przycisków na INT0.

Cytuj:
Pierwszy to to, że zawsze wykonuje mi się pierwszy warunek IF w obsłudze przycisków, nie ważne jak je zamaskuje i jaki przycisk wcisnę...

A jak masz te przyciski podłączone? Nie masz ich zwartych ze sobą?

Cytuj:
Drugi to zaczynają reagować dopiero po kilkukrotnym wciśnięcia na początku uruchomienia zegarka.

Jeżeli tego nie zmieniłeś to na początku programu miałeś delay'a 3s wykonanego przy pomocy pętli while(Timer2);
W tym czasie przyciski jak i cała reszta programu nie będą działać.

Autor:  Morales [ 15 kwi 2021, o 21:59 ]
Tytuł:  Re: Zegarek OLED - Problem z obsługą przycisków na INT0.

Miałem chwilę przerwy od tego tematu... Dzisiaj wróciłem do zabawy. Jeżeli chodzi o połączenie przycisków, to wykonałem je w takim sposób jak Mirek pokazywał w rozdziale dotyczącym budowy własnego pilota IR. Jedna nóżka przycisku jest podłączona do INT0, a druga do konkretnego portu np, PC6. Zauwazyłem, że nawet jeżeli zmienie podlączenie przycisków (z portu C na port D) a nie zmienie portu z PINC na PIND w funkcji superdebounce, to przyciski i tak będą reagować tak samo, czyli po uruchomieniu zegarka, 3-4 wciśnięcia nic nie robią, a później każde kolejne wykonuje wywołanie pierwszego superdebounce, czyli tego z funkcja switch1_command.

Pozwoliłem sobie wrzucić to przycięte zdjęcie z książki. Mam nadzieję, że w takim przypadku jest to dozwolone :).

Cytuj:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Obrazek

Strona 1 z 1 Strefa czasowa: UTC + 1
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/