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

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2017-01-28T11:30:16+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=4&amp;t=17461&amp;mode</id>
<entry>
<author><name><![CDATA[avrfun]]></name></author>
<updated>2017-01-28T11:30:16+01:00</updated>
<published>2017-01-28T11:30:16+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181102#p181102</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181102#p181102"/>
<title type="html"><![CDATA[Re: Odstępy czasowe pomiędzy poleceniami w sposób nieblokują]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181102#p181102"><![CDATA[
Bardzo dziękuję. Spróbuję ten automat zaimplementować w kodzie programu i poproszę o sprawdzenie.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=9310">avrfun</a> — 28 sty 2017, o 11:30</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[andrews]]></name></author>
<updated>2017-01-28T10:43:03+01:00</updated>
<published>2017-01-28T10:43:03+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181098#p181098</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181098#p181098"/>
<title type="html"><![CDATA[Re: Odstępy czasowe pomiędzy poleceniami w sposób nieblokują]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181098#p181098"><![CDATA[
Chciałbym jeszcze dodać, że koncentrowałem się tutaj bardziej na pokazaniu implementacji maszyny stanów, niż na precyzyjnym odmierzaniu czasu. Świadomie ustaliłem interwał inkrementacji zmiennej <em>timestamp</em> na 10ms, aby podczas odliczania 1000ms jej wartość nie przekroczyła 256, czyli pojemności typu <em>uint8_t</em> (1 bajtu).<br /><br />Chodziło mi o to, żeby nie komplikować niepotrzebnie kodu, ponieważ zmienne kilkubajtowe modyfikowane w przerwaniu wymagają w pętli głównej programu atomowego dostępu, co oznacza, że podczas każdego ich użycia należy wyłączać globalną flagę zezwalającą na przerwania (czy też użyć np. makra ATOMIC_BLOCK).<br /><br />W związku z powyższym mój kod może powodować pewne niedokładności rzędu jednego okresu obiegu timera, czyli 10ms. Jeśli jest to problemem, można zmniejszyć okres do 1ms i użyć zmiennej <em>timestamp</em> typu <em>uint16_t</em>, pamiętając o wyłączaniu przerwań w odpowiednich miejscach.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14165">andrews</a> — 28 sty 2017, o 10:43</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[avrfun]]></name></author>
<updated>2017-01-27T18:51:22+01:00</updated>
<published>2017-01-27T18:51:22+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181041#p181041</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181041#p181041"/>
<title type="html"><![CDATA[Re: Odstępy czasowe pomiędzy poleceniami w sposób nieblokują]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181041#p181041"><![CDATA[
<div class="quotetitle">andrews napisał(a):</div><div class="quotecontent"><br />Przedstawię jak mniej więcej jak ja bym to widział. Nie będzie to kod gotowy do skopiowania i skompilowania, ale taki &quot;zarys&quot; (objaśnienia w kodzie - w razie niejasności postaram się wyjaśnić):<br /></div><br />Bardzo dziękuję! Przeanalizuję kod i w razie niejasności i wątpliwości poproszę o wyjaśnienie. Pozdrawiam.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=9310">avrfun</a> — 27 sty 2017, o 18:51</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[andrews]]></name></author>
<updated>2017-01-27T18:01:55+01:00</updated>
<published>2017-01-27T18:01:55+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181040#p181040</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181040#p181040"/>
<title type="html"><![CDATA[Re: Odstępy czasowe pomiędzy poleceniami w sposób nieblokują]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181040#p181040"><![CDATA[
Przedstawię jak mniej więcej jak ja bym to widział. Nie będzie to kod gotowy do skopiowania i skompilowania, ale taki &quot;zarys&quot; (objaśnienia w kodzie - w razie niejasności postaram się wyjaśnić):<br /><br />[syntax=c]//................................<br /><br />// czas &quot;obiegu&quot; timera w ms<br />#define TIMER_PERIOD    10<br /><br />// definicje czasów opóźnień w ms<br />#define DELAY1          1000<br />#define DELAY2          200<br />#define DELAY3          300<br /><br />//..................................<br /><br />// stany, jakie może przyjąć automat<br />enum State {<br />    WAITING_FOR_HIGH_LEVEL,<br />    WAITING_FOR_LOW_LEVEL,<br />    FISRT_DELAY,<br />    SECOND_DELAY,<br />    THIRD_DELAY<br />    };<br /><br />// ..........................<br /><br />// zmienna inkrementowana w przerwaniu timera<br />volatile uint8_t timestamp;<br /><br />//...........................<br /><br />// timer2 (przykładowo) skonfigurowany na 10ms<br />// w procedurze obsługi przerwania tylko<br />ISR(TIMER2_COMPA_vect)<br />{<br />    timestamp++;<br />}<br /><br />//..........................<br /><br />// definicja funkcji wywoływanej cyklicznie w pętli while (1) we funckji &#91;i&#93;main&#91;/i&#93;<br />void RTC_EVENT(void)<br />{<br />    // zmienna statyczna reprezentująca aktualny stan automatu<br />    static enum State current_state = WAITING_FOR_HIGH_LEVEL;<br />    // zmienna wyznaczająca moment końca opóźnienia<br />    static uint8_t next_send_time;<br />    <br />    switch (current_state)<br />    {<br />        case WAITING_FOR_HIGH_LEVEL:<br />            // jeśli na pinie wystąpił stan wysoki<br />            if ( (PINC &amp; KEY_SOFT_INT_PIN) )<br />            {<br />                // włączamy oczekiwanie na stan niski<br />                current_state = WAITING_FOR_LOW_LEVEL;<br />            }<br />            break;<br />        case WAITING_FOR_LOW_LEVEL: /* czekamy na stan niski na pinie */<br />            // jeśli wystąpił stan niski<br />            if ( !(PINC &amp; KEY_SOFT_INT_PIN) )<br />            {<br />                // odczytujemy czas<br />                get_rtc_datetime();<br />                // jeśli sekundy przyjęly wartość 0<br />                if (datetime.ss == 0)<br />                {<br />                    // wysyłamy pierwszy pakiet<br />                    uart_puts(&quot;1&quot;);<br />                    // oznaczamy moment w którym upłynie pierwsze opóźnienie<br />                    next_send_time = timestamp + DELAY1/TIMER_PERIOD;<br />                    // włączamy pierwsze opóźnienie<br />                    current_state = FISRT_DELAY;<br />                }<br />                // jeśli nie przyjęły wartości 0<br />                else<br />                {<br />                    // włączamy oczekiwanie na stan niski<br />                    current_state = WAITING_FOR_HIGH_LEVEL;<br />                }<br />            }<br />            break;<br />        case FISRT_DELAY:<br />            // jeśli timestamp osiągnął żądaną wartość<br />            if ( timestamp &gt;= next_send_time )<br />            {<br />                // wysyłamy drugi pakiet<br />                uart_puts(&quot;2&quot;);<br />                // oznaczamy moment w którym upłynie drugie opóźnienie<br />                next_send_time = timestamp + DELAY2/TIMER_PERIOD;<br />                // włączamy drugie opóźnienie<br />                current_state = SECOND_DELAY;<br />            }<br />            break;<br />        case SECOND_DELAY:<br />            // jeśli timestamp osiągnął żądaną wartość<br />            if ( timestamp &gt;= next_send_time )<br />            {<br />                // wysyłamy trzeci pakiet<br />                uart_puts(&quot;3&quot;);<br />                // oznaczamy moent w którym upłynie trzecie opóźnienie<br />                next_send_time = timestamp + DELAY3/TIMER_PERIOD;<br />                // włączamy trzecie opóźnienie<br />                current_state = THIRD_DELAY;<br />            }<br />            break;<br />        case THIRD_DELAY:<br />            // jeśli timestamp osiągnął żądaną wartość<br />            if ( timestamp &gt;= next_send_time )<br />            {<br />                // wysyłamy ostatni pakiet<br />                funkcja_send(argumenty);<br />                // włączamy oczekiwanie na stan niski<br />                current_state = WAITING_FOR_HIGH_LEVEL;<br />            }<br />            break;<br />    }<br />}<br /><br />//...........................[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14165">andrews</a> — 27 sty 2017, o 18:01</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[avrfun]]></name></author>
<updated>2017-01-27T12:20:42+01:00</updated>
<published>2017-01-27T12:20:42+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181011#p181011</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181011#p181011"/>
<title type="html"><![CDATA[Re: Odstępy czasowe pomiędzy poleceniami w sposób nieblokują]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181011#p181011"><![CDATA[
<div class="quotetitle">andrews napisał(a):</div><div class="quotecontent"><br />Możesz zaimplementować wewnątrz funkcji prosty automat skończony (ang. finite state machine).<br /><br />W tej chwili nie mam czasu, a trudno to opisać na szybko w kilku słowach, więc może późniejszym popołudniem/wieczorem pokażę jakiś przykładowy kod, jeśli problem nie zostanie jeszcze rozwiązany.<br /></div><br /><br />Bardzo dziękuję. Poszukam. Będę wdzięczny za przykład w miarę wolnego czasu. Mój &quot;automat&quot; jest nieskończony bo timer programowy działa non-stop .<br />Pozdrawiam<br /><br /><strong><span style="color: #808000">------------------------ [ Dodano po: 22 minutach ]</span></strong><br /><br />Zrobiłem tak:<br />[syntax=c]void inicjalizacja(){<br /><br />if(!Timer1){<br /><br />switch(licznik){<br /><br />case 0: uart_puts(&quot;1&quot;); break;<br />case 10: uart_puts(&quot;2&quot;); break;<br />}<br />licznik++;<br />Timer1 = 10;<br />}<br />}[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=9310">avrfun</a> — 27 sty 2017, o 12:20</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[andrews]]></name></author>
<updated>2017-01-27T11:56:31+01:00</updated>
<published>2017-01-27T11:56:31+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181008#p181008</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181008#p181008"/>
<title type="html"><![CDATA[Re: Odstępy czasowe pomiędzy poleceniami w sposób nieblokują]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181008#p181008"><![CDATA[
Możesz zaimplementować wewnątrz funkcji prosty automat skończony (ang. <em>finite state machine</em>).<br /><br />W tej chwili nie mam czasu, a trudno to opisać na szybko w kilku słowach, więc może późniejszym popołudniem/wieczorem pokażę jakiś przykładowy kod, jeśli problem nie zostanie jeszcze rozwiązany.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14165">andrews</a> — 27 sty 2017, o 11:56</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[avrfun]]></name></author>
<updated>2017-01-27T11:34:03+01:00</updated>
<published>2017-01-27T11:34:03+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181006#p181006</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181006#p181006"/>
<title type="html"><![CDATA[Re: Odstępy czasowe pomiędzy poleceniami w sposób nieblokują]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181006#p181006"><![CDATA[
<div class="quotetitle">anonimg3 napisał(a):</div><div class="quotecontent"><br />Nie lepiej wrzucić do uC i sprawdzić, czy działa?<br /></div><br />Wrzucę i sprawdzę<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=9310">avrfun</a> — 27 sty 2017, o 11:34</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[anonimg3]]></name></author>
<updated>2017-01-27T11:31:04+01:00</updated>
<published>2017-01-27T11:31:04+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181005#p181005</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181005#p181005"/>
<title type="html"><![CDATA[Re: Odstępy czasowe pomiędzy poleceniami w sposób nieblokują]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181005#p181005"><![CDATA[
Po pierwsze nie wiem czemu funkcja inicjalizacja() jest w while() oraz RTC_EVENT(). Po drugie ciężko powiedzieć, bo nie ma całego kodu a jedynie fragmenty. Nie lepiej wrzucić do uC i sprawdzić, czy działa? <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=8904">anonimg3</a> — 27 sty 2017, o 11:31</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[avrfun]]></name></author>
<updated>2017-01-27T11:16:17+01:00</updated>
<published>2017-01-27T11:16:17+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181004#p181004</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181004#p181004"/>
<title type="html"><![CDATA[Re: Odstępy czasowe pomiędzy poleceniami w sposób nieblokują]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181004#p181004"><![CDATA[
<div class="quotetitle">anonimg3 napisał(a):</div><div class="quotecontent"><br />Dlaczego nie możesz umieścić w pętli while()? Wystarczy, że zamiast wysyłania w RTC_EVENT() ustawisz jakąś zmienną pomocniczą, a w pętli while() sprawdzisz warunek na podstawie tej zmiennej.<br /></div><br />Dziękuję. Jest to kwestia organizacji dużego programu. Myślałem żeby zrobić tak:<br /><br />1. W ciele RTC_EVENT(), jak w pierwszym poscie, przed funkcją <em>send</em> umieścić funkcję<em> inicjalizacja</em><br />[syntax=c]void RTC_EVENT(void){<br /> <br />        /* Programowy INT0 RTC-&gt;INT0-&gt;KEY_SOFT_INT_PIN */<br />        if(!key_lock &amp;&amp; !(PINC &amp; KEY_SOFT_INT_PIN)){<br /> <br />            key_lock=1;<br />            get_rtc_datetime(&amp;datetime);                // Odczyt daty i czasu z układu RTC<br /> <br />            if(datetime.ss ==0){<br /> <br />                  inicjalizacja();<br />                  funkcja_send(argumenty)   // Właściwa funkcja wysyłająca dane do uart<br />            }<br />       <br />        } else if(key_lock &amp;&amp; (PINC &amp; KEY_SOFT_INT_PIN)) key_lock=0;<br />}[/syntax]<br />2. Funkcję <em>inicjalizacja</em> umieścić w pętli while<br />[syntax=c]while(1){<br /> <br />        UART_RX_STR_EVENT(bufor);<br />        RTC_EVENT();<br />        inicjalizacja();<br />}[/syntax]<br />3. W ciele funkcji <em>inicjalizacja</em> zawrzeć timer programowy z licznikiem, który będzie odmierzał zadane odstępy czasu, przy konkretnej wartości licznika funkcja się zakończy i powróci do miejsca wywołania w RTC_EVENT() i w następnej kolejności uruchomiona zostanie funkcja send<br />[syntax=c]void inicjalizacja(){<br /><br />if(!Timer1){<br /><br />if(licznik == 0) uart_puts(&quot;1\r&quot;);<br />if(licznik == 1) uart_puts(&quot;2\r&quot;);<br />if(licznik == 2) uart_puts(&quot;3\r&quot;);<br />if(licznik == 3) uart_puts(&quot;4\r\r&quot;);<br /><br />if(licznik == 3){<br /><br />licznik = 10;<br /><br />} else {<br /><br />licznik++;<br />Timer1 = 200;<br />}<br />}<br />}[/syntax]<br />Czy założenia tego pomysłu są poprawne?<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=9310">avrfun</a> — 27 sty 2017, o 11:16</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[anonimg3]]></name></author>
<updated>2017-01-27T10:15:10+01:00</updated>
<published>2017-01-27T10:15:10+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181002#p181002</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181002#p181002"/>
<title type="html"><![CDATA[Re: Odstępy czasowe pomiędzy poleceniami w sposób nieblokują]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=181002#p181002"><![CDATA[
Dlaczego nie możesz umieścić w pętli while()? Wystarczy, że zamiast wysyłania w RTC_EVENT() ustawisz jakąś zmienną pomocniczą, a w pętli while() sprawdzisz warunek na podstawie tej zmiennej. Co do odstępu czasowego to odsyłam do poradnika MODULO na YT, który przygotował Pan Mirosław.<br /><br />BTW. Zachęcam do zakupu YELLOWBOOKA, bo tam jest pięknie opisana realizacja timerów sprzętowych oraz timeoutów z wykorzystaniem struktur i jednego przerwania sprzętowego, oczywiście w sposób nieblokujący.  <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=8904">anonimg3</a> — 27 sty 2017, o 10:15</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[avrfun]]></name></author>
<updated>2017-01-27T08:58:32+01:00</updated>
<published>2017-01-27T08:58:32+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=180998#p180998</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=180998#p180998"/>
<title type="html"><![CDATA[Odstępy czasowe pomiędzy poleceniami w sposób nieblokujący]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=17461&amp;p=180998#p180998"><![CDATA[
Witam!<br /><br />Mam pewien problem z wykonaniem kilku instrukcji po kolei, nieblokująco (timer programowy – 10ms), ale w szczególnej sytuacji. W programie głównym, w pętli while, wywoływane jest zdarzenie od okładu RTC RTC_EVENT(). W zdarzeniu tym w rytm sygnału z RTC co 1 sekundę pobierany jest z niego czas i gdy sekundy są zerowe (co minutę) następuje uruchomienie funkcji (funkcja_send) wysyłającej dane przez uart. Problem w tym, że przed właściwym wysłaniem danych (funkcja_send)  chciałbym wysłać do uart serię poleceń w odstępach np. 1000, 200, 300ms. Gdyby funkcja_send była w pętli while problemu by nie było. Proszę o pomoc i wskazówki. W kodzie wygląda to tak:<br /><br />[syntax=c]while(1){<br /><br />UART_RX_STR_EVENT(bufor);<br />RTC_EVENT();<br />}[/syntax]<br /><br />[syntax=c]void RTC_EVENT(void){<br /><br />/* Programowy INT0 RTC-&gt;INT0-&gt;KEY_SOFT_INT_PIN */<br />if(!key_lock &amp;&amp; !(PINC &amp; KEY_SOFT_INT_PIN)){<br /><br />    key_lock=1;<br />    get_rtc_datetime(&amp;datetime);// Odczyt daty i czasu z układu RTC<br /><br />    if(datetime.ss ==0){<br /><br />                  uart_puts(&quot;1&quot;);<br />                  1000ms                   // jak wstawić ten odstęp czasowy nieblokująco;<br />                  uart_puts(&quot;2&quot;;<br />                  200ms                     // jak wstawić ten odstęp czasowy nieblokująco;<br />                  uart_puts(&quot;3&quot;);<br />                  300ms                     // jak wstawić ten odstęp czasowy nieblokująco;<br /><br />          funkcja_send(argumenty)   // Właściwa funkcja wysyłająca dane do uart<br />            }<br /><br />} else if(key_lock &amp;&amp; (PINC &amp; KEY_SOFT_INT_PIN)) key_lock=0;<br />}[/syntax]<br /><br />Pozdrawiam<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=9310">avrfun</a> — 27 sty 2017, o 08:58</p><hr />
]]></content>
</entry>
</feed>