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:
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
.
MAIN:
Cytuj:
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
INICJALIZACJA PRZYCISKOW:
Cytuj:
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
INICJALIZACJA RTC:
Cytuj:
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
RTC_EVENT:
Cytuj:
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
INT0_vect:
Cytuj:
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.