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

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2014-07-11T15:39:36+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=4&amp;t=7384&amp;mode</id>
<entry>
<author><name><![CDATA[dawidek034]]></name></author>
<updated>2014-07-11T15:39:36+01:00</updated>
<published>2014-07-11T15:39:36+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=87261#p87261</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=87261#p87261"/>
<title type="html"><![CDATA[Re: Kłopot z przerwaniami]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=87261#p87261"><![CDATA[
Witam. Po przerwie związanej z sesją, chciałbym powrócić do dalszego rozbudowywania menu. Troszkę przebudowałem swoje menu i wygląda ona następująco:<br />[syntax=c]#define E_IDDLE 0<br />#define E_Prev 1<br />#define E_Select 2<br />#define E_Next 3<br /><br /><br /><br />void menuiddle( uint8_t event);<br />void zmianaMENU();<br />void godzina( uint8_t event);<br />void up(void);<br />void down(void);<br />void ok(void);<br /><br /><br /><br /><br />const uint8_t MN01&#91;&#93; PROGMEM=&quot;1.Godzina&quot;;<br />const  uint8_t subMN01_1&#91;&#93; PROGMEM=&quot;1_1.Czas&quot;;<br />const uint8_t subMN01_2&#91;&#93; PROGMEM=&quot;1_2.Data&quot;;<br />const uint8_t MN02&#91;&#93; PROGMEM=&quot;2.Wspol&quot;;<br />const uint8_t MN03&#91;&#93;PROGMEM = &quot;3.COS&quot;;<br /><br /><br />typedef struct<br />{<br />uint8_t next_state&#91;4&#93;;//przejścia do następnych stanów<br />void (*callback)(uint8_t event);//funkcja zwrotna<br />uint8_t* pierwszyWiersz;<br />uint8_t* drugiWiersz;<br />} menu_item;<br /><br /><br />enum {<br />Hello,<br />Menu1,<br />SubMenu1_1,<br />SubMenu1_1_1,<br />Submenu1_2,<br />Menu2,<br />Menu3<br />} ;<br /><br /><br />const menu_item menu&#91;&#93; = {<br />//Iddle,Prev, Select,Next<br />{{Hello, Menu1, Menu1, Menu1}, NULL,NULL, NULL},<br />{{Menu1, Menu1, Menu2, SubMenu1_1}, NULL, MN01,MN02},<br />{{SubMenu1_1, Menu1, Submenu1_2, SubMenu1_1_1},NULL, subMN01_1, subMN01_2},<br />{{SubMenu1_1_1, SubMenu1_1, SubMenu1_1_1, SubMenu1_1_1},godzina, NULL, NULL},<br />{{Submenu1_2, Menu1, SubMenu1_1, Submenu1_2}, NULL, subMN01_2, subMN01_1},<br />{{Menu2, Menu2, Menu3, Menu2}, NULL, MN02, MN03},<br />{{Menu3, Menu3, Menu1, Menu3}, NULL, MN03, MN01},<br /><br />};[/syntax]<br /><br />Do obsługi wykorzystuje funkcję<br />[syntax=c]void zmianaMENU() {<br />current_menu = menu&#91;current_menu&#93;.next_state&#91;menu_event&#93;;<br />lcd_cls();<br />//wyświetl 1-szą linię<br />if (menu&#91;current_menu&#93;.pierwszyWiersz)<br />{<br /><br />lcd_locate(0,1);<br />lcd_str_P((char*)menu&#91;current_menu&#93;.pierwszyWiersz);<br />}<br />//wyświetl 2-gą linię<br />if (menu&#91;current_menu&#93;.drugiWiersz)<br />{<br />lcd_locate(1,1);<br />lcd_str_P((char*)menu&#91;current_menu&#93;.drugiWiersz);<br />}<br />//wywolaj funkcje zwrotna<br />if (menu&#91;current_menu&#93;.callback)<br />menu&#91;current_menu&#93;.callback(menu_event);<br /><br /><br />//skasuj zdarzenie<br />menu_event = E_IDDLE;<br />}[/syntax]<br /><br />Tak prezentuje się w całości plik main.c<br />[syntax=c]#include &lt;avr/io.h&gt;<br />#include &lt;util/delay.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;avr/pgmspace.h&gt;<br />#include &lt;stdlib.h&gt;<br /><br />#include &quot;klawisz/klawisz.h&quot;<br />#include &quot;menu.h&quot;<br />#include &quot;LCD/lcd44780.h&quot; //biblioteka_LCD<br /><br />volatile  uint8_tcurrent_menu = 0;<br />volatile  uint8_tmenu_event = E_IDDLE;<br />volatile uint16_t Timer3;<br /><br />uint8_t key1_lock, key2_lock, key3_lock;<br /><br /><br />/*POCZATEK_FUNKCJI_MAIN*/<br />int main(void) {<br />//DDRD |= (1&lt;&lt;PD7);<br />//PORTD &amp;=~(1&lt;&lt;PD7);<br />//DDRC |= (1&lt;&lt;PC7);<br /><br />PORTC |= KEY1 | KEY2 | KEY3;<br /><br />TCCR2  |= (1&lt;&lt;WGM21);<br />TCCR2  |= (1&lt;&lt;CS22)|(1&lt;&lt;CS21)|(1&lt;&lt;CS20);<br />OCR2  = 108;<br />TIMSK  = (1&lt;&lt;OCIE2);<br /><br />lcd_init();<br />sei();<br /><br /><br /><br />/*POCZATEK_PETLI_WHILE*/<br />while(1) {<br />key_press( &amp;key1_lock, &amp;PINC, KEY1, up );<br />key_press( &amp;key2_lock, &amp;PINC, KEY2, down );<br />key_press( &amp;key3_lock, &amp;PINC, KEY3, ok );<br /><br /><br />if(menu_event) {<br />zmianaMENU();<br />}<br />if(current_menu == E_IDDLE)<br />menuiddle(E_IDDLE);<br /><br /><br /><br />}<br />/*KONIEC_PETLI_WHILE*/<br /><br /><br />}<br />/*KONIEC_FUNKCJI_MAIN*/<br /><br /><br /><br />void up(void)<br />{<br />menu_event=E_Prev;<br />}<br />void down(void)<br />{<br />menu_event=E_Next;<br />}<br />void ok(void)<br />{<br />menu_event=E_Select;<br />}<br /><br />void zmianaMENU() {<br />current_menu = menu&#91;current_menu&#93;.next_state&#91;menu_event&#93;;<br />lcd_cls();<br />//wyświetl 1-szą linię<br />if (menu&#91;current_menu&#93;.pierwszyWiersz)<br />{<br /><br />lcd_locate(0,1);<br />lcd_str_P((char*)menu&#91;current_menu&#93;.pierwszyWiersz);<br />}<br />//wyświetl 2-gą linię<br />if (menu&#91;current_menu&#93;.drugiWiersz)<br />{<br />lcd_locate(1,1);<br />lcd_str_P((char*)menu&#91;current_menu&#93;.drugiWiersz);<br />}<br />//wywolaj funkcje zwrotna<br />if (menu&#91;current_menu&#93;.callback)<br />menu&#91;current_menu&#93;.callback(menu_event);<br /><br /><br />//skasuj zdarzenie<br />menu_event = E_IDDLE;<br />}<br /><br /><br />ISR(TIMER2_COMP_vect) {<br />uint16_t n;<br /><br />n = Timer3;<br />if(n)<br />Timer3 = --n;<br />}[/syntax]<br /><br />Mój problem polega dosłownie identycznie jak poprzednio. Czyli wchodząc do 'SubMenu1_1_1' chciałbym otrzymywać przykładowo pomiary czasu_rzeczywistego. Rozwiązanie z poprzedniego menu nie potrafię przenieść na obecne menu. Czy ktoś mógłby naprowadzić jak sobie z tym poradzić?<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1862">dawidek034</a> — 11 lip 2014, o 15:39</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[dawidek034]]></name></author>
<updated>2014-06-12T22:38:45+01:00</updated>
<published>2014-06-12T22:38:45+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=84293#p84293</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=84293#p84293"/>
<title type="html"><![CDATA[Re: Kłopot z przerwaniami]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=84293#p84293"><![CDATA[
Bardzo dziękuje za porady. Mam nadzieje, że teraz się zgłoszę dopiero w celu zaprezentowania działającego menu <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1862">dawidek034</a> — 12 cze 2014, o 22:38</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[dawidek034]]></name></author>
<updated>2014-06-12T21:56:35+01:00</updated>
<published>2014-06-12T21:56:35+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=84285#p84285</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=84285#p84285"/>
<title type="html"><![CDATA[Re: Kłopot z przerwaniami]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=84285#p84285"><![CDATA[
Już wiem czym było spowodowane moje zagubienie  <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" />  Deklaracje funkcji zostały poczynione tylko, że nie zdefiniowałem funkcji i dlatego był błąd wyrzucany z strony kompilatora<br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />../main.c:50: error: 'pomiarTempAction' undeclared here (not in a function)<br /></div><br /><br />Poniżej daje graf przejść <br /><a href="http://forum.atnel.pl/_obrazki/o/1862/43fbed698ad2e8788e5a8f9d6d5f46bd.jpg"  class="postlink"><img src="http://forum.atnel.pl/_obrazki/o/thumb/1862/43fbed698ad2e8788e5a8f9d6d5f46bd.jpg" alt="Obrazek" /></a><br /><br />Miałem zrobiony już wcześniej ten graf, ale niestety nie umiałem go zbytnio przełożyć na program nawet przy tak prostym grafie.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1862">dawidek034</a> — 12 cze 2014, o 21:56</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[mirekk36]]></name></author>
<updated>2014-06-12T21:28:27+01:00</updated>
<published>2014-06-12T21:28:27+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=84282#p84282</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=84282#p84282"/>
<title type="html"><![CDATA[Re: Kłopot z przerwaniami]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=84282#p84282"><![CDATA[
<div class="quotetitle">mokrowski napisał(a):</div><div class="quotecontent"><br />Kolego, ty chyba jednak nie wziąłeś kartki i nie narysowałeś tych stanów<br /></div><br /><br />Ja tylko od siebie dodam - że nawet przy w sumie tak stosunkowo niby prostym programie ... sam (tak dla siebie) nie odważyłbym się marnować czasu - bez uprzedniego ostrego popracowania z kartką i ołówkiem a nawet gumką <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /> Na prawdę to nie tylko oszczędność czasu ale i nerwów .... własnych oczywiście.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=54">mirekk36</a> — 12 cze 2014, o 21:28</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[dawidek034]]></name></author>
<updated>2014-06-12T20:48:24+01:00</updated>
<published>2014-06-12T20:48:24+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=84267#p84267</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=84267#p84267"/>
<title type="html"><![CDATA[Re: Kłopot z przerwaniami]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=84267#p84267"><![CDATA[
Staram się rozwiązać problem, jak mam zaimplementować funkcję do tego. Bo zwraca mi taki komunikat:<br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />../main.c:50: error: 'pomiarTempAction' undeclared here (not in a function)<br /></div><br /><br />Więc zrobiłem coś takiego:<br />[syntax=c]#ifndef USED_FOR_TARGET<br />#define pomiarTempAction 0<br />#define pomiarWilgotnoscAction 1<br />#define pomiarWartoscAction 2<br />#define menuTempAction 3<br />#define menuWilgotnoscAction 4<br />#define menuWartoscAction 5<br />#endif[/syntax]<br /><br />Tylko, że teraz w konsoli dostaje warning:<br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />../main.c:50: warning: initialization makes pointer from integer without a cast<br /></div><br /><br />Jeżeli można wytłumaczyć ten fragment bo nie mam pojęcia jak zadeklarować funkcję dla każdego stanu.  <img src="https://forum.atnel.pl/images/smilies/icon_neutral.gif" alt=":|" title="Średnio zadowolony" /><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1862">dawidek034</a> — 12 cze 2014, o 20:48</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[dawidek034]]></name></author>
<updated>2014-06-12T00:12:58+01:00</updated>
<published>2014-06-12T00:12:58+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=84192#p84192</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=84192#p84192"/>
<title type="html"><![CDATA[Re: Kłopot z przerwaniami]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=84192#p84192"><![CDATA[
Dokładnie o coś takiego mi właśnie chodzi. Wprowadziłem zmiany niby zachowuje się tak jak chcę, ale to jest bardzo dalekie od rozwiązania uniwersalnego.<br />[syntax=c]enum pomiary { pomiarTemp, pomiarWilgotnosc, pomiarWartosc };<br />enum pomiary s_pomiary = 10;[/syntax]<br /><br />przypisałem s_pomiary wartość aby przy pierwszym uruchomieniu pętli głównej nie wchodził mi automatycznie do pomiarTemp<br /><br />W pętli głównej <br />[syntax=c]if(s_pomiary == pomiarTemp) {<br />lcd_locate(1,4);<br />lcd_str(&quot;Temp&quot;);<br />}<br />if(s_pomiary == pomiarWilgotnosc) {<br />lcd_locate(1,4);<br />lcd_str(&quot;wilgot&quot;);<br />if(!Timer2) {<br />Timer2 = 20;<br />PORTD ^= LED1;<br />}<br />}<br />if(s_pomiary == pomiarWartosc) {<br />lcd_locate(1,4);<br />lcd_str(&quot;wartosci&quot;);<br />}([/syntax]<br /><br />Tylko, że nieudolnie wychodzi mi obsługa key_enter. Zrobiłem coś takiego w funkcji do której się odwołuje klawisz_enter<br />[syntax=c]void kl2_press(void){<br />s_pomiary = element_menu;<br />}[/syntax]<br /><br />oraz dodałem coś takiego dla klawisza_menu aby przy ponownym wciśnięciu go wychodzić z stanu_pomiaru<br />[syntax=c]void kl1_press(void){<br />element_menu++;<br />lcd_cls();<br />s_pomiary= 50;<br />}[/syntax]<br /><br />tutaj dodam całość kodu, bo pokrętnie to tłumaczone<br />[syntax=c]#include &lt;avr/io.h&gt;<br />#include &lt;util/delay.h&gt;<br />#include &quot;LCD/lcd44780.h&quot;<br />#include &quot;1Wire/ds18x20.h&quot;<br />#include &lt;avr/interrupt.h&gt;<br /><br />#define KEY3 (1&lt;&lt;PC0)<br />#define KEY2 (1&lt;&lt;PC1)<br />#define LED (1&lt;&lt;PD7)<br />#define LED1 (1&lt;&lt;PD6)<br /><br /><br />volatile uint16_t Timer1, Timer2, Timer3;<br /><br />void superDebounce(volatile uint8_t *KPIN,<br />uint8_t key_mask, uint16_t rep_time, uint16_t rep_wait,<br />void (*push_proc)(void), void (*rep_proc)(void) );<br />void kl1_press(void);<br />void kl1_rep(void);<br />void kl2_press(void);<br />void kl2_rep(void);<br />void show_menu(uint8_t element);<br />void test();<br />uint8_t element_menu = 0;<br /><br /><br />enum menu { menuTemp, menuWilgotnosc, menuWartosci  };<br />enum menu s_menu ;<br /><br />enum pomiary { pomiarTemp , pomiarWilgotnosc , pomiarWartosc  };<br />enum pomiary s_pomiary = 10;<br /><br /><br />int main(void) {<br /><br />DDRD |= LED | LED1;<br />PORTD &amp;=~ LED | LED1;<br /><br />PORTC |= KEY3 | KEY2;<br />TCCR2  |= (1&lt;&lt;WGM21);<br />TCCR2  |= (1&lt;&lt;CS22)|(1&lt;&lt;CS21)|(1&lt;&lt;CS20);<br />OCR2  = 108;<br />TIMSK  = (1&lt;&lt;OCIE2);<br /><br /><br /><br />lcd_init();<br />sei();<br /><br />while(1) {<br />superDebounce(&amp;PINC, KEY3, 20, 500, kl1_press, kl1_rep );<br />superDebounce(&amp;PINC, KEY2, 80, 400, kl2_press, kl2_rep );<br /><br />show_menu(element_menu);<br />if(element_menu &gt; 2)<br />element_menu = 0;<br /><br />if(s_pomiary == pomiarTemp) {<br />lcd_locate(1,4);<br />lcd_str(&quot;Temp&quot;);<br />}<br />if(s_pomiary == pomiarWilgotnosc) {<br />lcd_locate(1,4);<br />lcd_str(&quot;wilgot&quot;);<br />if(!Timer2) {<br />Timer2 = 20;<br />PORTD ^= LED1;<br />}<br />}<br />if(s_pomiary == pomiarWartosc) {<br />lcd_locate(1,4);<br />lcd_str(&quot;wartosci&quot;);<br />}<br />test();<br /><br />}<br />}<br /><br />void show_menu(uint8_t element) {<br />switch(element) {<br />case menuTemp:<br />lcd_locate(0,4);<br />lcd_str(&quot;Temp&quot;);<br />break;<br />case menuWilgotnosc:<br />lcd_locate(0,4);<br />lcd_str(&quot;Wilg&quot;);<br />break;<br />case menuWartosci:<br />lcd_locate(0,4);<br />lcd_str(&quot;Wart&quot;);<br />break;<br />}<br /><br />}<br /><br />void superDebounce(volatile uint8_t *KPIN,<br />uint8_t key_mask, uint16_t rep_time, uint16_t rep_wait,<br />void (*push_proc)(void), void (*rep_proc)(void) ) {<br /><br />enum KS {idle, debounce, go_rep, wait_rep, rep};<br /><br />static enum KS key_state;<br />static uint8_t last_key;<br />uint8_t key_press;<br /><br />// zabezpieczenie przed wykonywaniem tej samej funkcji dla<br />// dwóch klawiszy wciskanych jednocześnie (zawsze będzie<br />// wykonywana odpowiednia akcja dla tego, który został<br />// wciśnięty jako pierwszy<br />if( last_key &amp;&amp; last_key != key_mask ) return;<br /><br />key_press = !(*KPIN &amp; key_mask);<br /><br />if( key_press &amp;&amp; !key_state ) {<br />key_state = debounce;<br />Timer1 = 5;<br />} else<br />if( key_state  ) {<br />if( key_press &amp;&amp; debounce==key_state &amp;&amp; !Timer1 ) {<br />key_state = go_rep;<br />Timer1=3;<br />last_key = key_mask;<br />} else<br />if( !key_press &amp;&amp; key_state&gt;debounce &amp;&amp; key_state&lt;rep ) {<br />if(push_proc) push_proc();/* KEY_UP */<br />key_state=idle;<br />last_key = 0;<br />} else<br />if( key_press &amp;&amp; go_rep==key_state &amp;&amp; !Timer1 ) {<br />if(!rep_time) rep_time=20;<br />if(!rep_wait) rep_wait=150;<br />key_state = wait_rep;<br />Timer1=rep_wait;<br />} else<br />if( key_press &amp;&amp; wait_rep==key_state &amp;&amp; !Timer1 ) {<br />key_state = rep;<br />} else<br />if( key_press &amp;&amp; rep==key_state &amp;&amp; !Timer1 ) {<br />Timer1 = rep_time;<br />if(rep_proc) rep_proc();/* KEY_REP */<br />}<br />}<br /><br />if( key_state&gt;=wait_rep &amp;&amp; !key_press ) {<br />key_state = idle;<br />last_key = 0;<br />}<br />}<br /><br />void kl1_press(void){<br />element_menu++;<br />lcd_cls();<br />s_pomiary= 50;<br /><br />}<br />void kl1_rep(void){<br /><br />}<br />void kl2_press(void){<br />s_pomiary = element_menu;<br />}<br /><br />void kl2_rep(void){<br /><br />}<br /><br />void test() {<br />if(!Timer3) {<br />Timer3 = 75;<br />PORTD ^= LED;<br />}<br /><br />}<br /><br />ISR(TIMER2_COMP_vect) {<br />uint16_t n;<br /><br />n = Timer1;<br />if(n)<br />Timer1 = --n;<br /><br />n = Timer2;<br />if(n)<br />Timer2 = --n;<br /><br />n = Timer3;<br />if(n)<br />Timer3 = --n;<br />}[/syntax]<br />Nie mam pomysłu jak to składnie zrobić  <img src="https://forum.atnel.pl/images/smilies/icon_neutral.gif" alt=":|" title="Średnio zadowolony" /> Jakieś sugestie?<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1862">dawidek034</a> — 12 cze 2014, o 00:12</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[dawidek034]]></name></author>
<updated>2014-06-11T19:33:13+01:00</updated>
<published>2014-06-11T19:33:13+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=84166#p84166</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=84166#p84166"/>
<title type="html"><![CDATA[Re: Kłopot z przerwaniami]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=84166#p84166"><![CDATA[
[syntax=c]#include &lt;avr/io.h&gt;<br />#include &lt;util/delay.h&gt;<br />#include &quot;LCD/lcd44780.h&quot;<br />#include &quot;1Wire/ds18x20.h&quot;<br />#include &lt;avr/interrupt.h&gt;<br /><br />#define KEY3 (1&lt;&lt;PC0)<br />#define KEY2 (1&lt;&lt;PC1)<br />#define LED (1&lt;&lt;PD7)<br />#define LED1 (1&lt;&lt;PD6)<br />volatile uint16_t Timer1, Timer2, Timer3;<br /><br /><br />void superDebounce(volatile uint8_t *KPIN,<br />uint8_t key_mask, uint16_t rep_time, uint16_t rep_wait,<br />void (*push_proc)(void), void (*rep_proc)(void) );<br />void kl1_press(void);<br />void kl1_rep(void);<br />void kl2_press(void);<br />void kl2_rep(void);<br />void show_menu();<br />void test();<br />uint8_t element_menu = 0;<br /><br />enum menu { mainMenu, mpomiar, mwartosci  };<br />enum menu s_menu ;<br /><br /><br />int main(void) {<br /><br />DDRD |= LED | LED1;<br />PORTD &amp;=~ LED | LED1;<br /><br />PORTC |= KEY3 | KEY2;<br />TCCR2  |= (1&lt;&lt;WGM21);<br />TCCR2  |= (1&lt;&lt;CS22)|(1&lt;&lt;CS21)|(1&lt;&lt;CS20);<br />OCR2  = 108;<br />TIMSK  = (1&lt;&lt;OCIE2);<br /><br />lcd_init();<br />sei();<br /><br />while(1) {<br />superDebounce(&amp;PINC, KEY3, 20, 500, kl1_press, kl1_rep );<br />superDebounce(&amp;PINC, KEY2, 80, 400, kl2_press, kl2_rep );<br /><br />show_menu();<br />if(element_menu &gt; 2)<br />element_menu = 0;<br />test(); // test czy przerwania sie zaklocaja<br />}<br />}<br /><br />void show_menu() {<br />switch(element_menu) {<br />case mainMenu:<br />lcd_locate(0,5);<br />lcd_str(&quot;MENU&quot;);<br />break;<br />case mpomiar:<br />lcd_locate(0,2);<br />lcd_str(&quot;Pomiar_temp&quot;);<br />break;<br />case mwartosci:<br />lcd_locate(0,4);<br />lcd_str(&quot;Wartosci&quot;);<br />if(!Timer2) {<br />Timer2 = 20;<br />PORTD ^= LED1;<br />}<br />break;<br />}<br /><br />}<br /><br /><br />void superDebounce(volatile uint8_t *KPIN,<br />uint8_t key_mask, uint16_t rep_time, uint16_t rep_wait,<br />void (*push_proc)(void), void (*rep_proc)(void) ) {<br /><br />enum KS {idle, debounce, go_rep, wait_rep, rep};<br /><br />static enum KS key_state;<br />static uint8_t last_key;<br />uint8_t key_press;<br /><br />// zabezpieczenie przed wykonywaniem tej samej funkcji dla<br />// dwóch klawiszy wciskanych jednocześnie (zawsze będzie<br />// wykonywana odpowiednia akcja dla tego, który został<br />// wciśnięty jako pierwszy<br />if( last_key &amp;&amp; last_key != key_mask ) return;<br /><br />key_press = !(*KPIN &amp; key_mask);<br /><br />if( key_press &amp;&amp; !key_state ) {<br />key_state = debounce;<br />Timer1 = 5;<br />} else<br />if( key_state  ) {<br />if( key_press &amp;&amp; debounce==key_state &amp;&amp; !Timer1 ) {<br />key_state = go_rep;<br />Timer1=3;<br />last_key = key_mask;<br />} else<br />if( !key_press &amp;&amp; key_state&gt;debounce &amp;&amp; key_state&lt;rep ) {<br />if(push_proc) push_proc();/* KEY_UP */<br />key_state=idle;<br />last_key = 0;<br />} else<br />if( key_press &amp;&amp; go_rep==key_state &amp;&amp; !Timer1 ) {<br />if(!rep_time) rep_time=20;<br />if(!rep_wait) rep_wait=150;<br />key_state = wait_rep;<br />Timer1=rep_wait;<br />} else<br />if( key_press &amp;&amp; wait_rep==key_state &amp;&amp; !Timer1 ) {<br />key_state = rep;<br />} else<br />if( key_press &amp;&amp; rep==key_state &amp;&amp; !Timer1 ) {<br />Timer1 = rep_time;<br />if(rep_proc) rep_proc();/* KEY_REP */<br />}<br />}<br /><br />if( key_state&gt;=wait_rep &amp;&amp; !key_press ) {<br />key_state = idle;<br />last_key = 0;<br />}<br />}<br /><br />void kl1_press(void){<br />lcd_cls();<br />element_menu++;<br /><br />}<br />void kl1_rep(void){<br /><br />}<br />void kl2_press(void){<br /><br />}<br />void kl2_rep(void){<br /><br />}<br /><br />void test() {<br />if(!Timer3) {<br />Timer3 = 75;<br />PORTD ^= LED;<br />}<br /><br />}<br /><br />ISR(TIMER2_COMP_vect) {<br />uint16_t n;<br /><br />n = Timer1;<br />if(n)<br />Timer1 = --n;<br /><br />n = Timer2;<br />if(n)<br />Timer2 = --n;<br /><br />n = Timer3;<br />if(n)<br />Timer3 = --n;<br />}[/syntax]<br /><br />Wprowadziłem typ wyliczeniowy jak zaproponowałeś i działa tak jak chciałem. Miałeś racje źle się do tego zabierałem. Dziękuje za pomoc. Teraz mam pytanie jak powiązać tą zmianę stanów z jakimś prostym menu. Czyli jak ja to widzę przykładowo:<br />1.poruszam się klawiszem pod opcjach menu(pomiar_temp; godzina; wilgotność)<br />2.gdy jestem na konkretnej pozycji z menu, drugim klawiszem wybieram daną opcje i przechodzę jak powyżej do pracy ciągłej pomiaru temperatury<br /><br />Trochę próbowałem jakoś powiązać dwie konstrukcje switch() ze sobą, ale zbytni mi to nie wychodzi. Jak inaczej się do tego zabrać? Powyższy kod różni się od pierwotnego, lecz idea pozostaje ta sama(zastosowałem inne funkcje)<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1862">dawidek034</a> — 11 cze 2014, o 19:33</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[dawidek034]]></name></author>
<updated>2014-06-10T20:01:20+01:00</updated>
<published>2014-06-10T20:01:20+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=83992#p83992</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=83992#p83992"/>
<title type="html"><![CDATA[Kłopot z przerwaniami]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=7384&amp;p=83992#p83992"><![CDATA[
Problem polega na tym iż chciałbym za pomocą klawisza włączyć daną funkcję tak aby tak działała w sposób ciągły. Przykładowo pomiar temperatury: naciskając KEY3 chciałbym zobaczyć na lcd, wynik pomiaru, ale nie pojedynczego tylko trwającego aż do odwołania przykładowo innym przyciskiem. Następnie takie rozwiązanie chciałbym zaimplementować do jakiegoś prostego menu. Siedzę już nad tym dość sporo ale najwyraźniej czegoś nie rozumiem.<br />Bardzo proszę o wskazówki i porady dotyczącego tego problemu jak kodu. Co warto w nim zmienić.<br />[syntax=c]#include &lt;avr/io.h&gt;<br />#include &lt;util/delay.h&gt;<br />#include &quot;LCD/lcd44780.h&quot;<br />#include &quot;1Wire/ds18x20.h&quot;<br />#include &lt;avr/interrupt.h&gt;<br /><br /><br />#define KEY1 (1&lt;&lt;PC0)<br />#define KEY2 (1&lt;&lt;PC1)<br />#define KEY3 (1&lt;&lt;PC2)<br /><br />typedef struct {<br /><br />volatile uint8_t *KPIN;<br />uint8_t wait_time_s;<br />uint8_t key_mask;<br />void(*kfun1)(void);<br />void(*kfun2)(void);<br />uint8_t klock;<br />uint8_t flag;<br /><br />}TBUTTON;<br /><br />volatile uint16_t TIMER1, TIMER2, TIMER3;<br />volatile uint8_t sekundy, ms10_cnt, s1_flag;<br />uint8_t czujniki_cnt;<br />uint8_t subzero, cel, cel_fract_bits;<br /><br />void pomiar_temp();<br />void temp_value(void);<br />void key_press(TBUTTON *btn);<br />void timer_conf(void);<br />void button_value();<br />void display_temp(uint8_t x);<br />void button_value1();<br />void moj_klawisz(void);<br /><br />//Definicja klawisza<br />TBUTTON button;<br />TBUTTON button1;<br /><br />int main(void) {<br /><br /><br />PORTC |= (KEY1) | (KEY2) | (KEY3);<br /><br />timer_conf();<br />button_value();<br />button_value1();<br />lcd_init();<br />sei();<br /><br /><br />while(1) {<br /><br />key_press(&amp;button);<br />key_press(&amp;button1);<br /><br /><br /><br />} //end while<br /><br />}<br />void key_press(TBUTTON * btn) {<br />register uint16_t key_press = (*btn -&gt; KPIN &amp; btn -&gt; key_mask);<br />if( !btn-&gt;klock &amp;&amp; !key_press ) {<br />  btn-&gt;klock=1;<br /><br />  // reakcja na PRESS krótkie wcinięcie klawisza<br />  if(btn-&gt;kfun1) btn-&gt;kfun1();<br />  btn-&gt;flag=1;<br />  TIMER1 = (btn-&gt;wait_time_s*1000)/10;<br /><br /> }<br /> else if( btn-&gt;klock &amp;&amp; key_press ) {<br />  (btn-&gt;klock)++;<br />  if( !btn-&gt;klock ) {<br />   TIMER1 = 0;<br />   btn-&gt;flag = 0;<br />  }<br /> } else if( btn-&gt;flag &amp;&amp; !TIMER1 ) {<br />  // reakcja na dłuższe wcinięcie klawisza<br />  if(btn-&gt;kfun2) btn-&gt;kfun2();<br />  btn-&gt;flag=0;<br /> }<br />}<br /><br />void temp_value(void) {<br /><br />if(DS18X20_OK == DS18X20_read_meas(gSensorIDs&#91;0&#93;, &amp;subzero, &amp;cel, &amp;cel_fract_bits)) {<br />lcd_locate(1,0);<br />lcd_str(&quot; &quot;);<br />display_temp(1);<br />TIMER2 = 100;<br />}<br /><br />else {<br />lcd_locate(1,0);<br />lcd_str(&quot;error&quot;);<br />}<br />}<br />void pomiar_temp(void) {<br />czujniki_cnt = search_sensors();<br />DS18X20_start_meas( DS18X20_POWER_EXTERN, NULL );<br /><br />}<br /><br />void display_temp(uint8_t x) {<br />x = 1;<br />lcd_locate(1,x);<br />if(subzero) lcd_str(&quot;-&quot;);/* jeśli subzero==1 wyświetla znak minus (temp. ujemna) */<br />else lcd_str(&quot; &quot;);/* jeśli subzero==0 wyświetl spację zamiast znaku minus (temp. dodatnia) */<br />lcd_int(cel);/* wyświetl dziesiętne części temperatury  */<br />lcd_str(&quot;.&quot;);/* wyświetl kropkę */<br />lcd_int(cel_fract_bits); /* wyświetl dziesiętne części stopnia */<br /><br />//lcd_str(&quot; \x80&quot;&quot;C&quot;); /* wyświetl znak jednostek (C - stopnie Celsiusza) */<br />}<br /><br /><br />void timer_conf(void) {<br />TCCR2  |= (1&lt;&lt;WGM21);<br />TCCR2  |= (1&lt;&lt;CS22)|(1&lt;&lt;CS21)|(1&lt;&lt;CS20);<br />OCR2  = 108;<br />TIMSK  = (1&lt;&lt;OCIE2);<br />}<br /><br />void button_value() {<br />button.KPIN = &amp;PINC;<br />button.key_mask = KEY1;<br />button.wait_time_s = 2;<br />button.kfun1 = temp_value ;<br />button.kfun2 = NULL;<br />}<br />void button_value1() {<br />button1.KPIN = &amp;PINC;<br />button1.key_mask = KEY2;<br />button1.wait_time_s = 2;<br />button1.kfun1 = NULL;<br />button1.kfun2 = NULL;<br />}<br /><br />/**Przerwania_TIMER2**/<br />ISR(TIMER2_COMP_vect) {<br /><br />uint16_t n;<br /><br />n = TIMER1;<br />if(n)<br />TIMER1 = --n; //100Hz<br /><br />n = TIMER2;<br />if(n)<br />TIMER2 = --n; //100Hz<br /><br />n = TIMER3;<br />if(n)<br />TIMER3 = --n;//100Hz<br /><br />}[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1862">dawidek034</a> — 10 cze 2014, o 20:01</p><hr />
]]></content>
</entry>
</feed>