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

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2016-01-13T18:33:19+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=4&amp;t=14118&amp;mode</id>
<entry>
<author><name><![CDATA[avrfun]]></name></author>
<updated>2016-01-13T17:58:29+01:00</updated>
<published>2016-01-13T17:58:29+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150496#p150496</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150496#p150496"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150496#p150496"><![CDATA[
<div class="quotetitle">rskup napisał(a):</div><div class="quotecontent"><br />Dlatego nie dziwi mnie że Twoje 10 minut jest raz bliższe a raz dalsze tego spodziewanego okresu.<br /></div><br />Witam!<br />Poradziłem sobie z problemem rozjeżdżania się timera programowego odliczającego czas do następnej synchronizacji poprzez... rezygnację z niego. Wykorzystałem sekundowe zmiany flagi sprzętowej przerwania INT0 - z czasem synchronizacji podawanym jako argument RTC_EVENT(). Teraz synchronizacja jest precyzyjna w dowolnym okresie czasu. Zauważyłem jednak ze zgrozą <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /> , że kropka sekundowa mruga bardzo nieregularnie w rytm... timera programowego (cy2 bez kropki / cy2 z kropką). Nie wiem jak włączyć mruganie cy2 w rytm &quot;INT0&quot;, a może rozwiązać to zupełnie inaczej. Proszę o rady.<br />Rozwiązanie w chwili obecnej wygląda tak:<br />[syntax=c]/* &quot;mruganie&quot; kropki minutowej w rytm pracy Timer1 */<br />if(!Timer1) cy2 = cy2_temp + 10;[/syntax]<br />[syntax=c]cy1 = (dt-&gt;hh) / 10;<br />if (cy1 == 0) cy1 = 22;<br />cy2 = (dt-&gt;hh) % 10;<br />cy2_temp = (dt-&gt;hh) % 10;<br />cy2 = cy2_temp;<br />cy3 = (dt-&gt;mm) / 10;<br />cy4 = (dt-&gt;mm) % 10;[/syntax]<br />Pozdrawiam<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=9310">avrfun</a> — 13 sty 2016, o 17:58</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[rskup]]></name></author>
<updated>2016-01-12T20:01:43+01:00</updated>
<published>2016-01-12T20:01:43+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150352#p150352</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150352#p150352"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150352#p150352"><![CDATA[
<div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />Rozumiem, że timer programowy jest &quot;zatrzymywany&quot; poprzez ustawienie wartości w pętli głównej<br /></div><br />Timer programowy jest zatrzymywany w procedurze obsługi przerwania timera sprzętowego. Bo zmienna jest zmieniana tylko w przypadku wartości różnej od zera a w momencie wyzerowania już nie:<br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />[syntax=c]if (n) Timer3 = --n;[/syntax]<br /></div><br />Załadowanie ponownej wartości różnej od zera następuje w funkcjach / eventach wywoływanych w pętli głównej. I tak dla Timer3 następuje to w evencie GetNtpTime_EVENT() i to samym jego końcu. Więc masz od momentu wyzerowania wartości Timer3 do czasu jego przeładowania nową wartością zatrzymany timer programowy. A czas przeładowania jest zależny jak szybko wejdziesz w GetNtpTime_EVENT() i jakie elementy w nim będą wykonane.<br /><br />-- <br />Pozdrawiam,<br />Robert<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3427">rskup</a> — 12 sty 2016, o 20:01</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[avrfun]]></name></author>
<updated>2016-01-12T07:42:02+01:00</updated>
<published>2016-01-12T07:42:02+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150309#p150309</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150309#p150309"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150309#p150309"><![CDATA[
<div class="quotetitle">rskup napisał(a):</div><div class="quotecontent"><br />Dlatego nie dziwi mnie że Twoje 10 minut jest raz bliższe a raz dalsze tego spodziewanego okresu.<br /></div><br />Witam.<br />Dziękuję za wyjaśnienia. Rozumiem, że timer programowy jest &quot;zatrzymywany&quot; poprzez ustawienie wartości w pętli głównej na różnym etapie swojego odliczania co zaburza cykl jego pracy i raz ma bliżej, a raz dalej do 0. Czy znasz sposób rozwiązania tego problemu?<br />Pozdrawiam<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=9310">avrfun</a> — 12 sty 2016, o 07:42</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[rskup]]></name></author>
<updated>2016-01-13T18:33:19+01:00</updated>
<published>2016-01-12T02:25:31+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150308#p150308</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150308#p150308"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150308#p150308"><![CDATA[
Co zduplikował się poprzedni post  <img src="https://forum.atnel.pl/images/smilies/icon_e_sad.gif" alt=":(" title="Smutny" /><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3427">rskup</a> — 12 sty 2016, o 02:25</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[rskup]]></name></author>
<updated>2016-01-12T02:25:29+01:00</updated>
<published>2016-01-12T02:25:29+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150307#p150307</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150307#p150307"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150307#p150307"><![CDATA[
Masz w procedurze obsługi przerwania timera (TIMER2_COMP) zatrzymywanie liczenia dla zmiennych timera programowego Timer1/3/5/_SuperDebounce. Liczenie ponownie uruchamiane jest dopiero w elementach pętli głównej w momencie obsłużenia danego zdarzenia wykonywanego przy wyzerowaniu zmiennej Timer1/3/5/_SuperDebounce. Jest to poprawne, ale czas liczony między kolejnymi zerowaniami danej zmiennej to nie tylko czas wyznaczony przez przerwania przepełnienia timera ale także czas jaki mija na dojście w pętli głównej do momentu ponownego uruchomienia zliczania danego timera programowego (wpisanie do niego wartości różnej od zera). A ten drugi czas zależy od czasu wykonania pozostałych funkcji / eventów w pętli głównej a także od momentu w którym akurat trafi się wyzerowanie zmiennej timera programowego (jak stanie się to tuż przed daną procedurą, to następuje szybko a jak zaraz po niej, to zajmie to czas potrzebny do obsłużenia wszystkich funkcji).<br />Zwróć też jeszcze uwagę, że timer dla NTP uruchamiasz ponownie (* tmr_100ms = 16;) na koniec procedury. Czyli musi się wykonać wszystko co masz tam w danym momencie zrobić i dopiero zaczynasz liczyć. Czyli raz dzieje się to szybciej a raz wolniej.<br /><br />Dlatego nie dziwi mnie że Twoje 10 minut jest raz bliższe a raz dalsze tego spodziewanego okresu.<br /><br />-- <br />Pozdrawiam,<br />Robert<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3427">rskup</a> — 12 sty 2016, o 02:25</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[avrfun]]></name></author>
<updated>2016-01-09T16:42:04+01:00</updated>
<published>2016-01-09T16:42:04+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150075#p150075</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150075#p150075"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150075#p150075"><![CDATA[
<div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />A gdzie masz zliczanie timera programowego?<br />Daj więcej kodu. Szczególnie tego związanego z timerami.<br /></div><br />Organizacja timerów programowych:<br />[syntax=c]void SoftTimer_init(void){<br />// ustawienia timera sprzętowego wybranego jako podstawa czasu timerów programowych dla &quot;Dawcy czasu&quot; (100Hz)<br />// wykorzystany również do multipleksowania 7-segmentowych wyświetlaczy LED (200Hz)<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  = 108;                               // rozdzielczosć: 10ms (100Hz)<br />OCR2  = 48;                               // rozdzielczosć: 5ms (200Hz)<br />TIMSK  |= (1&lt;&lt;OCIE2);                      // odblokowanie przerwania CompareMatch<br />}[/syntax]<br />[syntax=c]ISR(TIMER2_COMP_vect){<br /><br />static uint16_t n;<br />static uint8_t anoda;<br />if(anoda == 0) disp_send(~(pgm_read_byte(&amp;Display&#91;0&#93;)), (pgm_read_byte(&amp;Cyfra&#91;cy4&#93;)));<br />else if(anoda == 1) disp_send(~(pgm_read_byte(&amp;Display&#91;1&#93;)), (pgm_read_byte(&amp;Cyfra&#91;cy3&#93;)));<br />else if(anoda == 2) disp_send(~(pgm_read_byte(&amp;Display&#91;2&#93;)), (pgm_read_byte(&amp;Cyfra&#91;cy2&#93;)));<br />else if(anoda == 3) disp_send(~(pgm_read_byte(&amp;Display&#91;3&#93;)), (pgm_read_byte(&amp;Cyfra&#91;cy1&#93;)));<br />anoda++;<br />if(anoda &gt; 3) anoda = 0;<br /><br />n = Timer1;<br />if(n) Timer1 = --n;<br />n = Timer3;<br />if (n) Timer3 = --n;<br />n = Timer5;<br />if (n) Timer5 = --n;<br />n = Timer_SuperDebounce;<br />if (n) Timer_SuperDebounce = --n;<br /><br />if(200 == Timer_linijka_off) y = 1;<br />Timer_linijka_off++;<br />}[/syntax]<br />main.c<br />[syntax=c]int main(void){<br /><br />DDRC |= (1&lt;&lt;PC5)|(1&lt;&lt;PC6)|(1&lt;&lt;PC7);<br />PORTC |= (1&lt;&lt;PC5)|(1&lt;&lt;PC6)|(1&lt;&lt;PC7);<br /><br />PORTD |= KL1;<br />PORTC |= KL2;<br /><br />SoftTimer_init();<br />InitSpi();<br />SendSpi(0);<br />USART_Init(__UBRR);<br />register_uart_str_rx_event_callback(parse_rs232);<br />init_rtc();<br />register_rtc_event_callback(pokazuj_date_czas);<br />ir_init();<br />register_ir_event_callback(ir_decode);<br />lcd_init();<br />BMP180_init();<br />ws_cls(linijka1, 0);<br /><br />Timer_linijka_off = 201;<br /><br />/* sprawdzamy ile czujników DS18xxx widocznych jest na magistrali */<br />czujniki_cnt = search_sensors();<br />DS18X20_start_meas( DS18X20_POWER_EXTERN, NULL );<br />/* czekamy 750ms na dokonanie konwersji przez podłączone czujniki */<br />_delay_ms(1500);<br /><br />DHT22_ShowOnLCD();<br />BMP180_ShowOnLCD();<br /><br />lcd_defchar_P(0x80,znak_stopien); /* &quot;rejestracja&quot; własnego znaku */<br /><br />tcl = 0;<br />first_sync = 1;<br /><br />sei();<br /><br />set_rtc_datetime(&amp;datetime, 0, 0, 0, 0, 0, 0);<br /><br />while(1){<br /><br />UART_RX_STR_EVENT(uart_buf);<br />RTC_EVENT();<br />GetNtpTime_EVENT(&amp;Timer3, 0, 2, 0, NULL);<br />IR_EVENT();<br /><br />SuperDebounce(&amp;k1, &amp;PIND, KL1, 20, 500, parametr_p, NULL );<br />SuperDebounce(&amp;k2, &amp;PINC, KL2, 20, 500, parametr_to, NULL );<br /><br />/* &quot;mruganie&quot; kropki minutowej w rytm pracy Timer1 */<br />if(!Timer1) cy2 = cy2_temp + 10;<br /><br />/* Timer_linijka_off zlicza do 200 i wystawia flagę y=1, co gasi linijkę i diodę i resetuje flagę y */<br />if(y == 1){<br />ws_line(linijka1, 0, 26, 0x00);<br />cli();<br />ws281x_asm_send( linijka1, WS_LED_CNT, WS_PIN);<br />sei();<br />PORTC |= (1&lt;&lt;PC7);<br />y=0;<br />}<br />}<br />}[/syntax]<br />while(1)<br />[syntax=c]while(1){<br /><br />UART_RX_STR_EVENT(uart_buf);<br />RTC_EVENT();<br />GetNtpTime_EVENT(&amp;Timer3, 0, 2, 0, NULL);<br />IR_EVENT();<br /><br />SuperDebounce(&amp;k1, &amp;PIND, KL1, 20, 500, parametr_p, NULL );<br />SuperDebounce(&amp;k2, &amp;PINC, KL2, 20, 500, parametr_to, NULL );<br /><br />/* &quot;mruganie&quot; kropki minutowej w rytm pracy Timer1 */<br />if(!Timer1) cy2 = cy2_temp + 10;<br /><br />/* Timer_linijka_off zlicza do 200 i wystawia flagę y=1, co gasi linijkę i diodę i resetuje flagę y */<br />if(y == 1){<br />ws_line(linijka1, 0, 26, 0x00);<br />cli();<br />ws281x_asm_send( linijka1, WS_LED_CNT, WS_PIN);<br />sei();<br />PORTC |= (1&lt;&lt;PC7);<br />y=0;<br />}<br />}[/syntax]<br />GetNtpTime_EVENT()<br />[syntax=c]void GetNtpTime_EVENT (volatile uint16_t * tmr_100ms, uint8_t sr, uint8_t mr, uint8_t gr, void(*timer_100ms)(void)){<br /><br />/* Timer3 z projektu GPS liczy trzy razy szybciej stąd (mr*20ul*10ul) zamiast (mr*60ul*10ul) i.t.d. */<br />uint32_t co_ile_czasu = (sr*10ul) + (mr*60ul*10ul) + (gr*60ul*60ul*10ul);<br /><br />if(first_sync){co_ile_czasu = (1*20ul*10ul);}<br />czas = co_ile_czasu;<br /><br />if(!*tmr_100ms){<br /><br />PORTC ^= (1&lt;&lt;PC5);<br /><br />switch (ms100_tick){<br /><br />case 0:  uart_puts(&quot;+&quot;); break;<br />case 1:  uart_puts(&quot;+&quot;); break;<br />case 2:  uart_puts(&quot;+&quot;); break;<br />case 3:  uart_puts(&quot;a&quot;); break;<br />case 5: {actual_at_cmd = _at_gmt;<br />uart_puts(&quot;AT+GMT=&quot;);<br />uart_putint(datetime.dst, 10);<br />//dst=1 -&gt; czas zimowy, dst=2 -&gt; czas letni, ustaw w pliku mk_pcf8583.h !!!<br />uart_puts(&quot;\r&quot;); uart_puts(&quot;            &quot;); uart_puts(&quot;\r&quot;);<br />break;<br />}<br />case 10: uart_puts(&quot;AT+ENTM\r&quot;);uart_puts(&quot;            &quot;); uart_puts(&quot;\r\n&quot;); break; // Enter Transparet Mode<br />case 11: {ws_line(linijka1, 0, 26, 0x0F0000);<br />cli();<br />ws281x_asm_send( linijka1, WS_LED_CNT, WS_PIN);<br />PORTC &amp;= ~(1&lt;&lt;PC7);<br />sei();<br />cy1=21; cy2=21; cy3=21; cy4=21;<br />Timer1=200; // czas wydłużony ze 100 do 200ms, aby nie migęła cy2 z kropką tylko pozostał &quot;-&quot;<br />break;<br />}<br />case 15: {ws_line(linijka1, 0, 26, 0x00);<br />cli();<br />ws281x_asm_send( linijka1, WS_LED_CNT, WS_PIN);<br />sei();<br />PORTC |= (1&lt;&lt;PC7);<br />break;<br />}<br />}<br />ms100_tick++;<br /><br />/* dane testowe do wyświetlenia na LCD */<br />lcd_locate(0,4);<br />if (ms100_tick &lt; 1000) lcd_str(&quot;_&quot;);<br />if(ms100_tick &lt; 100) lcd_str(&quot;_&quot;);<br />if(ms100_tick &lt; 10) lcd_str(&quot;_&quot;);<br />lcd_int(ms100_tick);<br /><br />if(ms100_tick &gt; co_ile_czasu){<br />ms100_tick = 0; // odpytywanie czasu co 10s<br />}<br /><br />if(datetime.force_ntp) datetime.force_ntp--;<br />if(1 == datetime.force_ntp) ms100_tick = 0;<br /><br />if(timer_100ms) timer_100ms();<br />* tmr_100ms = 16;<br />}<br />}[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=9310">avrfun</a> — 9 sty 2016, o 16:42</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[rskup]]></name></author>
<updated>2016-01-09T16:17:16+01:00</updated>
<published>2016-01-09T16:17:16+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150069#p150069</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150069#p150069"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150069#p150069"><![CDATA[
A gdzie masz zliczanie timera programowego?<br />Daj więcej kodu. Szczególnie tego związanego z timerami.<br /><br />-- <br />Pozdrawiam,<br />Robert<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3427">rskup</a> — 9 sty 2016, o 16:17</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[avrfun]]></name></author>
<updated>2016-01-09T15:52:14+01:00</updated>
<published>2016-01-09T15:52:14+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150067#p150067</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150067#p150067"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150067#p150067"><![CDATA[
<div class="quotetitle">rskup napisał(a):</div><div class="quotecontent"><br />Sam musisz wybrać jakie są wymagania Twojego rozwiązania i co będzie najlepsze.<br /></div><div class="quotetitle">rskup napisał(a):</div><div class="quotecontent"><br />Choć może miganie diodą lepiej robić na początku w pętli głównej, bo jej nieregularność od razu mówi, że coś nie do końca tak robimy.<br /></div><br /><br />Dziękuję za wyjaśnienia.<br />Powodem dla którego założyłem ten wątek jest rozjeżdżający się timer programowy w dawcy czasu wykorzystywany do  odmierzania czasu do synchronizacji wg polecenia:<br />[syntax=c]GetNtpTime_EVENT(&amp;Timer3, 0, 2, 0, NULL);[/syntax] Na debuggerze jednodiodowym i liczniku na LCD obserwuję jego zacinanie się co przekłada się na dłuższe i krótsze czasy do następnej synchronizacji przy stałym zadanym odstępie np. 10 minut. Postanowiłem więc wykonać &quot;ciało&quot; GetNtpTime_EVENT jako osobny program z użyciem timera programowego i flag. Obie wersje działają bardzo dobrze i synchronizacja jest dokładna. Umieszczenie tego w moim kombajnie skutkuje dławieniem się synchronizacji. Tak wygląda pętla while(!):<br />[syntax=c]while(1){<br /><br />UART_RX_STR_EVENT(uart_buf);<br />RTC_EVENT();<br />GetNtpTime_EVENT(&amp;Timer3, 0, 2, 0, NULL);<br />IR_EVENT();<br /><br />SuperDebounce(&amp;k1, &amp;PIND, KL1, 20, 500, parametr_p, NULL );<br />SuperDebounce(&amp;k2, &amp;PINC, KL2, 20, 500, parametr_to, NULL );<br /><br />/* &quot;mruganie&quot; kropki minutowej w rytm pracy Timer1 */<br />if(!Timer1) cy2 = cy2_temp + 10;<br /><br />/* Timer_linijka_off zlicza do 200 i wystawia flagę y=1, co gasi linijkę i diodę i resetuje flagę y */<br />if(y == 1){<br />ws_line(linijka1, 0, 26, 0x00);<br />cli();<br />ws281x_asm_send( linijka1, WS_LED_CNT, WS_PIN);<br />sei();<br />PORTC |= (1&lt;&lt;PC7);<br />y=0;<br />}<br />}[/syntax]<br />Włączałem i wyłączałem poszczególne instrukcje w różnej kombinacji, ale nieregularność pozostaje. Nie chodzi mi o super dokładność, bo czy synchronizacja nastąpi po 10 czy 15 minutach nie ma znaczenia dla sprawy, ale chodzi o wymknięcie się programu spod mojej kontroli, a to już jest trudne do przyjęcia. Czytając Twoje wyjaśnienia pomyślałem, że można wymusić na sztywno synchronizację po zadanym czasie za pomocą flagi timera sprzętowego licząc się nawet ze stratami. Wyobrażam to sobie tak. Zadany czas do synchronizacji ustawiam np. na 10 minut. Chimeryczny timer programowy generując kolejne tyknięcia co 70, 100, 140, 60ms sprawia, że 10 minut uzbiera się w różnym czasie. Flaga timera sprzętowego zostanie wystawiona dokładnie po 10 minutach i wymusi synchronizację. Powtarzalność 99.99%. Czy takie podejście jest poprawne merytorycznie, a jeżeli tak to jak to zrealizować?<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=9310">avrfun</a> — 9 sty 2016, o 15:52</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[rskup]]></name></author>
<updated>2016-01-09T13:55:28+01:00</updated>
<published>2016-01-09T13:55:28+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150047#p150047</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150047#p150047"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150047#p150047"><![CDATA[
<div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />To rozjaśnia moje spojrzenie na zagadnienie flag przerwań sprzętowych. Sądziłem, że sprzętowo będzie dokładniej, ale teraz rozumiem, że kluczem do tej dokładności jest długość pętli głównej.<br /></div><br />Dokładnie liczy timer sprzętowy. W pętla głównej umieszczasz funkcje wymagające dłuższego czasu ich wykonania, ale timerowi sprzętowemu to nie przeszkadza, bo ma przerwania, które się wykonują wstrzymując działanie pętli głównej. Lecz jeżeli chcesz sam sprawdzać flagę znacznika przepełnienia zamiast generować przerwanie, to nie musisz to robić natychmiast po jej ustawieniu, ale musi to być szybciej niż jedno tyknięcie timera sprzętowego, bo inaczej będziesz gubił &quot;tyknięcia&quot;.<br />Podobna zasada dotyczy timera programowego, tylko tutaj zakładasz jego długość x razy więcej niż sprzętowego. Dlatego aby zgubić jego &quot;tyknięcie&quot; to musisz w tym wypadku działać w pętli głównej x razy wolniej niż jakbyś sprawdzał flagę.<br />Dodatkowo timer programowy możesz używać w dwóch trybach. Pierwszy to wystawiający flagę a liczący od razu od początku. Więc jak nie zgubisz, jak wcześniej wpisałem jego tyknięcia, to masz dokładne odstępy. W drugiej wersji nie zliczasz kolejnych tyknięć dopóki nie zaczniesz obsługiwać tego timera. Przez co będziesz miał zmienną długość czasu timera (zależnie od długości działania pętli głównej), ale gwarancję że nie będą zgubione żadne tyknięcia.<br />Sam musisz wybrać jakie są wymagania Twojego rozwiązania i co będzie najlepsze.<br /><br />Teoretycznie także możesz liczyć i obsługiwać timer programowy na przerwaniu. Tylko funkcje wykonywane na nim muszą to być proste - na przykład miganie diodą.<br />Choć może miganie diodą lepiej robić na początku w pętli głównej, bo jej nieregularność od razu mówi, że coś nie do końca tak robimy.<br /><br />-- <br />Pozdrawiam,<br />Robert<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3427">rskup</a> — 9 sty 2016, o 13:55</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[avrfun]]></name></author>
<updated>2016-01-09T10:10:35+01:00</updated>
<published>2016-01-09T10:10:35+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150032#p150032</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150032#p150032"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150032#p150032"><![CDATA[
Witam.<br /><div class="quotetitle">rskup napisał(a):</div><div class="quotecontent"><br />Wcześniej podawałeś kod:<br />Cytuj:<br />Składnia: [ Pobierz ] [ Ukryj ]<br />język c<br />if(!Timer1) Timer1 = 1;<br />GeSHi<br />choć teraz już piszesz:<br />Cytuj:<br />Tak zrobiłem: Timer1=10 jako pierwsza instrukcja<br /></div><br />Po przemyśleniu i Twoich poradach o dwukrotnym sprawdzaniu tego samego warunku it(!Timer1) i &quot;rozdzielczości&quot;, sprawdzam go tylko raz, a Timer ustawiam na 10, zamiast na 1.<br /><br /><div class="quotetitle">rskup napisał(a):</div><div class="quotecontent"><br />Aby mieć sprawdzanie 10 tyknięć to musisz i tak mieć zmienną typu Timer1, która będzie je zliczać. Proponowana przez Ciebie obsługa flag, to po prostu realizacja timera programowego w całości w pętli głównej. Ale raczej tak nie powinno się robić. Aby mieć dokładny timer programowy, to zliczanie tyknięć TIMER0 powinny być robione na przerwaniach. Gdybyś to robił w pętli głównej, to musiałbyś mieć gwarancję, że najdłuższy czas wykonania pętli głównej jest krótszy od tyknięcie TIMER0, bo inaczej możesz zgubić jakieś tyknięcie. Jak robisz to na przerwaniu, to pętla główna powinna być jedynie krótsza niż wartość timera programowego (u ciebie 10 tyknięć TIMER0).<br /></div><br />To rozjaśnia moje spojrzenie na zagadnienie flag przerwań sprzętowych. Sądziłem, że sprzętowo będzie dokładniej, ale teraz rozumiem, że  kluczem do tej dokładności jest długość pętli głównej.<br /><br />Bardzo dziękuję<br />Pozdrawiam<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=9310">avrfun</a> — 9 sty 2016, o 10:10</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[rskup]]></name></author>
<updated>2016-01-09T00:52:18+01:00</updated>
<published>2016-01-09T00:52:18+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150028#p150028</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150028#p150028"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150028#p150028"><![CDATA[
<div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />Zliczam po 10 impulsów (10x10ms)<br /></div>Wcześniej podawałeś kod:<div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />[syntax=c]if(!Timer1) Timer1 = 1;[/syntax]<br /></div>choć teraz już piszesz:<div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />Tak zrobiłem: Timer1=10 jako pierwsza instrukcja<br /></div><br /><br /><br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />należy napisać coś w rodzaju: if(flaga sprzętowa){instrukcja}.<br /></div><br />Tak. Sprawdzasz flagę. Jak jest ustawiona, to ją od razu kasujesz (uwaga, kasuje się przez wpisanie 1) i zmniejszasz Timer1. Jak Timer1 = 0, to go ustawiasz na wartość startową (10) i wykonujesz operacje.<br />Nie napisałeś jaki masz procesor. Ale dla ATmega32 jest to:<br /><a href="https://obrazkiforum.atnel.pl/3427/484b391b804c4a8ab279fd99acd12518.png"  class="postlink"><img src="https://obrazkiforum.atnel.pl/thumb/3427/484b391b804c4a8ab279fd99acd12518.png" alt="Obrazek" /></a><br /><br /><br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />Jak jednak zliczać 10 takich flag na tyknięcie (100ms), czyli jak zastąpić warunek Timer1=10?<br /></div>Aby mieć sprawdzanie 10 tyknięć to musisz i tak mieć zmienną typu Timer1, która będzie je zliczać. Proponowana przez Ciebie obsługa flag, to po prostu realizacja timera programowego w całości w pętli głównej. Ale raczej tak nie powinno się robić. Aby mieć dokładny timer programowy, to zliczanie tyknięć TIMER0 powinny być robione na przerwaniach. Gdybyś to robił w pętli głównej, to musiałbyś mieć gwarancję, że najdłuższy czas wykonania pętli głównej jest krótszy od tyknięcie TIMER0, bo inaczej możesz zgubić jakieś tyknięcie. Jak robisz to na przerwaniu, to pętla główna powinna być jedynie krótsza niż wartość timera programowego (u ciebie 10 tyknięć TIMER0).<br /><br />-- <br />Pozdrawiam,<br />Robert<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3427">rskup</a> — 9 sty 2016, o 00:52</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[avrfun]]></name></author>
<updated>2016-01-08T22:38:51+01:00</updated>
<published>2016-01-08T22:38:51+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150018#p150018</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150018#p150018"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=150018#p150018"><![CDATA[
Bardzo dziękuję za porady. Program działa jak należy i &quot;równo&quot; w takt 100ms  <img src="https://forum.atnel.pl/images/smilies/icon_e_biggrin.gif" alt=":D" title="Bardzo szczęśliwy" /> <br /><div class="quotetitle">rskup napisał(a):</div><div class="quotecontent"><br />jako pierwszą instrukcję w warunku (tym pierwszym, bo i tak sprawdzasz to samo dwa razy).<br />Jakiej prędkości rs232 używasz?<br /></div><br />Tak zrobiłem: Timer1=10 jako pierwsza instrukcja<br />RS232: 115200<br /><div class="quotetitle">rskup napisał(a):</div><div class="quotecontent"><br />Dodatko<br />wo nie ma sensu działania ze zliczaniem 1 impulsu bo dokładność masz jednego impulsu ;( Ustawiając Timer1 = 1 nie wiesz na jakim etapie zliczania jest licznik w TIMER0.<br /></div><br />Zliczam po 10 impulsów (10x10ms)<br /><div class="quotetitle">rskup napisał(a):</div><div class="quotecontent"><br />Aby sprawdzić czy nastąpiło przepełnienie to nie włączasz przerwania TIMER0_COMP, tylko sprawdzasz flagę w rejestrze. Masz to wszystko podane w datasheetcie do procesora.<br /></div><br />Rozumiem, że należy napisać coś w rodzaju: if(flaga sprzętowa){instrukcja}. Jak jednak zliczać 10 takich flag na tyknięcie (100ms), czyli jak zastąpić warunek Timer1=10?<br /><div class="quotetitle">kicajek napisał(a):</div><div class="quotecontent"><br />A może tak na żywca; &quot;u mnie&quot; takt to wyliczone 100ms.<br /></div><br />Działa dobrze. Rozumiem, że zliczasz 5 impulsów po 20ms na takt?<br /><br />Pozdrawiam<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=9310">avrfun</a> — 8 sty 2016, o 22:38</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[kicajek]]></name></author>
<updated>2016-01-08T19:35:07+01:00</updated>
<published>2016-01-08T19:35:07+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149994#p149994</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149994#p149994"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149994#p149994"><![CDATA[
Witam<br />A może tak na żywca; &quot;u mnie&quot; takt to wyliczone 100ms.<br />Nie wiem czy zadziała; tak bym próbował:<br />[syntax=c]ISR(...){<br />static uint16_t takt;<br /><br />     if (takt&gt;5){<br /> tykniecia = takt - 6<br /> flaga =1;<br />     }<br /> takt++;<br /> if (takt &gt; ileś_tam) takt =0;<br />}[/syntax]<br />a na &quot;górze&quot;<br />[syntax=c]if(flaga){<br />flaga =0;<br />// - Twoje case<br />}[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=826">kicajek</a> — 8 sty 2016, o 19:35</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[rskup]]></name></author>
<updated>2016-01-08T19:22:12+01:00</updated>
<published>2016-01-08T19:22:12+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149991#p149991</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149991#p149991"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149991#p149991"><![CDATA[
Czy przypadkiem funkcja puts() nie jest blokująca?<br />Daj [syntax=c]if(!Timer1) Timer1 = 1;[/syntax] jako pierwszą instrukcję w warunku (tym pierwszym, bo i tak sprawdzasz to samo dwa razy).<br />Jakiej prędkości rs232 używasz?<br /><br />-- <br />Pozdrawiam,<br />Robert<br /><br /><strong><span style="color: #808000">------------------------ [ Dodano po: 6 minutach ]</span></strong><br /><br />Jak chcesz mieć regularność twojego programu, to timer nie powinien być zatrzymywany w przerwaniu tylko ponownie przeładowywany a do głównej części programu iść tylko znacznik (inna zmienna) o przepełnieniu licznika.<br />Dodatkowo nie ma sensu działania ze zliczaniem 1 impulsu bo dokładność masz jednego impulsu ;( Ustawiając Timer1 = 1 nie wiesz na jakim etapie zliczania jest licznik w TIMER0.<br /><br /><strong><span style="color: #808000">------------------------ [ Dodano po: 11 minutach ]</span></strong><br /><br /><div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />W jaki sposób użyć flag przerwania timera sprzętowego (TIMER0 CTC Atmega32) zamiast timera programowego, czyli zamiast: if(!Timer1) {instrukcja; Timer1=100}. Pomyślałem, że po co tworzyć timer programowy gdy można bezpośrednio wykorzystać flagi przerwań - będzie dokładniej<br /></div><br />Timer programowy ma sens jak zliczasz np. 100 lub 1000 razy wolniejsze zdarzenia niż przerwanie przepełnienia. Ty próbujesz robić to 1 do 1, więc ciężko to nazwać timerem programowym.<br />Aby sprawdzić czy nastąpiło przepełnienie to nie włączasz przerwania TIMER0_COMP, tylko sprawdzasz flagę w rejestrze. Masz to wszystko podane w datasheetcie do procesora.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3427">rskup</a> — 8 sty 2016, o 19:22</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[avrfun]]></name></author>
<updated>2016-01-08T19:10:46+01:00</updated>
<published>2016-01-08T19:10:46+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149988#p149988</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149988#p149988"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149988#p149988"><![CDATA[
W jaki sposób użyć flag przerwania timera sprzętowego (TIMER0 CTC Atmega32) zamiast timera programowego, czyli zamiast: if(!Timer1) {instrukcja; Timer1=100}. Pomyślałem, że po co tworzyć timer programowy gdy można bezpośrednio wykorzystać flagi przerwań - będzie dokładniej <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=9310">avrfun</a> — 8 sty 2016, o 19:10</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[avrfun]]></name></author>
<updated>2016-01-08T15:20:40+01:00</updated>
<published>2016-01-08T15:20:40+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149967#p149967</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149967#p149967"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149967#p149967"><![CDATA[
<div class="quotetitle">rskup napisał(a):</div><div class="quotecontent"><br />W którymś momencie Timer1 dochodzi Ci do zera i już z nim nic nie robisz.<br />W pętla główna się cały czas wykonuje, bo tam masz już spełniony warunek<br />Składnia: [ Pobierz ] [ Ukryj ]<br />język c<br />if(!Timer1){<br />GeSHi<br /></div><br /><br />Dzięki. Dodałem linię 20, aby po wyzerowaniu timera ustawiać go na 1 czyli 10ms, a więc po 100ms powinien wykonać się warunek case 10. W terminalu cyfry od 1-4 pojawiają się po kolei i co 150 tyknięć, ale LED PC6 nadal mruga nieregularnie, więc nie wiem jaka jest częstotliwość zmian i ile trwa tyknięcie. Chciałbym aby warunki instrukcji switch wykonały się po kolei co 100ms.<br />[syntax=c]while(1){<br /><br />if(!Timer1){<br /><br />PORTC ^= (1&lt;&lt;PC6);<br /><br />switch(tykniecia){<br /><br />case 0:  uart_puts(&quot;1&quot;); break;<br />case 10:  uart_puts(&quot;2&quot;); break;<br />case 20:  uart_puts(&quot;3&quot;); break;<br />case 30:  uart_puts(&quot;4&quot;); break;<br /><br />}<br />tykniecia++;<br /><br />if(tykniecia == 150) tykniecia = 0;<br />}<br /><br />if(!Timer1) Timer1 = 1;<br />}<br />}[/syntax]<br /><br />P.S. Timer zdefiniowany jest w przerwaniu:<br />[syntax=c]ISR(TIMER0_COMP_vect){<br /><br />static uint16_t n;<br /><br />n = Timer1;<br />if(n) Timer1 = --n;<br /><br />PORTC ^= (1&lt;&lt;PC5);<br />}[/syntax]<br /><a href="https://obrazkiforum.atnel.pl/9310/c1e2ca5b641c2f2640e09d9d718804e4.png"  class="postlink"><img src="https://obrazkiforum.atnel.pl/thumb/9310/c1e2ca5b641c2f2640e09d9d718804e4.png" alt="Obrazek" /></a><br />Absolutny brak regularności w wyświetlaniu kolejnych cyfr w terminalu! Dla mnie w chwili obecnej niezrozumiałe.<br />Wygląda to jak interferencja dwóch lub więcej rytmów (częstotliwości), które wypadkowo dają nieregularne mruganie diody (impulsy mają długość: 10ms, 30ms (najczęściej) oraz rzadko 20ms).<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=9310">avrfun</a> — 8 sty 2016, o 15:20</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[rskup]]></name></author>
<updated>2016-01-08T15:02:23+01:00</updated>
<published>2016-01-08T15:02:23+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149965#p149965</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149965#p149965"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149965#p149965"><![CDATA[
A gdzie? Masz:[syntax=c]n = Timer1;<br />if(n) Timer1 = --n;[/syntax]<br />Więc tylko wykonuje się jak Timer1 (n) jest różny od 0.<br /><br />-- <br />Pozdrawiam,<br />Robert<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3427">rskup</a> — 8 sty 2016, o 15:02</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[MirkoT]]></name></author>
<updated>2016-01-08T14:57:10+01:00</updated>
<published>2016-01-08T14:57:10+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149964#p149964</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149964#p149964"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149964#p149964"><![CDATA[
A jak wygląda deklaracja i definicja zmiennej Timer1<br /><br /><strong><span style="color: #808000">------------------------ [ Dodano po: 2 minutach ]</span></strong><br /><br /><div class="quotetitle">rskup napisał(a):</div><div class="quotecontent"><br />W którymś momencie Timer1 dochodzi Ci do zera i już z nim nic nie robisz.<br />W pętla główna się cały czas wykonuje, bo tam masz już spełniony warunek [syntax=c]if(!Timer1){[/syntax]<br /><br />-- <br />Pozdrawiam,<br />Robert<br /></div><br />Nie, nie... w przerwaniu jest cały czas dekrementowana, więc się przekręca i znów działa.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=189">MirkoT</a> — 8 sty 2016, o 14:57</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[rskup]]></name></author>
<updated>2016-01-08T14:49:29+01:00</updated>
<published>2016-01-08T14:49:29+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149962#p149962</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149962#p149962"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149962#p149962"><![CDATA[
W którymś momencie Timer1 dochodzi Ci do zera i już z nim nic nie robisz.<br />W pętla główna się cały czas wykonuje, bo tam masz już spełniony warunek [syntax=c]if(!Timer1){[/syntax]<br /><br />-- <br />Pozdrawiam,<br />Robert<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3427">rskup</a> — 8 sty 2016, o 14:49</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[avrfun]]></name></author>
<updated>2016-01-08T14:01:49+01:00</updated>
<published>2016-01-08T14:01:49+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149959#p149959</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149959#p149959"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149959#p149959"><![CDATA[
Witam.<br /><br />Przeprowadzając badania nad &quot;rozjeżdżaniem się&quot; timerów programowych napisałem krótki program testowy (poniżej). Umieściłem w nim 2 debuggery jednodiodowe. Spodziewałem się, że obie diody będą mrugać w tym samym rytmie gdyż timer programowy (tu z założenia) powinien zerować się co 10ms, ale tak nie jest (zdjęcie poniżej). Nie potrafię tego wyjaśnić. Proszę o podpowiedź.<br />[syntax=c]int main(void){<br /><br />DDRC |= (1&lt;&lt;PC5)|(1&lt;&lt;PC6);<br /><br />TCCR0  |= (1&lt;&lt;WGM01);          // tryb: CTC<br />TCCR0  |= (1&lt;&lt;CS02)|(1&lt;&lt;CS00); // preskaler: 1024<br />OCR0 = 107;                    // rozdzielczosć: 10ms (100Hz)<br />TIMSK  |= (1&lt;&lt;OCIE0);<br /><br />USART_Init(__UBRR);<br />lcd_init();<br /><br />sei();<br /><br />while(1){<br /><br />if(!Timer1){<br /><br />PORTC ^= (1&lt;&lt;PC6);<br /><br />switch(tykniecia){<br /><br />case 0:  uart_puts(&quot;1&quot;); break;<br />case 10:  uart_puts(&quot;2&quot;); break;<br />case 20:  uart_puts(&quot;3&quot;); break;<br />case 30:  uart_puts(&quot;4&quot;); break;<br />}<br />tykniecia++;<br /><br />if(tykniecia == 1000) tykniecia = 0;<br />}<br />}<br />}<br /><br />ISR(TIMER0_COMP_vect){<br /><br />static uint16_t n;<br /><br />n = Timer1;<br />if(n) Timer1 = --n;<br /><br />PORTC ^= (1&lt;&lt;PC5);<br />}[/syntax]<br /><a href="https://obrazkiforum.atnel.pl/9310/b23c59083991a4305a0dcfb8c463b0fc.png"  class="postlink"><img src="https://obrazkiforum.atnel.pl/thumb/9310/b23c59083991a4305a0dcfb8c463b0fc.png" alt="Obrazek" /></a><br />Pozdrawiam<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=9310">avrfun</a> — 8 sty 2016, o 14:01</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[avrfun]]></name></author>
<updated>2016-01-08T06:38:33+01:00</updated>
<published>2016-01-08T06:38:33+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149939#p149939</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149939#p149939"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149939#p149939"><![CDATA[
<div class="quotetitle"><b>Quote:</b></div><div class="quotecontent"><br />...ale tak &quot;ciurkiem&quot; czy co 100ms?<br /></div><br />Witam!<br />Co 100ms<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=9310">avrfun</a> — 8 sty 2016, o 06:38</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[kicajek]]></name></author>
<updated>2016-01-08T00:25:38+01:00</updated>
<published>2016-01-08T00:25:38+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149933#p149933</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149933#p149933"/>
<title type="html"><![CDATA[Re: switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149933#p149933"><![CDATA[
Witam<br /><div class="quotetitle">avrfun napisał(a):</div><div class="quotecontent"><br />wykonał ciąg instrukcji switch case<br /></div><br />...ale tak &quot;ciurkiem&quot; czy co 100ms?<br /><br />Pozdr.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=826">kicajek</a> — 8 sty 2016, o 00:25</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[avrfun]]></name></author>
<updated>2016-01-07T23:42:47+01:00</updated>
<published>2016-01-07T23:42:47+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149928#p149928</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149928#p149928"/>
<title type="html"><![CDATA[switch case - prośba o pomoc w organizacji instrukcji]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=14118&amp;p=149928#p149928"><![CDATA[
Witam!<br />Zorganizowałem licznik 100ms w przerwaniu timera sprzętowego. Próbuję zmusić licznik aby po doliczeniu do konkretnej wartości (np.600) uległ wyzerowaniu, wykonał ciąg instrukcji switch case (linia 7), a następnie liczył dalej do 600 i tak bez przerwy. Nie bardzo wiem, w którym miejscu kodu umieścić tę procedurę. Bardzo proszę o pomoc.<br /><br />licznik:<br />[syntax=c]ISR(TIMER0_COMP_vect){<br /><br />if(t10ms_tics == 10){<br />t10ms_tics = 0;<br />t100ms_tics++;<br />if(t100ms_tics == 600){<br />   t100ms_tics = 0;     // ----&gt; ciąg instrukcji: switch case <br />        }<br />}<br />t10ms_tics++;<br />}[/syntax]<br />ciąg instrukcji do wykonania:<br />[syntax=c]switch (ms100_tick){<br /><br />case 0:  uart_puts(&quot;+&quot;); break;<br />case 1:  uart_puts(&quot;+&quot;); break;<br />case 2:  uart_puts(&quot;+&quot;); break;<br />case 3:  uart_puts(&quot;a&quot;); break;<br />                        // dalsze liczenie do 600 i znów wyzerowanie[/syntax]<br />Pozdrawiam<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=9310">avrfun</a> — 7 sty 2016, o 23:42</p><hr />
]]></content>
</entry>
</feed>