<?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=23061&amp;mode" />

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2020-05-04T08:52:48+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=4&amp;t=23061&amp;mode</id>
<entry>
<author><name><![CDATA[mario2015]]></name></author>
<updated>2020-05-04T08:52:48+01:00</updated>
<published>2020-05-04T08:52:48+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226923#p226923</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226923#p226923"/>
<title type="html"><![CDATA[Re: EVENT &amp; CALLBACK pomocy.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226923#p226923"><![CDATA[
Dzięki Mirku, odnośnie instrukcji lcd_int w pętli głównej, to było mi to potrzebne tylko na potrzeby testu a z tym przerwaniem to jeszcze powalczę.<br />Pozdrawiam.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=8867">mario2015</a> — 4 maja 2020, o 08:52</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[mirekk36]]></name></author>
<updated>2020-05-04T07:26:29+01:00</updated>
<published>2020-05-04T07:26:29+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226921#p226921</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226921#p226921"/>
<title type="html"><![CDATA[Re: EVENT &amp; CALLBACK pomocy.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226921#p226921"><![CDATA[
kilka podpowiedzi:<br /><br />[syntax=c]while(1)<br />        {<br />                 KBD_EVENT();<br />                lcd_int(1,15,z);<br />         }[/syntax]<br /><br />Jaki jest sens wywoływania miliard razy na sekundę tego &quot;lcd_int()&quot; ?<br /><br /><div class="quotetitle">mario2015 napisał(a):</div><div class="quotecontent"><br />ISR(TIMER2_COMP_vect)<br />{<br />          if( (!key_lock &amp;&amp; !(PINC &amp; KEY1 )) || (!key_lock &amp;&amp; !(PINC &amp; KEY2 )) || (!key_lock &amp;&amp; !(PINC &amp; KEY3 )) ) {<br />           key_lock=1;<br /> <br />           // reakcja na PRESS (wcinięcie przycisku)<br />           nr = (PINC &amp; 0x07 );<br /> <br />          } else if( (key_lock &amp;&amp; (PINC &amp; KEY1 )) || (key_lock &amp;&amp; (PINC &amp; KEY2 )) || (key_lock &amp;&amp; (PINC &amp; KEY3 )) ) key_lock++;<br /> <br />        if(nr!=7) key_flag = 1;<br />        else key_flag = 0;<br /> <br />}<br /></div><br /><br />Pomijając już fakt, że taka obsługa klawiszy (z mojego bloga) nie nadaje się do obsługi wewnątrz przerwań - to na dodatek próbujesz ogarnąć jedną taką sekcją wiele przycisków naraz tzn więcej niż jeden - a to znowu jest niemożliwe nawet poza przerwaniem i wyjaśniam to na blogu - jak to się robi dla kilku przycisków.<br /><br />Ja bym na twoim miejscu porzucił tę obsługę przycisków z bloga i w przerwaniu cyklicznie sprawdzał zwykłą metodą stan przycisków - po prostu stan pinów np co 30-40ms i w zależności od stanu robił dalej to co tutaj czyli uwstawiał sobie flagi<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=54">mirekk36</a> — 4 maja 2020, o 07:26</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[mario2015]]></name></author>
<updated>2020-05-03T22:44:03+01:00</updated>
<published>2020-05-03T22:44:03+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226919#p226919</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226919#p226919"/>
<title type="html"><![CDATA[Re: EVENT &amp; CALLBACK pomocy.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226919#p226919"><![CDATA[
Szkoda, że nikt nie chce więcej pomóc...<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=8867">mario2015</a> — 3 maja 2020, o 22:44</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[mario2015]]></name></author>
<updated>2020-05-01T20:39:23+01:00</updated>
<published>2020-05-01T20:39:23+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226823#p226823</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226823#p226823"/>
<title type="html"><![CDATA[Re: EVENT &amp; CALLBACK pomocy.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226823#p226823"><![CDATA[
Szanowni koledzy.<br />Dzięki waszej pomocy udało mi się sklecić coś takiego jak poniżej.<br />Callback i funkcja KBD_EVENT() chyba działają prawidłowo ponieważ program działa zgodnie z moim oczekiwaniem.<br />Prosił bym jednak forumowiczów o sprawdzenie kodu, czy aby na pewno jest poprawnie napisany, czy też wymaga poprawek albo może optymalizacji.<br />Wydaje mi się, że zrozumiałem zagadnienie. Brakowało mi tylko wyjaśnienia jak tworzyć funkcje zdarzeniowe i callbacki ale dzięki wam<br />chyba mi się udało.<br />Proszę o komentarze co jeszcze jest nie tak i co mam poprawić.<br /><br /><br />[syntax=c]// tu dołączamy biblioteki systemowe<br />#include &lt;avr/io.h&gt;          // dołączenie biblioteki głównej<br />#include &lt;avr/interrupt.h&gt;   // dołączenie biblioteki przerwań<br />#include &lt;util/delay.h&gt;      // dołączenie biblioteki opóżnień<br /><br /><br />// tu dołączamy biblioteki własne<br />#include &quot;LCD/lcd.h&quot;<br /><br />// makra pinów do obsługi klawiszy<br />#define KEY1 (1&lt;&lt;PC0)<br />#define KEY2 (1&lt;&lt;PC1)<br />#define KEY3 (1&lt;&lt;PC2)<br /><br />// makra pinów do obsługi LED<br />#define LED1 (1&lt;&lt;PD7)<br />#define LED2 (1&lt;&lt;PD6)<br />#define LED3 (1&lt;&lt;PD5)<br /><br />void timer2_init(void);<br />void klawisze(uint8_t nr);<br /><br />void (*key_action_wsk)(uint8_t nr); // pusty wskaźnik na funkcję<br />void register_key_action_wsk(void(*callback)(uint8_t nr)) {key_action_wsk = callback; } // funkcja rejestrująca<br /><br /><br />void KBD_EVENT(void);<br /><br />uint8_t z;<br />volatile uint8_t nr, key_lock, key_flag, menu;<br /><br /><br />int main(void)<br />{<br /><br /> PORTC |= KEY1|KEY2|KEY3;  // podciągamy linie klawiszy do VCC<br /> DDRD |= LED1|LED2|LED3;   // piny LED jako WYjścia<br /> PORTD |= LED1|LED2|LED3;  // ustawiamy stan wysoki na pinach LED<br /><br /> _delay_ms(10);<br /><br /><br /> timer2_init();<br /> lcd_init();<br /> lcd_cls();<br /><br /> lcd_str(1,7,&quot;TEST&quot;);<br /> _delay_ms(1000);<br /> lcd_cls();<br /><br /> register_key_action_wsk (klawisze);<br /><br /><br /><br />sei(); // zezwolenie na globalne przerwania<br /><br />while(1)<br />{<br /><br />KBD_EVENT();<br />lcd_int(1,15,z);<br /><br /><br />}<br />}<br /><br /><br />// ================= PROCEDURA OBSŁUGI PRZERWANIA – COMPARE MATCH<br />// pełni funkcję timera programowego wyznaczającego podstawę czasu = 10ms<br />ISR(TIMER2_COMP_vect)<br />{<br />  if( (!key_lock &amp;&amp; !(PINC &amp; KEY1 )) || (!key_lock &amp;&amp; !(PINC &amp; KEY2 )) || (!key_lock &amp;&amp; !(PINC &amp; KEY3 )) ) {<br />   key_lock=1;<br /><br />   // reakcja na PRESS (wcinięcie przycisku)<br />   nr = (PINC &amp; 0x07 );<br /><br />  } else if( (key_lock &amp;&amp; (PINC &amp; KEY1 )) || (key_lock &amp;&amp; (PINC &amp; KEY2 )) || (key_lock &amp;&amp; (PINC &amp; KEY3 )) ) key_lock++;<br /><br />if(nr!=7) key_flag = 1;<br />else key_flag = 0;<br /><br />}<br /><br />// ******* KLAWISZ 1<br />//  if( !key1_lock &amp;&amp; !(PINC &amp; KEY1 ) ) {<br />//   key1_lock=1;<br />//<br />//   // reakcja na PRESS (wcinięcie przycisku)<br />//   PORTC ^= LED1;<br />//<br />//  } else if( key1_lock &amp;&amp; (PINC &amp; KEY1 ) ) key1_lock++;<br /><br />void KBD_EVENT(void)<br />{<br />if(key_flag)<br />{<br />if(key_action_wsk) (*key_action_wsk)(nr);<br />key_flag = 0;<br />nr=7;<br />}<br />}<br /><br />void klawisze(uint8_t nr)<br />{<br /><br /> if (nr==6)<br />  {<br />    lcd_str(1,4,&quot;Nacisnieto&quot;); lcd_str(2,3,&quot;Klawisz nr.1&quot;);<br />    lcd_int(1,1,menu);<br />      PORTD &amp;= ~LED1;<br />      _delay_ms(1);<br />      PORTD |= LED1;<br /><br />      switch(menu)<br />      {<br />  case 1: z--;<br />    if(z&gt;9) z=9;<br />  break;<br />  case 2: z-=2;<br />      if(z&gt;9) z=9;<br />  break;<br />  case 3: z-=5;<br />      if(z&gt;9) z=9;<br />  break;<br />      }<br />  }<br /><br />  if (nr==5)<br />  {<br />    lcd_str(1,4,&quot;Nacisnieto&quot;); lcd_str(2,3,&quot;Klawisz nr.2&quot;);<br />      lcd_int(1,1,menu);<br />        PORTD &amp;= ~LED2;<br />        _delay_ms(1);<br />        PORTD |= LED2;<br /><br />    menu++; if (menu&gt;3) menu=0;<br />      lcd_int(1,1,menu);<br />    }<br /><br />  if (nr==3)<br />    {<br />    lcd_str(1,4,&quot;Nacisnieto&quot;); lcd_str(2,3,&quot;Klawisz nr.3&quot;);<br />    lcd_int(1,1,menu);<br />    PORTD &amp;= ~LED3;<br />    _delay_ms(1);<br />    PORTD |= LED3;<br /><br />      switch(menu)<br />      {<br />  case 1: z++;<br />      if(z&gt;9) z=0;<br />  break;<br />  case 2: z+=2;<br />      if(z&gt;9) z=0;<br />  break;<br />  case 3: z+=5;<br />      if(z&gt;9) z=0;<br />  break;<br />      }<br />    }<br />}<br /><br />void timer2_init(void)<br />{<br />// ustawienie TIMER0 dla F_CPU = 8MHz<br />// przerwanie wykonywane z częstotliwością ok 100Hz (10ms)<br />TCCR2 |= (1&lt;&lt;WGM21); // tryb CTC<br />TCCR2 |= (1&lt;&lt;CS22)|(1&lt;&lt;CS21)|(1&lt;&lt;CS20); // preskaler = 1024<br />OCR2 = 10; // dodatkowy podział przez 10 (rej. porównania)<br />TIMSK |= (1&lt;&lt;OCIE2); // zezwolenie na przerwanie CompareMatch (porównanie)<br />}[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=8867">mario2015</a> — 1 maja 2020, o 20:39</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[mario2015]]></name></author>
<updated>2020-04-28T16:55:59+01:00</updated>
<published>2020-04-28T16:55:59+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226721#p226721</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226721#p226721"/>
<title type="html"><![CDATA[Re: EVENT &amp; CALLBACK pomocy.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226721#p226721"><![CDATA[
Dzięki Harry, to chyba z przemęczenia już nie dowidzę ale i tak nie wiem co dalej, co wstawić do przerwania.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=8867">mario2015</a> — 28 kwi 2020, o 16:55</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Harry]]></name></author>
<updated>2020-04-28T16:47:04+01:00</updated>
<published>2020-04-28T16:47:04+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226720#p226720</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226720#p226720"/>
<title type="html"><![CDATA[Re: EVENT &amp; CALLBACK pomocy.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226720#p226720"><![CDATA[
Masz literówkę w kodzie:<br />[syntax=c]void register_key_action_wsk(void(*callback)(uint8_t nr)) {     key_action_wsk = callback; } // funkcja rejestrująca<br /><br />register_key_actioin_wsk (klawisze);[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14685">Harry</a> — 28 kwi 2020, o 16:47</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[mario2015]]></name></author>
<updated>2020-04-28T16:26:38+01:00</updated>
<published>2020-04-28T16:26:38+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226717#p226717</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226717#p226717"/>
<title type="html"><![CDATA[Re: EVENT &amp; CALLBACK pomocy.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226717#p226717"><![CDATA[
MisterWhite, idąc za twoimi radami, skleciłem coś takiego.<br /><br />[syntax=c]#include &lt;avr/io.h&gt;          // dołączenie biblioteki głównej<br />#include &lt;avr/interrupt.h&gt;   // dołączenie biblioteki przerwań<br />#include &lt;util/delay.h&gt;      // dołączenie biblioteki opóżnień<br /><br /><br />// tu dołączamy biblioteki własne<br />#include &quot;LCD/lcd.h&quot;<br /><br />// makra pinów do obsługi klawiszy<br />#define KEY1 (1&lt;&lt;PC0)<br />#define KEY2 (1&lt;&lt;PC1)<br />#define KEY3 (1&lt;&lt;PC2)<br /><br />// makra pinów do obsługi LED<br />#define LED1 (1&lt;&lt;PD7)<br />#define LED2 (1&lt;&lt;PD6)<br />#define LED3 (1&lt;&lt;PD5)<br /><br />void timer2_init(void);<br />void klawisze(uint8_t nr);<br /><br />void (*key_action_wsk)(uint8_t nr); // pusty wskaźnik na funkcję<br />void register_key_action_wsk(void(*callback)(uint8_t nr)) {key_action_wsk = callback; } // funkcja rejestrująca<br /><br /><br />void KBD_EVENT(void);<br /><br />uint8_t key1_lock, key2_lock, key3_lock;<br />volatile uint8_t key_flag, nr;<br /><br /><br />int main(void)<br />{<br /><br /> PORTC |= KEY1|KEY2|KEY3;  // podciągamy linie klawiszy do VCC<br /> DDRD |= LED1|LED2|LED3;   // piny LED jako WYjścia<br /> PORTD |= LED1|LED2|LED3;  // ustawiamy stan wysoki na pinach LED<br /><br /> _delay_ms(10);<br /><br /><br /> timer2_init();<br /> lcd_init();<br /> lcd_cls();<br /><br /> lcd_str(1,7,&quot;TEST&quot;);<br /> _delay_ms(1500);<br /> lcd_cls();<br /><br /><br /> register_key_actioin_wsk (klawisze);<br /><br /><br />sei(); // zezwolenie na globalne przerwania<br /><br />while(1)<br />{<br />KBD_EVENT();<br /><br />}<br />}<br /><br /><br />// ================= PROCEDURA OBSŁUGI PRZERWANIA – COMPARE MATCH<br />// pełni funkcję timera programowego wyznaczającego podstawę czasu = 10ms<br />ISR(TIMER2_COMP_vect)<br />{<br /><br />}<br /><br />void klawisze(uint8_t nr)<br />{<br /><br />}<br /><br /><br />void KBD_EVENT(void)<br />{<br />if(key_flag)<br />{<br />if(key_action_wsk) (*key_action_wsk)(nr);<br />key_flag = 0;<br />}<br />}<br /><br /><br />void timer2_init(void)<br />{<br />// ustawienie TIMER0 dla F_CPU = 8MHz<br />// przerwanie wykonywane z częstotliwością ok 100Hz (10ms)<br />TCCR2 |= (1&lt;&lt;WGM21); // tryb CTC<br />TCCR2 |= (1&lt;&lt;CS22)|(1&lt;&lt;CS21)|(1&lt;&lt;CS20); // preskaler = 1024<br />OCR2 = 10; // dodatkowy podział przez 10 (rej. porównania)<br />TIMSK |= (1&lt;&lt;OCIE2); // zezwolenie na przerwanie CompareMatch (porównanie)<br />}[/syntax]<br /><br />Jednak w tej linijce<br />[syntax=c]register_key_actioin_wsk (klawisze);[/syntax]<br />eclips krzyczy warningiem:<br /> &quot; warning: implicit declaration of function 'register_key_actioin_wsk' [-Wimplicit-function-declaration]   register_key_actioin_wsk (klawisze);&quot;<br />Oprócz tego nie wiem jak teraz obsłużyć przerwanie , jak się do tego wszystkiego zabrać. <br />Porównywałem też kod do IR w GB ale nie ogarniam tego.<br />Co robię nie tak?<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=8867">mario2015</a> — 28 kwi 2020, o 16:26</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[auers]]></name></author>
<updated>2020-04-27T22:15:34+01:00</updated>
<published>2020-04-27T22:15:34+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226711#p226711</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226711#p226711"/>
<title type="html"><![CDATA[Re: EVENT &amp; CALLBACK pomocy.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226711#p226711"><![CDATA[
<div class="quotetitle">MisterWhite napisał(a):</div><div class="quotecontent"><br />Alef2 napisał(a):<br />Działanie funkcji rejestrującej to tylko nadanie wartości wskaźnikowi, po co pisze sie funkcje, skoro wystarczy tylko przypisanie. A może nie wystarczy?<br /><br />Mirek to tłumaczył kilka razy, a ja też napisałem chwilę dalej. Uzyskujemy w ten sposób parę możliwości . Przede wszystkim możemy bardzo elastycznie,wywołując w trakcie programu funkcję register z róznymi funkcjami obsługi - jako argumentami, zmieniać reakcję programu na to samo zdarzenie. Możemy np. tak napisać program , aby pierwsze naciśnięcie klawisza wywoływało inną reakcję, drugie inną a trzecie jeszcze inną.<br />Poza tym - o czym wspominał Mirek przy &quot;siłowaniu się z callback'ami&quot; - callback pozwala na uruchomienie własnej funkcji obsługującej coś w bibliotece , bez ingerencji w tę bibliotekę.<br /></div><br /><br />Dokładnie to samo można uzyskać bezpośrednio przypisując do wskaźnika adres funkcji i do samego działania to wystarczy. Natomiast w bibliotece zazwyczaj nie udostępniamy samego wskaźnika tylko funkcję która go rejestruje. Tak jest bardziej &quot;elegancko&quot; i bezpieczniej. Nie operujemy bezpośrednio na wskaźniku tylko pośrednio przez funkcję do tego przeznaczoną.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=7806">auers</a> — 27 kwi 2020, o 22:15</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[MisterWhite]]></name></author>
<updated>2020-04-27T18:41:54+01:00</updated>
<published>2020-04-27T18:41:54+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226707#p226707</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226707#p226707"/>
<title type="html"><![CDATA[Re: EVENT &amp; CALLBACK pomocy.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226707#p226707"><![CDATA[
<div class="quotetitle">Alef2 napisał(a):</div><div class="quotecontent"><br /><div class="quotetitle">MisterWhite napisał(a):</div><div class="quotecontent">mechanizm EVENT został stworzony po to aby ograniczyć się tylko do jednego miejsca w programie w którym wywoływana jest reakcja na dane zdarzenie<br /></div>nie rozumiem, jak to możliwe, przecież zmienna key_flag  będzie widoczna w całym programie</div><br />Zgadza się , będzie widoczna w całym programie, chodzi o to, że tylko zmiana tej jednej zmiennej jest warunkiem koniecznym i wystarczającym do uruchomienia zdarzenia EVENT. Jej ustawienie jest jedynym liczącym się świadectwem naciśnięcia klawisza (Naciśnięcia w ogóle, któregokolwiek). A to że jest widoczna w całym programie nie ma nic do rzeczy , pozwala jedynie aby zdarzenie EVENT() wywołać gdziekolwiek, choć jedynym sensownym miejscem wydaje się pętla główna.<br /><div class="quotetitle">Alef2 napisał(a):</div><div class="quotecontent"><br /><div class="quotetitle">MisterWhite napisał(a):</div><div class="quotecontent">Wyjście z przerwania zwraca stan flagi oraz numer naciśniętego klawisza.<br /></div>funkcja obsługi przerwania nie zwraca żadnej wartości</div><br />W sensie programistycznym ,trzymając się formalnej terminologii masz oczywiście rację. Ja wyrażałem sie bardziej literacko mając na myśli iż w trakcie obsługi przerwania uzyskujemy  informację o fakcie naciśnięcia klawisza. Oczywiście nie jest ona uzyskiwana w postaci &quot;return&quot; - bo takiego czegoś w przerwaniu nie ma, lecz w postaci ustawienia flagi i jakiejś zmiennej zawierającej numer naciśniętego lawisza. Można to potraktować jako przekazanie lub też (może mniej szczęśliwie, bo niejednoznacznie ) zwracanie informacji.<br /><div class="quotetitle">Alef2 napisał(a):</div><div class="quotecontent"><br /><div class="quotetitle">MisterWhite napisał(a):</div><div class="quotecontent">Stan flagi, key_flag jest warunkiem uruchomienia funkcji KEY_EVENT()<br /></div>a nie jest tak, że funkcja KEY_EVENT() jest wywoływana za każdym obiegiem petli głównej programu, i pierwsze co sprawdza to stan flagi, i jeżeli nie jest ustawiony to kończy swoje działanie.</div><br />No właśnie dokładnie tak jest z tym że pod  pojęciem uruchomienia funkcji KEY_EVENT rozumiem podjęcie przez nią dalszych działań - w tym wypadku wywołania Twojej funkcji obsługi - a nie stwierdzenia że nie ma nic do roboty i zakończenia działalności. Myślę,że to oczywiste<br /><div class="quotetitle">Alef2 napisał(a):</div><div class="quotecontent"><br />Działanie funkcji rejestrującej to tylko nadanie wartości wskaźnikowi, po co pisze sie funkcje, skoro wystarczy tylko przypisanie. A może nie wystarczy?<br /></div><br />Mirek to tłumaczył kilka razy, a ja też napisałem chwilę dalej. Uzyskujemy w ten sposób parę możliwości . Przede wszystkim możemy bardzo elastycznie,wywołując w trakcie programu funkcję register z róznymi funkcjami obsługi - jako argumentami, zmieniać reakcję programu na to samo zdarzenie. Możemy np. tak napisać program , aby pierwsze naciśnięcie klawisza wywoływało inną reakcję, drugie inną a trzecie jeszcze inną.<br />Poza tym - o czym wspominał Mirek przy &quot;siłowaniu się z callback'ami&quot; - callback  pozwala na uruchomienie własnej funkcji obsługującej coś w bibliotece , bez ingerencji w tę bibliotekę.<br /><div class="quotetitle">Alef2 napisał(a):</div><div class="quotecontent"><br /><div class="quotetitle">MisterWhite napisał(a):</div><div class="quotecontent">void *key_action_wsk (argumenty)<br /></div>czy *key_action nie powinno być w nawiasie void (*key_action)(argumenty), zapis bez nawiasu oznacza funkcje zawracającą pusty wskaźnik. Proszę mnie poprawić jeśli się mylę.</div><br />Tak , oczywiście masz rację , przepraszam za literówkę.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1051">MisterWhite</a> — 27 kwi 2020, o 18:41</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Alef2]]></name></author>
<updated>2020-04-27T17:17:38+01:00</updated>
<published>2020-04-27T17:17:38+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226706#p226706</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226706#p226706"/>
<title type="html"><![CDATA[Re: EVENT &amp; CALLBACK pomocy.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226706#p226706"><![CDATA[
Poprosiłbym o rozwianie mich wątpliwości, bo nie wiem czy dobrze rozumuje.<br />Próbowałem ogarnąć callback'i, ale poległem. Teraz próbuje na nowo.<br /><div class="quotetitle">MisterWhite napisał(a):</div><div class="quotecontent"><br />mechanizm EVENT został stworzony po to aby ograniczyć się tylko do jednego miejsca w programie w którym wywoływana jest reakcja na dane zdarzenie<br /></div>nie rozumiem, jak to możliwe, przecież zmienna key_flag  będzie widoczna w całym programie<br /><div class="quotetitle">MisterWhite napisał(a):</div><div class="quotecontent"><br />Wyjście z przerwania zwraca stan flagi oraz numer naciśniętego klawisza.<br /></div>funkcja obsługi przerwania nie zwraca żadnej wartości<div class="quotetitle">MisterWhite napisał(a):</div><div class="quotecontent"><br />Stan flagi, key_flag jest warunkiem uruchomienia funkcji KEY_EVENT()<br /></div>a nie jest tak, że funkcja KEY_EVENT() jest wywoływana za każdym obiegiem petli głównej programu, i pierwsze co sprawdza to stan flagi, i jeżeli nie jest ustawiony to kończy swoje działanie<br /><br />Działanie funkcji rejestrującej to tylko nadanie wartości wskaźnikowi, po co pisze sie funkcje, skoro wystarczy tylko przypisanie. A może nie wystarczy?<div class="quotetitle">MisterWhite napisał(a):</div><div class="quotecontent"><br />void *key_action_wsk (argumenty)<br /></div>czy *key_action nie powinno być w nawiasie void (*key_action)(argumenty), zapis bez nawiasu oznacza funkcje zawracającą pusty wskaźnik. Proszę mnie poprawić jeśli się mylę.<br /><br />Pytam, bo nie wiem, a chce się dowiedzieć i zrozumieć<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14998">Alef2</a> — 27 kwi 2020, o 17:17</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[MisterWhite]]></name></author>
<updated>2020-04-27T12:15:18+01:00</updated>
<published>2020-04-27T12:15:18+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226704#p226704</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226704#p226704"/>
<title type="html"><![CDATA[Re: EVENT &amp; CALLBACK pomocy.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226704#p226704"><![CDATA[
Witam<br />Właściwie wszystko co istotne powiedział w poprzednim poście Mirek. Może jednak ja spróbuję wytłumaczyć Ci to jak początkujący początkującemu (lub jak wolisz hobbysta hobbyście).<br />Mianowicie - tak jak ja to rozumiem - mechanizm EVENT został stworzony po to aby ograniczyć się tylko do jednego miejsca w programie w którym wywoływana jest reakcja na dane zdarzenie. Tak więc musisz najpierw określić takie zjawisko które w sposób jednoznaczny potwierdzi ,że zaszło działanie które Cię interesuje. Musi to być coś jednoznacznego i unikalnego. Tak jak poradził Mirek można zrobić to w osłudze przerwania, co np. 10ms.<br />Wprowadzasz dodatkową zmienną, np. key_flag i w obsłudze przerwania sprawdzasz czy którykolwiek z klawiszy nie został naciśnięty. Jeśli tak , to stan key_flag zmienia się na 1. Wyjście z przerwania zwraca stan flagi oraz numer naciśniętego klawisza.<br />Stan flagi, key_flag jest warunkiem uruchomienia funkcji KEY_EVENT(). Jeśli flaga nie jest ustawiona KEY_EVENT nic nie robi, nie zajmując czasu w pętli głównej, jeśli jest ustawiona wdraża akcję wywołując Twoją funkcję obsługi.<br />Oczywiście można w prosty sposób wywołać funkcję obsługi, wpisując jej nazwę lub wskażnik do niej. Aby jednak uzyskać dodatkowe funkjonalności wprowadzono bardzo sprytny mechanizm callback.<br />W zasadzie sprowadza sie on do tego że  funkcję,  która ma wykonać działanie  wywołujemy z pomocą wskaźnika który w momencie definicji nie jest określony (jest wskaźnikiem pustym) . Dopiero w trakcie działania programu, a dokładnie najczęściej w trakcie inicjacji ten pusty wskaźnik &quot;kierujemy&quot; na jakąś wybraną przez nas funkcję. Ten mechanizm kierowania (czy też może błędnie ale bardziej obrazowo) przypisania konkretnej funkcji do wywołującego , pustego początkowo wskaźnika nazywamy rejestracją i wykonujemy za pomocą wywołania specjalnej funkcji register. Taką rejestrację możemy wykonywać dowolnie w trakcie działania programu zmieniając w dowolny sposób funkcje które będą wywoływane w wyniku zdarzenia EVENT().<br />Funkcja register działa tak,że przypisuje ten pusty wskaźnik do wskaźnika funkcji którą chcemy wywołać . W ten sposób ten pusty dotychczas wskaźnik zaczyna wskazywać od tego momentu (wywołnia funkcji register) na okresloną przez nas własną funkcję.<br />Reasumując:<br />Tworzymy jakiś pusty wskaźnik na funkcję mającą argumenty w postaci (argumenty)<br />[syntax=c]void *key_action_wsk (argumenty)[/syntax]<br />Tworzymy funkcję rejestrującą <br />[syntax=c]register_key_action_wsk ((*callback)(argumenty)) {<br />       key_action_key = callback;<br />       }[/syntax]<br />nazewnictwo jest zupełnie dowolne, ale przyjęta przez Mirka konwencja wykorzystywania nazw związanych z działąniem wydaje się być doskonała<br /><br />Tworzysz funkcję EVENT() <br />[syntax=c]void EVENT_KEY (void){<br />  if (key_flag){<br />  if (key_action_wsk) (*key_action_wsk )(argumenty);<br />  key_flag = 0;<br />   }<br />  }[/syntax]<br /><br />I to wszystko. Musisz tylko pamiętać aby przed uruchomieniem pętli głównej przypisac wskaźnik key_action_wsk do jakiejś swojej funkcji obsługi przez wywołanie funkcji register<br /><br />[syntax=c]register_key_action_wsk (twoja_funkcja);[/syntax]<br /><br />Jeśli tego nie zrobisz , pierwsza część warunku w funkcji EVENT będie niespełniona i nie zostanie wywołane żadne działanie. <br />Mnie osobiście największą trudność sprawiła składnia:<br />1. w definicji pustego wskaźnika key_action_wsk i w funkcji register trzeba jak argumenty wpisać takie same argumenty, jakie będą występowac w Twojej własnej funkcji bsługi<br />2. Funkcję register wywołujesz wpisując jak argument tylko nazwę Twojej własnej funkcji, bez żdnych  argumentów dodatkowych.<br />To tyle . Przepraszam, że tyle nudziłem na tematy oczywiste, ale mnie to sprawiało w pewnym momencie spore  trudności<br />Oczywiście to wszystko jest dokładnie i szcegółowo opisane w książkach Mirka, ale niestety w różnych miejscach. Gdy człowiek jeszcze niedokładnie wie czego i gdzie szukać to jest to nieco kłopotliwe.<br />Pozdrawiam<br />W<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1051">MisterWhite</a> — 27 kwi 2020, o 12:15</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[mirekk36]]></name></author>
<updated>2020-04-26T16:53:08+01:00</updated>
<published>2020-04-26T16:53:08+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226672#p226672</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226672#p226672"/>
<title type="html"><![CDATA[Re: EVENT &amp; CALLBACK pomocy.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226672#p226672"><![CDATA[
0. Przygotuj funkcję do rejestracji Callbacka - który wywoła funkcję użytkownika i przekaże jej info jaki przycisk został wciśnięty<br /><br /><br />1. Wyprowadź w obsłudze Timera co 10ms, funkcję która będzie sprawdzała stan przycisków - i daj jej nazwę np KBD_EVENT() - to będzie obsługa zdarzeń<br /><br />2. Gdy ta funkcja zobaczy że jakiś przycisk został wciśnięty to może wywołać callbacka .... ale najpierw zrób jego rejestrację na początku - może w pkt.nr 0 - już go dodaję <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /><br /><br />Przykłady takich zachowań masz w GB tzn tam jest najwięcej takich przykładów jak z tym postępować - postaraj się prześledzić książkę w tym zakresie<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=54">mirekk36</a> — 26 kwi 2020, o 16:53</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[mario2015]]></name></author>
<updated>2020-04-26T15:47:17+01:00</updated>
<published>2020-04-26T15:47:17+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226669#p226669</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226669#p226669"/>
<title type="html"><![CDATA[Re: EVENT &amp; CALLBACK pomocy.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226669#p226669"><![CDATA[
MirkoT, mi chodzi o to, żeby przedstawiony program działał w następujący sposób:<br />W przerwaniu co 10ms sprawdzam stan klawiszy. Jeżeli nie zostanie naciśnięty żaden klawisz , to oczywiście nic się nie dzieje.<br />Teraz z kolei funkcją zdarzeniową KEY_EVENT() , chciałbym jeśli dojdzie do zdarzenia, wysłać do funkcji klawisze(),<br />wiadomość, że został naciśnięty np. klawisz nr.2 za pomocą callback-a i nie wiem jak się zabrać do tego.<br />Na przykładzie tego programu, nie wiem co powinno się znaleźć w obsłudze przerwania, jak napisać tę funkcję KEY_EVENT() a<br />moja funkcja, żeby była wywołana za pomocą callback-a. Nie wiem, myślę że teraz trochę jaśniej wytłumaczyłem mój problem.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=8867">mario2015</a> — 26 kwi 2020, o 15:47</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[MirkoT]]></name></author>
<updated>2020-04-26T08:51:18+01:00</updated>
<published>2020-04-26T08:51:18+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226644#p226644</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226644#p226644"/>
<title type="html"><![CDATA[Re: EVENT &amp; CALLBACK pomocy.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226644#p226644"><![CDATA[
Ale może napisz bardziej konkretnie z czym właściwie masz problem. <br />Gdzie potrzebujesz pomocy, wytłumaczenia. <br />Przeczytałem Twój post 3 razy i nadal nie wiem <img src="https://forum.atnel.pl/images/smilies/icon_e_sad.gif" alt=":-(" title="Smutny" /> pewnie wiek robi swoje...<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=189">MirkoT</a> — 26 kwi 2020, o 08:51</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[mario2015]]></name></author>
<updated>2020-04-25T21:58:18+01:00</updated>
<published>2020-04-25T21:58:18+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226642#p226642</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226642#p226642"/>
<title type="html"><![CDATA[Re: EVENT &amp; CALLBACK pomocy.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226642#p226642"><![CDATA[
Tak. Zgadzam się i wiem, że w przerwaniu muszę &quot;szybko działać&quot;<br />może źle się wyraziłem. W przerwaniu chcę tylko sprawdzić, czy doszło do zdarzenia. Jeśli tak to do jakiego tzn. który klawisz został naciśnięty? Przekaż to funkcji zdarzeniowej EVENT, jeśli żaden klawisz , to nic nie rób.<br />Jeśli przekazałeś te dane do funkcji EVENT, to wywołaj callbacka z funkcją, której na tym etapie nie znam ale przekaż argument np: Tak naciśnięty klawisz nr.1<br /><br />Acha, PIN-y celowo są podpięte do jednego portu. To na potrzeby zrozumienia i nauki.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=8867">mario2015</a> — 25 kwi 2020, o 21:58</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[JarekB]]></name></author>
<updated>2020-04-25T20:56:20+01:00</updated>
<published>2020-04-25T20:56:20+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226638#p226638</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226638#p226638"/>
<title type="html"><![CDATA[Re: EVENT &amp; CALLBACK pomocy.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226638#p226638"><![CDATA[
Tak na początek bez zbytniej analizy kodu to podszedłbym inaczej do obsługi przerwania.<br />[syntax=c]#include &lt;avr/io.h&gt;<br />#include &lt;util/delay.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br /><br />volatile uint8_t klawisze_stan;<br />uint8_t klawisze_temp;<br />                                                        <br />void KEY_EVENT( void );<br /><br />int main( void ) {<br />    while ( 1 ) {                   <br />        KEY_EVENT();<br />    }                          <br />}<br /><br /><br /><br />void KEY_EVENT( void ) {<br />    if ( klawisze_stan != klawisze_temp ) {<br />        // wykonaj funkcje sprawdzenia <br />        klawisze_temp = klawisze_stan;<br />    }<br /><br />}<br /><br /><br />ISR( TIMER2_COMP_vect ) {<br />    klawisze_stan = PINC;<br />}[/syntax]<br /><br /><br />Po prostu w przerwaniu robiłbym jak najmniej. <br />Resztą niech się zajmie zdarzenie.<br />Zauważ że piny masz podpięte do jednego portu.<br />To taki pierwsza uwaga.<br />P/S <br />Pewnie narobiłem jakiś baboli ale chodzi mi o idee.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=18188">JarekB</a> — 25 kwi 2020, o 20:56</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[mario2015]]></name></author>
<updated>2020-04-25T19:24:04+01:00</updated>
<published>2020-04-25T19:24:04+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226633#p226633</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226633#p226633"/>
<title type="html"><![CDATA[EVENT &amp; CALLBACK pomocy.]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=23061&amp;p=226633#p226633"><![CDATA[
Witam wszystkich i pozdrawiam serdecznie.<br />Korona wirus uziemił nas skutecznie ale za to mamy więcej czasu na hobby.<br />Mam taki problem do rozwiązania.<br />Poniżej wstawiam kod testowy i opiszę o co chodzi.<br />1. Próbuję walczyć z funkcjami zdarzeniowymi i callback-ami.<br />2. Poniższy program ( na razie działa) ma mi posłużyć do opanowania posługiwania się eventami i callbackami<br />3. Założenie potrzebne do nauki:<br />   a) wykorzystać przerwanie co 10ms jako timer sprzętowy (konfiguracja załatwiona, mam nadzieję, że poprawnie dla ATmega8 8MHz)<br />   b) skorzystać z funkcji zdarzeniowej, która będzie wywoływana w pętli głównej.<br />   c) w obsłudze przerwania - sprawdzanie stanu pinów na których są klawisze (przyciski) i reakcja tej funkcji zdarzeniowej jak któryś z przycisków naciśnięty<br />   d) przekazanie do mojej funkcji &quot; klawisze()&quot; informacji , że został naciśnięty przycisk i który był naciśnięty (na razie do testów bez callbacka użyłem funkcji bez argumentów)<br />Dalej z obsługą jak mają działać klawisze, to już chyba sobie poradzę. <br />Wiem też, że moja funkcja musi być zarejestrowana. Walczę z tym sporo czasu, posiłkując się BB, GB i nawet poradnikiem o callbackach i nadal nie wiem jak tego użyć w poniższym kodzie.<br />Chyba wiek też robi swoje. Na razie robię to wszystko w jednym pliku ale na tym etapie to chyba nie istotne.<br />Proszę szanownych kolegów aby mnie ktoś naprowadził jak to ugryźć.<br /><br />Proszę o wyrozumiałość dla laika.<br /><br /><br />Acha, biblioteka do lcd trochę pozmieniana, dlatego takie dziwne zapisy.<br />[syntax=c]// tu dołączamy biblioteki systemowe<br />#include &lt;avr/io.h&gt;          // dołączenie biblioteki głównej<br />#include &lt;avr/interrupt.h&gt;   // dołączenie biblioteki przerwań<br />#include &lt;util/delay.h&gt;      // dołączenie biblioteki opóżnień<br /><br /><br />// tu dołączamy biblioteki własne<br />#include &quot;LCD/lcd.h&quot;<br /><br />// makra pinów do obsługi klawiszy<br />#define KEY1 (1&lt;&lt;PC0)<br />#define KEY2 (1&lt;&lt;PC1)<br />#define KEY3 (1&lt;&lt;PC2)<br /><br />#define LED1 (1&lt;&lt;PD7)<br />#define LED2 (1&lt;&lt;PD6)<br />#define LED3 (1&lt;&lt;PD5)<br /><br />void klawisze(void);<br /><br />uint8_t key1_lock, key2_lock, key3_lock;<br /><br /><br /><br />int main(void)<br />{<br /><br /> PORTC |= KEY1|KEY2|KEY3;  // podciągamy linie klawiszy do VCC<br /> DDRD |= LED1|LED2|LED3;   // piny LED jako WYjścia<br /> PORTD |= LED1|LED2|LED3;<br /><br /> _delay_ms(10);<br /><br />// ustawienie TIMER0 dla F_CPU = 8MHz<br />// przerwanie wykonywane z częstotliwością ok 100Hz (10ms)<br />TCCR2 |= (1&lt;&lt;WGM21); // tryb CTC<br />TCCR2 |= (1&lt;&lt;CS22)|(1&lt;&lt;CS21)|(1&lt;&lt;CS20); // preskaler = 1024<br />OCR2 = 10; // dodatkowy podział przez 10 (rej. porównania)<br />TIMSK |= (1&lt;&lt;OCIE2); // zezwolenie na przerwanie CompareMatch (porównanie)<br /><br /> lcd_init();<br /> lcd_cls();<br /><br /> lcd_str(1,7,&quot;TEST&quot;);<br /> _delay_ms(1500);<br /> lcd_cls();<br /><br /><br />sei(); // zezwolenie na globalne przerwania<br /><br />while(1)<br />{<br />//KEY_EVENT();<br /><br />klawisze();<br /><br />}<br />}<br /><br /><br />// ================= PROCEDURA OBSŁUGI PRZERWANIA – COMPARE MATCH<br />// pełni funkcję timera programowego wyznaczającego podstawę czasu = 10ms<br />ISR(TIMER2_COMP_vect)<br />{<br />// 1.sprawdzic stan przyciskow<br />// 2. jesli zaden, to nic nie rob<br />// 3.jesli ktorykolwiek nacisniety, to ktory<br />// 4.wyslij informacje do mojej funkcji, ze zostal nacisniety klawisz nr. x<br /><br />}<br /><br /><br />void klawisze(void)<br />{<br />   uint8_t a;<br />   uint8_t b;<br />   uint8_t c;<br /><br />  // ******* KLAWISZ 1<br />  if( !key1_lock &amp;&amp; !(PINC &amp; KEY1 ) ) {<br />   key1_lock=1;<br /><br />   // reakcja na PRESS (wcinięcie przycisku)<br />   {<br />   PORTD ^= LED1;<br />   }<br />  } else if( key1_lock &amp;&amp; (PINC &amp; KEY1 ) ) key1_lock++;<br /><br />  if(!( PIND &amp; LED1 )) a = 0;<br />  else a = 1;<br />  lcd_str(1,1,&quot;Led1&quot;);<br />  if (a) lcd_str(2,1,&quot;Off&quot;);<br />  else lcd_str(2,1,&quot; On&quot;);<br /><br />  // ******* KLAWISZ 2<br />  if( !key2_lock &amp;&amp; !(PINC &amp; KEY2 ) ) {<br />   key2_lock=1;<br /><br />   // reakcja na PRESS (wcinięcie przycisku)<br />   PORTD ^= LED2;<br /><br />  } else if( key2_lock &amp;&amp; (PINC &amp; KEY2 ) ) key2_lock++;<br /><br />  if(!( PIND &amp; LED2 )) b = 0;<br />  else b = 1;<br />  lcd_str(1,7,&quot;Led2&quot;);<br />  if (b) lcd_str(2,7,&quot;Off&quot;);<br />  else lcd_str(2,7,&quot; On&quot;);<br /><br />  // ******* KLAWISZ 3<br />  if( !key3_lock &amp;&amp; !(PINC &amp; KEY3 ) ) {<br />   key3_lock=1;<br /><br />   // reakcja na PRESS (wcinięcie przycisku)<br />   PORTD ^= LED3;<br /><br />  } else if( key3_lock &amp;&amp; (PINC &amp; KEY3 ) ) key3_lock++;<br /><br />  if(!( PIND &amp; LED3 )) c = 0;<br />  else c = 1;<br />  lcd_str(1,13,&quot;Led3&quot;);<br />  if (c) lcd_str(2,13,&quot;Off&quot;);<br />  else lcd_str(2,13,&quot; On&quot;);<br />}[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=8867">mario2015</a> — 25 kwi 2020, o 19:24</p><hr />
]]></content>
</entry>
</feed>