<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl-pl">
<link rel="self" type="application/atom+xml" href="https://forum.atnel.pl/feed.php?f=4&amp;t=23705&amp;mode" />

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2021-04-15T21:59:47+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=4&amp;t=23705&amp;mode</id>
<entry>
<author><name><![CDATA[Morales]]></name></author>
<updated>2021-04-15T21:59:47+01:00</updated>
<published>2021-04-15T21:59:47+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=232005#p232005</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=232005#p232005"/>
<title type="html"><![CDATA[Re: Zegarek OLED - Problem z obsługą przycisków na INT0.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=232005#p232005"><![CDATA[
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.<br /><br />Pozwoliłem sobie wrzucić to przycięte zdjęcie z książki. Mam nadzieję, że w takim przypadku jest to dozwolone <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" />.<br /><br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />[syntax=c]void KEYS_EVENT(void) {<br /><br />if (Button_pressed == 1) {<br />SuperDebounce(&amp;k1, &amp;PINC, KL1, 30, 250, switch1_command, switch1_command); // Zawsze wykonuje się ten superdebounce, niewazne który przycisk wcisne<br />SuperDebounce(&amp;k2, &amp;PINC, KL2, 30, 250, switch2_command, switch2_command);<br />SuperDebounce(&amp;k3, &amp;PINC, KL3, 30, 250, switch3_command, switch3_command);<br />Button_pressed = 0;<br />}<br />}[/syntax]<br /></div><br /><br /><a href="https://obrazkiforum.atnel.pl/21510/b6eca59edaca895d84f2ea8767d7cfb0.jpg"  class="postlink"><img src="https://obrazkiforum.atnel.pl/thumb/21510/b6eca59edaca895d84f2ea8767d7cfb0.jpg" alt="Obrazek" /></a><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=21510">Morales</a> — 15 kwi 2021, o 21:59</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[auers]]></name></author>
<updated>2021-04-09T20:27:45+01:00</updated>
<published>2021-04-09T20:27:45+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231889#p231889</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231889#p231889"/>
<title type="html"><![CDATA[Re: Zegarek OLED - Problem z obsługą przycisków na INT0.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231889#p231889"><![CDATA[
<div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />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ę...<br /></div><br />A jak masz te przyciski podłączone? Nie masz ich zwartych ze sobą?<br /><br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />Drugi to zaczynają reagować dopiero po kilkukrotnym wciśnięcia na początku uruchomienia zegarka.<br /></div><br />Jeżeli tego nie zmieniłeś to na początku programu miałeś delay'a 3s wykonanego przy pomocy pętli while(Timer2);<br />W tym czasie przyciski  jak i cała reszta programu nie będą działać.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=7806">auers</a> — 9 kwi 2021, o 20:27</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Morales]]></name></author>
<updated>2021-04-08T21:06:39+01:00</updated>
<published>2021-04-08T21:06:39+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231877#p231877</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231877#p231877"/>
<title type="html"><![CDATA[Re: Zegarek OLED - Problem z obsługą przycisków na INT0.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231877#p231877"><![CDATA[
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...<br /><br />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 :/<br /><br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />[syntax=c]void KEYS_EVENT(void) {<br /><br />uint8_t keys;<br />keys = PINC;<br /><br />if (Button_pressed == 1) {<br /><br />if (!(keys &amp; KL1)) {<br />SuperDebounce(&amp;k1, &amp;PINC, KL1, 30, 250, switch1_command, switch1_command); // Zawsze wykonuje się ten if, niewazne który przycisk wcisne<br />} // Jezeli bym podmienił np. na obłsuge przycisku 3, to wlasnie on by sie tylko wykonywał<br />else if (!(keys &amp; KL2)) {<br />SuperDebounce(&amp;k2, &amp;PINC, KL2, 30, 250, switch2_command, switch2_command);<br />}<br />else if (!(keys &amp; KL3)) {<br />SuperDebounce(&amp;k3, &amp;PINC, KL3, 30, 250, switch3_command, switch3_command);<br />}<br /><br />Button_pressed = 0;<br />}<br />}[/syntax]<br /></div><br /><br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />[syntax=c]void switch1_command (void) {<br /><br />if(forward++ &gt;= 3) forward = 1;<br /><br />}<br /><br />void switch2_command (void) {<br /><br />}<br /><br />void switch3_command (void) {<br /><br />if(backwards++ &gt;= 2) backwards = 0;<br /><br />}[/syntax]<br /></div><br /><br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />[syntax=c]/* Piny do ktorych podpiete sa klawisze */<br />#define KL1 (1&lt;&lt;PC6)<br />#define KL2 (1&lt;&lt;PC5)<br />#define KL3 (1&lt;&lt;PC4)<br />#define PORT_KL PORTC<br />#define DDR_KL DDRC<br />#define KEYS_MASK (KL1|KL2|KL3)<br /><br /><br />#define DEFAULT 0<br /><br />extern volatile uint8_t Button_pressed;<br />volatile uint16_t Timer1, Timer2;/* timery programowe 100Hz */<br />uint8_t k1, k2, k3;  // zmienne pomocnicze do przechowywania stanów klawiszy[/syntax]<br /></div><br /><br /><br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />[syntax=c]void init_key( void ) {<br /><br />DDR_KL |= (KL1 | KL2 | KL3);<br />PORT_KL &amp;= ~(KL1|KL2|KL3);<br /><br />/* Timer2 – inicjalizacja przerwania co 10ms */<br />TCCR2 |= (1&lt;&lt;WGM21);// tryb pracy CTC<br />TCCR2 |= (1&lt;&lt;CS22)|(1&lt;&lt;CS20);// preskaler = 1024<br />OCR2 = 107;// przerwanie porównania co 10ms (100Hz)<br />TIMSK |= (1&lt;&lt;OCIE2);// Odblokowanie przerwania CompareMatch<br /><br /><br />PORTD |= (1&lt;&lt;PD2);// podciągnięcie pinu INT0 do VCC<br />GICR |= (1&lt;&lt;INT0);<br /><br /><br />//sei(); //Zakomentowac, jezeli sei() jest juz w main.c<br />}[/syntax]<br /></div><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=21510">Morales</a> — 8 kwi 2021, o 21:06</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[auers]]></name></author>
<updated>2021-04-07T18:57:42+01:00</updated>
<published>2021-04-07T18:57:42+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231857#p231857</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231857#p231857"/>
<title type="html"><![CDATA[Re: Zegarek OLED - Problem z obsługą przycisków na INT0.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231857#p231857"><![CDATA[
Przerwanie od RTC nie może blokować przerwań od przycisków.<br />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 &quot;sekcji ISR&quot;.<br />To nie RTC blokuje Ci klawisze, prędzej kod z INT0_vect blokuje resztę programu i pozostałe przerwania.<br />Chyba że kod INT0_vect: masz poza ISR.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=7806">auers</a> — 7 kwi 2021, o 18:57</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Morales]]></name></author>
<updated>2021-04-07T16:01:28+01:00</updated>
<published>2021-04-07T16:01:28+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231854#p231854</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231854#p231854"/>
<title type="html"><![CDATA[Re: Zegarek OLED - Problem z obsługą przycisków na INT0.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231854#p231854"><![CDATA[
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.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=21510">Morales</a> — 7 kwi 2021, o 16:01</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[mirekk36]]></name></author>
<updated>2021-04-06T20:58:53+01:00</updated>
<published>2021-04-06T20:58:53+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231834#p231834</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231834#p231834"/>
<title type="html"><![CDATA[Re: Zegarek OLED - Problem z obsługą przycisków na INT0.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231834#p231834"><![CDATA[
<div class="quotetitle">auers napisał(a):</div><div class="quotecontent"><br />2. Źle kasujesz flagę przerwań:<br /></div><br />Dokładnie, dlatego kasowanie flagi powinno wyglądać w tym wypadku tak<br /><br />[syntax=c]GIFR = (1&lt;&lt;INTF1); // Kasowanie flagi dla przerwania INT0.[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=54">mirekk36</a> — 6 kwi 2021, o 20:58</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[auers]]></name></author>
<updated>2021-04-06T19:21:33+01:00</updated>
<published>2021-04-06T19:21:33+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231824#p231824</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231824#p231824"/>
<title type="html"><![CDATA[Re: Zegarek OLED - Problem z obsługą przycisków na INT0.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231824#p231824"><![CDATA[
Popełniłeś dwa błędy<br /><br />1. W przerwaniu   INT0_vect używasz delay. Nie idź tą drogą. Skoro używasz przerwań to nie blokuj ich delay'ami.<br /><br />2. Źle kasujesz flagę przerwań:<br /><br />[syntax=c]GIFR |= (1&lt;&lt;INTF1); // Kasowanie flagi dla przerwania INT0.[/syntax]<br />W ten sposób kasujesz wszystkie aktywne flagi ustawione w rejestrze GIFR a nie tylko tą od INT1.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=7806">auers</a> — 6 kwi 2021, o 19:21</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Morales]]></name></author>
<updated>2021-04-04T12:03:29+01:00</updated>
<published>2021-04-04T12:03:29+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231803#p231803</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231803#p231803"/>
<title type="html"><![CDATA[Zegarek OLED - Problem z obsługą przycisków na INT0.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23705&amp;p=231803#p231803"><![CDATA[
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...<br /><br />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 <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /><br /><br />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 &amp; 0x0F)); mk_ssd1306_cmd(SSD1306_SETHIGHCOLUMN | col_start &gt;&gt; 4); mk_ssd1306_cmd(0xB0 + page_cnt); // ustawienie strony<br /><br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />[syntax=c]void mk_ssd1306_refresh_pages(uint8_t page_nr, uint8_t pages_cnt, uint8_t col_start, uint8_t col_end) {<br /><br />uint8_t page_cnt, col_cnt;<br />uint8_t * ram_buf_start;<br /><br />for (page_cnt = page_nr; page_cnt &lt; (page_nr + pages_cnt); page_cnt++) {<br /><br />mk_ssd1306_cmd(SSD1306_SETLOWCOLUMN | (col_start &amp; 0x0F));<br />mk_ssd1306_cmd(SSD1306_SETHIGHCOLUMN | col_start &gt;&gt; 4);<br />mk_ssd1306_cmd(0xB0 + page_cnt); // ustawienie strony<br /><br />ram_buf_start = &amp;ssd1306_buf&#91;(page_cnt * 128) + col_start&#93;;<br /><br />DC_HI;<br />#if USE_CS == 1<br />CS_LOW;<br />#endif<br /><br />for( col_cnt = col_start; col_cnt &lt; col_end; col_cnt++) {<br />SendSpi( * ram_buf_start++);<br />}<br />}<br />}[/syntax]<br /></div><br /><br />Miałem też z nimi problem w wątku &quot;SSD1306 - Przesuwanie się bitmap&quot;. Jak ktoś ma pomysł jak to rozwiązać to chętnie przeczytam <img src="https://forum.atnel.pl/images/smilies/icon_e_biggrin.gif" alt=":D" title="Bardzo szczęśliwy" />.<br /><br />MAIN:<br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />[syntax=c]#include &lt;avr/io.h&gt;<br />#include &lt;avr/pgmspace.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;string.h&gt;<br />#include &lt;util/delay.h&gt;<br />#include &lt;stdlib.h&gt;<br />#include &lt;avr/wdt.h&gt;<br />#include &lt;avr/sleep.h&gt;<br /><br />#include &quot;MK_OLED_SSD1306/MK_SSD1306.h&quot;<br />#include &quot;BD_OLED_WATCH/OLED_WATCH.h&quot;<br />#include &quot;MKUART/mkuart.h&quot;<br />#include &quot;RTC_LIB/RTC_LIB.h&quot;<br />#include &quot;I2C_TWI/i2c_twi.h&quot;<br />#include &quot;1Wire/ds18x20.h&quot;<br /><br /><br />void Main_Menu( TDATETIME * dt);<br />void Temp_Menu( TDS18B20 * tmp);<br /><br />int main (void) {<br /><br />//int i, k;<br /><br />mk_ssd1306_init(SSD1306_SWITCHCAPVCC, REFRESH_MID); // Inicjalizacja wyswietlacza OLED<br />mk_ssd1306_display();<br /><br />init_RTC(100); // Inicjalizacja RTC, I2C na 100kHz oraz pinu PD2 w tryb INT0<br />register_rtc_callback(Main_Menu); // Rejestracja funkcji show_time<br /><br />USART_Init(__UBRR);<br /><br />init_key(); // Inicjalizacja klawiszy<br /><br />/* sprawdzamy ile czujników DS18xxx widocznych jest na magistrali */<br />temp.czujniki_cnt = search_sensors();<br />DS18X20_start_meas( DS18X20_POWER_EXTERN, NULL );<br />register_ds18b20_callback(Temp_Menu);<br /><br />ADC_init();<br /><br />sei();<br /><br />Timer2 = 3000; // Czekaj 3s<br />while (Timer2);<br />mk_ssd1306_clearDisplay();<br /><br />while(1){<br /><br /><br />DS18B20_EVENT(&amp;temp); // Zdarzenie do odczytu temperatury<br />RTC_EVENT(); // Zdarzenie do odczytu czasu<br /><br />///* Obsluga trzech przyciskow przy pomocy funkcji SuperDebounce */<br />//SuperDebounce(&amp;k1, &amp;PINC, KL1, 10, 20, switch1_command, switch1_command);<br />//SuperDebounce(&amp;k2, &amp;PINC, KL2, 10, 20, switch2_command, switch2_command);<br />//SuperDebounce(&amp;k3, &amp;PINC, KL3, 10, 20, switch3_command, switch3_command);<br /><br />//<br />//for ( i = 130, k =-180; i &gt;-300; i--,k++) { // i mozna potraktowac jako x<br />//mk_ssd1306_puts(i, 6 * 8, &quot;cwel&quot;, 1, 0, 0);<br />//mk_ssd1306_refresh_pages(page5, 1, 0, 127);<br />//mk_ssd1306_display();<br />//}<br />//<br /><br />}<br /><br />}<br /><br />void Main_Menu(TDATETIME *dt) {<br /><br />if (forward == 0 ) {<br />mk_ssd1306_clearDisplay();<br />ADC_EVENT(7);<br />if (procent &gt;= 75 ) mk_ssd1306_drawBitmap_P(0, 0, bitmap1, 128, 64, 1);<br />if (procent &lt; 75 &amp;&amp; procent &gt;= 50) mk_ssd1306_drawBitmap_P(0, 0, bitmap2, 128, 64, 1);<br />if (procent &lt; 50 &amp;&amp; procent &gt;= 25) mk_ssd1306_drawBitmap_P(0, 0, bitmap3, 128, 64, 1);<br />if (procent &lt; 25) mk_ssd1306_drawBitmap_P(0, 0, bitmap4, 128, 64, 1);<br />mk_ssd1306_puts(90, 17, &quot;TEMP&quot;, 1, 1, 1);<br />mk_ssd1306_puts(90, 55, &quot;TIME&quot;, 1, 1, 1);<br />mk_ssd1306_puts(0, 3, dt-&gt;date, 1, 1, 1);<br />mk_ssd1306_puts(17, 32, dt-&gt;time, 2, 1, 1);<br />mk_ssd1306_put_int(30, 13, backwards, 1, 1, 1);<br />mk_ssd1306_display();<br /><br />}<br />}<br /><br />void Temp_Menu(TDS18B20 *tmp) {<br /><br />if (forward == 1) {<br />mk_ssd1306_clearDisplay();<br />ADC_EVENT(7);<br />if (procent &gt;= 75 ) mk_ssd1306_drawBitmap_P(0, 0, bitmap1, 128, 64, 1);<br />if (procent &lt; 75 &amp;&amp; procent &gt;= 50) mk_ssd1306_drawBitmap_P(0, 0, bitmap2, 128, 64, 1);<br />if (procent &lt; 50 &amp;&amp; procent &gt;= 25) mk_ssd1306_drawBitmap_P(0, 0, bitmap3, 128, 64, 1);<br />if (procent &lt; 25) mk_ssd1306_drawBitmap_P(0, 0, bitmap4, 128, 64, 1);<br />mk_ssd1306_puts(90, 55, &quot;TIME&quot;, 1, 1, 1);<br />mk_ssd1306_puts(90, 17, &quot;BACK&quot;, 1, 1, 1);<br />mk_ssd1306_puts(0, 28, tmp-&gt;temperatura, 2, 1, 1);<br />mk_ssd1306_display();<br />}<br />}[/syntax]<br /></div><br /><br />INICJALIZACJA PRZYCISKOW:<br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />[syntax=c]DDR_KL |= (KL1 | KL2 | KL3);<br />PORT_KL &amp;= ~(KL1|KL2|KL3);<br /><br />/* Timer2 – inicjalizacja przerwania co 10ms */<br />TCCR2 |= (1&lt;&lt;WGM21);// tryb pracy CTC<br />TCCR2 |= (1&lt;&lt;CS22)|(1&lt;&lt;CS20);// preskaler = 1024<br />OCR2 = 107;// przerwanie porównania co 10ms (100Hz)<br />TIMSK |= (1&lt;&lt;OCIE2);// Odblokowanie przerwania CompareMatch<br /><br />DDRD &amp;= ~(1&lt;&lt;PD2);<br />PORTD |= (1&lt;&lt;PD2);// podciągnięcie pinu INT0 do VCC<br />GICR |= (1&lt;&lt;INT0);<br />GIFR |= (1&lt;&lt;INTF0);[/syntax]<br /></div><br /><br />INICJALIZACJA RTC:<br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />[syntax=c]void init_RTC(uint16_t i2c_bitrate) {<br />// Przerwanie INT1<br />MCUCR |= (1&lt;&lt;ISC11);// wyzwalanie zboczem opadającym<br />PORTD |= (1&lt;&lt;PD3);// podciągnięcie pinu INT1 do VCC<br /><br />i2cSetBitrate( i2c_bitrate ); // USTAWIAMY prędkość 100 kHz na magistrali I2C<br />datetime.dst = _zimowy;<br />}[/syntax]<br /></div><br /><br />RTC_EVENT:<br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />[syntax=c]/* REJESTR GIFR może byc inny dla innych mikrokontrolerow (Tutaj ATmega32). */<br />void RTC_EVENT(void) {<br />if(GIFR &amp; (1&lt;&lt;INTF1)) { // Zamiast flagi programowej inkrementowanej w ISR (INT0) dajemy flagi sprzętowe. Nadal występuje przerwanie co 1s z RTC<br />get_rtc_datetime(&amp;datetime);<br />if(rtc_callback) rtc_callback(&amp;datetime);<br />GIFR |= (1&lt;&lt;INTF1); // Kasowanie flagi dla przerwania INT0.<br />}<br />}[/syntax]<br /></div><br /><br />INT0_vect:<br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />[syntax=c]uint8_t keys;<br /><br />DDR_KL &amp;= ~(KL1 | KL2 | KL3);<br />PORT_KL |= (KL1 | KL2 | KL3);<br /><br />DDRD |= (1 &lt;&lt; PD2);<br />PORTD &amp;= ~(1 &lt;&lt; PD2);<br />keys = PINC;<br />if ((keys &amp; KEYS_MASK) != KEYS_MASK) {<br />_delay_ms(50);<br />keys = PINC;<br />if ((keys &amp; KEYS_MASK) != KEYS_MASK) {<br />do {<br />if (!(keys &amp; KL1)) switch1_command();<br />if (!(keys &amp; KL2)) switch2_command();<br />if (!(keys &amp; KL3)) switch3_command();<br />keys = PINC;<br />} while ((keys &amp; KEYS_MASK) != KEYS_MASK); /* powtarzaj gdy wciśnięty */<br />}<br />}<br />DDRD &amp;= ~(1 &lt;&lt; PD2);<br />PORTD |= (1 &lt;&lt; PD2);<br /><br />DDR_KL |= (KL1 | KL2 | KL3);<br />PORT_KL &amp;= ~(KL1 | KL2 | KL3);<br /><br />GIFR |= (1 &lt;&lt; INTF0);<br /><br />}[/syntax]<br /></div><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=21510">Morales</a> — 4 kwi 2021, o 12:03</p><hr />
]]></content>
</entry>
</feed>