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

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2016-07-28T06:08:37+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=4&amp;t=15866&amp;mode</id>
<entry>
<author><name><![CDATA[andrews]]></name></author>
<updated>2016-07-28T06:08:37+01:00</updated>
<published>2016-07-28T06:08:37+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15866&amp;p=164877#p164877</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15866&amp;p=164877#p164877"/>
<title type="html"><![CDATA[Re: ATmega88PA i funkcja delay_ms na Timerze 2]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15866&amp;p=164877#p164877"><![CDATA[
Takie rozwiązanie też jest OK.<br /><br />Pozwolę sobie jednak wytłumaczyć, na czym polega różnica między naszymi rozwiązaniami.<br />W Twoim przypadku akurat prawdopodobnie nie ma to większego znaczenia, ale czasami jest bardzo istotne, aby przerwania blokować na jak najkrótszy okres czasu, szczególnie jeśli korzystamy z większej ilości przerwań i niektóre z nich wymagają natychmiastowej (lub przynajmniej jak najszybszej) reakcji.<br /><br />Rozwiązanie z dodatkową zmienną ma w takim przypadku przewagę, dlatego że przerwania są zablokowane tylko na czas odczytu/kopiowania zmiennej <em>delay_cnt_ms</em>. W Twoim rozwiązaniu, oprócz odczytu danej z RAM, musi być jeszcze wykonane porównanie zmiennej z wartością 0 i przypisanie wartości do zmiennej <em>exit</em>. To zajmie nieco więcej czasu, a przerwanie, które może w tym czasie nastąpić, będzie musiało zaczekać na obsługę do końca bloku ATOMIC_BLOCK.<br /><br />Mam nadzieję, że nie potraktujesz tego jako złośliwą krytykę, bo nie to było moim zamiarem <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=14165">andrews</a> — 28 lip 2016, o 06:08</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[JungleMan]]></name></author>
<updated>2016-07-27T18:01:56+01:00</updated>
<published>2016-07-27T18:01:56+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15866&amp;p=164833#p164833</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15866&amp;p=164833#p164833"/>
<title type="html"><![CDATA[Re: ATmega88PA i funkcja delay_ms na Timerze 2]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15866&amp;p=164833#p164833"><![CDATA[
Ogromne dzięki andrews. Nigdy bym na to nie wpadł.<br /><br />Rozwiązałem to w następujący sposób:<br />[c]<br />void delay_ms_x (uint16_t ms_del) {<br />uint8_t exit = FALSE;<br />delay_cnt_ms = ms_del;<br /><br />Timer2_start();<br /><br />while(1) {<br />ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {<br />if(!delay_cnt_ms) exit = TRUE;<br />}<br />if(exit) break;<br />}<br /><br />Timer2_stop();<br />}[/c]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3945">JungleMan</a> — 27 lip 2016, o 18:01</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[andrews]]></name></author>
<updated>2016-07-27T05:56:12+01:00</updated>
<published>2016-07-27T05:56:12+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15866&amp;p=164797#p164797</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15866&amp;p=164797#p164797"/>
<title type="html"><![CDATA[Re: ATmega88PA i funkcja delay_ms na Timerze 2]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15866&amp;p=164797#p164797"><![CDATA[
<div class="quotetitle">JungleMan napisał(a):</div><div class="quotecontent"><br />[syntax=c]   while(delay_cnt_ms);[/syntax]<br /></div>Tak naprawdę to ta instrukcja jest równoważna:[syntax=c]   while(delay_cnt_ms!=0);[/syntax]<br />Zwróć uwagę, że w tym momencie mikrokontroler porównuje z wartością 0 zmienną dwubajtową modyfikowaną w przerwaniu. Jako że jest to mikrokontroler 8-bitowy, nie zrobi tego w jednym takcie zegara, a między sprawdzaniem poszczególnych bajtów może wystąpić przerwanie, które wprowadzi nową wartość do tej zmiennej i operacja porównania będzie błędna. Możnaby spróbować wprowadzić zmienną pośrednią i zapewnić atomowy dostęp do zmiennej <strong><em>delay_cnt_ms</em></strong>, coś w stylu:[syntax=c]uint16_t delay_tmp;<br />do<br />{<br />    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {<br />        delay_tmp = delay_cnt_ms;<br />    }<br />} while(delay_tmp);[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=14165">andrews</a> — 27 lip 2016, o 05:56</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[Jaglarz]]></name></author>
<updated>2016-07-27T00:38:59+01:00</updated>
<published>2016-07-27T00:38:59+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15866&amp;p=164796#p164796</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15866&amp;p=164796#p164796"/>
<title type="html"><![CDATA[Re: ATmega88PA i funkcja delay_ms na Timerze 2]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15866&amp;p=164796#p164796"><![CDATA[
<!-- l --><a class="postlink-local" href="http://forum.atnel.pl/topic7402.html" >topic7402.html</a><!-- l --><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=471">Jaglarz</a> — 27 lip 2016, o 00:38</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[JungleMan]]></name></author>
<updated>2016-07-27T18:03:39+01:00</updated>
<published>2016-07-27T00:36:30+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=15866&amp;p=164795#p164795</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=15866&amp;p=164795#p164795"/>
<title type="html"><![CDATA[ATmega88PA i funkcja delay_ms na Timerze 2]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=15866&amp;p=164795#p164795"><![CDATA[
Witam,<br /><br />mam pewien problem, który wydaje mi się banalny, ale nie daje mi spać.<br /><br />Otóż, utworzyłem sobie funkcję delay_ms_x o ciele:<br />[c]inline void Timer2_start() {<br />// Clear timer register.<br />TCNT2 = 0;<br /><br />// Start Timer and set prescaling.<br />TCCR2B |= (1&lt;&lt;CS21);<br />}<br /><br />inline void Timer2_stop() {<br />TCCR2B &amp;= ~((1&lt;&lt;CS22) | (1&lt;&lt;CS21) | (1&lt;&lt;CS20));<br />}<br /><br />void delay_ms_x (uint16_t ms_del) {<br />delay_cnt_ms = ms_del;<br />Timer2_start();<br />while(delay_cnt_ms);<br />Timer2_stop();<br />}[/c]<br /><br />Ową funkcję wywołuję w pętli, która odpowiedzialna jest za animację a'la &quot;loading&quot; na LCD:<br />[c]for(uint8_t i = 0 ; i &lt; LCD_COLS &amp;&amp; dev_state == UNARMING; i ++) {<br />lcd_char(0xFF);<br />delay_ms_x(arm_bar_dur);<br />LED_TOG;<br />}[/c]<br /><br />Ciało przerwania Timer'a 2:<br />[c]<br />ISR(TIMER2_COMPA_vect) {<br />if(!delay_cnt_ms) return;<br />delay_cnt_ms--;<br />}[/c]<br /><br />Timer2 inicjalizuję na początku funkcji main:<br />[c]void Timer2_init() {<br />// Set CTC mode.<br />TCCR2A |= (1&lt;&lt;WGM21);<br /><br />#define TIMER2_PRESCALER (8.0)<br />#define TIMER2_INT_FREQ (1000.0)<br /><br />// Set ~1ms interrupt.<br />OCR2A = F_CPU / TIMER2_PRESCALER / TIMER2_INT_FREQ - 1;<br /><br />TIMER2_INT_EN;<br />}[/c]<br /><br /><br />Problem w tym, że raz po raz ten odstęp nie jest równy i co około 3 raz funkcja delay_ms_x kończy swoje instrukcje szybciej niż powinna.<br />Zmienna arm_bar_dur jest niezmienna. Nawet jak podmieniłem w wywołaniu funkcji argument na wartość liczbową zachowanie jest identyczne.<br />Proszę, pokażcie mi gdzie popełniam błąd.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3945">JungleMan</a> — 27 lip 2016, o 00:36</p><hr />
]]></content>
</entry>
</feed>