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

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2015-08-23T17:04:37+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=49&amp;t=12443&amp;mode</id>
<entry>
<author><name><![CDATA[daro2020]]></name></author>
<updated>2015-08-23T17:04:37+01:00</updated>
<published>2015-08-23T17:04:37+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=12443&amp;p=138156#p138156</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=12443&amp;p=138156#p138156"/>
<title type="html"><![CDATA[Re: Knight rider - jak uprościć delay?]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=12443&amp;p=138156#p138156"><![CDATA[
Nie koniecznie delaye to zło. Korzystam z nich czasem w debugowaniu, albo przy inicjalizacji programu, zanim ruszy cała machina przerwaniowo-timerowa. A gdybyś chciał kiedykolwiek użyć delaya w asm to zrób tak:<br />[syntax=asm]Delay:<br />                ldi r17, 255                    ;24 bit count down delay<br />                ldi r18, 255<br />                ldi r19, 2<br />Delay_Loop: <br />              dec r17<br />              brne Delay_Loop<br />              dec r18<br />              brne Delay_Loop<br />              dec r19<br />              brne Delay_Loop[/syntax]<br />Poza tym uważam, że jednym z najbardziej przyjaznych asm posiadają AVRy, niby to aż 140 instrukcji, ale biorąc po uwagę instrukcje pochodne lub powielające się, ich ilość jest niewielka. Plusem AVR jest że każdy z 32 rejestrów roboczych może pełnić rolę akumalatora.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1608">daro2020</a> — 23 sie 2015, o 17:04</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[j23]]></name></author>
<updated>2015-07-27T01:53:17+01:00</updated>
<published>2015-07-27T01:53:17+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=12443&amp;p=135592#p135592</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=12443&amp;p=135592#p135592"/>
<title type="html"><![CDATA[Re: M32 - Knight rider, jak uprościć delay?]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=12443&amp;p=135592#p135592"><![CDATA[
Cześć Anty,<br /><div class="quotetitle">Antystatyczny napisał(a):</div><div class="quotecontent"><br />1. Czy da się jakoś uprościć funkcję Delay?<br />2. Jak właściwie obliczać długość takiego delaya?<br />3. A może jest zupełnie inna metoda tworzenia delaya?<br /></div><br />Zacznę trochę nietypowo, bo od 2-giego punktu:<br />Ad.2 - Podstawa to jest znać ilość cykli zegarowych potrzebnej do wykonania danej instrukcji procesora (arytmetycznego). To zawsze powinno być w dokumentacji gdzieś w dziale &quot;Arithmetic and Logic Instructions&quot; w kolumnie &quot;Cycles&quot;. Sumujesz ilość cykli wszystkich instrukcji (pamiętając, że liczenie w ALU zaczyna się od zera) oraz dodajesz 4 cykle (zazwyczaj) na powrót z instrukcji ret.<br /><br />Ad.3 - Nie wiem czy są jakieś konkretne metody tworzenia delay'ów. Ja zawsze -podobnie jak Kolega SylwekK stosowałem pętle, gdzie przeważnie w tej całkiem wewnętrznej pętli była instrukcja nop. Z tym stosowaniem pętli jest taka ciekawostka, że trzeba wiedzieć następującą (być może prozaiczną zasadę obliczenia czasu):[syntax=asm]----------------------------------------------------------------------------------------------------------------------------<br />                                                ilość cykli zegarowych straconych na pętlę (lub wiele pętli)  &#91;Hz&#93;<br />czas opóźnienia (w sekundach) = ------------------------------------------------------------------------------------<br />                                                ilość cykli na sekundę z jaką działa zegar procesora  &#91;Herców=Hz&#93;<br />----------------------------------------------------------------------------------------------------------------------------[/syntax]<br /><br />W oparciu o to dokonujemy przekształcenia wzoru i mamy tak:[syntax=asm]ilość cykli zegarowych straconych na pętlę (lub wiele pętli) = czas opóźnienia * ilość cykli na sekundę z jaką działa zegar procesora[/syntax]<br /><br />Teraz wiemy ile musimy &quot;nabić&quot; tych cykli jakimiś instrukcjami i jakimiś pętlami (wewnętrznymi i zewnętrznymi)...<br />np. taka pętla dla Atmega32...<br />[syntax=asm]ldi R16, 0                           ; wyzerowanie rejestru (jeśli trzeba) - 1 cykl zegarowy (dodatkowy)<br />opoznienie_125_cykli:                ; nazwa_podprogramu<br />inc R16                              ; inkrementacja rejestru  - 1 cykl zegarowy<br />cpi R16, 125                         ; ComPare Immediate     - 1 cykl zegarowy<br />brlo opoznienie_125_cykli            ; BRanch if LOwer - skok do instrukcji wywołującej, jeśli wartość w rejestrze R16 jest mniejsza - 2 cykle zegarowe[/syntax]Ostatnia instrukcja skoku  jest dość ciekawa, bo zajmuje 2 cykle jeśli występuje w pętli zewnętrznej tak jak tutaj, ale 1 cykl zegarowy w pętli wewnętrzej - patrz proszę przykład poniżej:<br /><br /><br />[syntax=asm];początek podprogramu<br />Opoznienie:<br />ldi R17, 0                                                        ; 1 cykl zegarowy<br />; pętla zewnętrzna - start<br />zewn_opoznienie_8_cykli_x_ilosc_cykli_instrukcji:<br />     ldi R16, 0                                                   ; 1 cykl zegarowy<br />     ; pętla wewnętrzna - start<br />     wewn_opoznienie_125_cykli_x_ilosc_cykli_instrukcji:<br />     inc R16                                                      ; 1 cykl zegarowy<br />     cpi R16, 125                                                 ; 1 cykl zegarowy<br />     brlo wewn_opoznienie_125_cykli_x_ilosc_cykli_instrukcji      ; 1 cykl zegarowy<br />     ; pętla wewnętrzna - end<br />inc R17                                                           ; 1 cykl zegarowy<br />cpi R17, 8                                                        ; 1 cykl zegarowy<br />brlo zewn_opoznienie_8_cykli_x_ilosc_cykli_instrukcji             ; 2 cykle zegarowe<br />; pętla zewnętrzna - end<br />ret                                                               ; powrót z podprogramu 4 cykle zegarowe[/syntax]<br /><br />Liczymy ilość cykli pętli wewnętrznej:<br />125 * 4 = 500 cykli zegarowych<br /><br />Liczymy ilość cykli pętli zewnętrznej:<br />- pętla wewnętrzna wykona: 500 * 8 (wartość R17) = 4000 cykli zegarowych<br />- oraz wykona raz obejście samej siebie co jej zajmie: 4 * 8 = 32 cykle zegarowe<br /><br />Suma cykli zegarowych wynikających z pętli wewn. i zewn. = 4032 i do tego należy dodać 1 cykl zerowania rejestru R17 oraz 4 cykle na powrót z instrukcji wywołania (ret), czyli RAZEM: 4032 + 1+ 4 = 4037 cykli<br /><br />Czas jaki to zajmie przy założeniu że ALU jest taktowany zegarem np. 8 MHz:<br />t = 4037 / 8000000 = 0.0005 sekundy<br /><br />Mam nadzieję, że niczego nie pomieszałem, bo dość późno o tym piszę, ale chcę dobrze.<br />Anty akurat do asemblera jeśli chodzi o avr'y ja używałem książki Borkowskiego. Nie jest to może najlepsza książka, jednak ma tą przewagę nad innymi, że niektóre rzeczy akurat w assemblerze autor tłumaczy tam naprawdę dokładnie, można by rzec zbyt dokładnie i zbyt wiele drobnych uwag tam wtrąca, które mnie akurat rozpraszały, ale jak dla kogoś kto zaczyna mogłyby pomóc...<br />A gdy się już te podstawy zrozumie to należy się wziąść za Baranowskiego - on już jedzie ostrzej <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /><br /><br />Acha, często stosuje się ileś tam nop'ów, tzn. nop - to taka mini-instrukcja delay procesora <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /> która zajmuje przeważnie 1 cykl zegarowy<br />Mam nadzieję, że przynajmniej odrobinkę pomogłem <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /><br /><br />Pozdrawiam! j23 Jarek<br />P.S. &quot;Załaduj program skoków&quot; <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /> ...z Matrix'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=4504">j23</a> — 27 lip 2015, o 01:53</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[SylwekK]]></name></author>
<updated>2015-07-26T12:44:27+01:00</updated>
<published>2015-07-26T12:44:27+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=12443&amp;p=135526#p135526</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=12443&amp;p=135526#p135526"/>
<title type="html"><![CDATA[Re: M32 - Knight rider, jak uprościć delay?]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=12443&amp;p=135526#p135526"><![CDATA[
Nie orientuję się jeszcze w asemblerze na uC natomiast na pierwszy rzut oka wydaje mi się bardzo rozbudowany ten delay. Ja przy programowaniu 20 lat temu 6502 stosowałem bardzo prostą pętlę zagnieżdżoną. O ile pamiętam wyglądało to mniej więcej tak:<br /><br />[syntax=asm].     ldx #$FF <br />tu2:  ldy #$FF<br />tu1:  dey<br />      bne tu1<br />      dex<br />      bne tu2<br />      rts[/syntax]<br /><br />Tłumaczenia chyba to nie wymaga no i oczywiście to w pełni blokujący fragment programu <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1922">SylwekK</a> — 26 lip 2015, o 12:44</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[mirekk36]]></name></author>
<updated>2015-07-26T12:21:52+01:00</updated>
<published>2015-07-26T12:21:52+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=12443&amp;p=135523#p135523</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=12443&amp;p=135523#p135523"/>
<title type="html"><![CDATA[Re: M32 - Knight rider, jak uprościć delay?]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=12443&amp;p=135523#p135523"><![CDATA[
1-3... proponuję ci napisać taki sam program w C, i zajrzeć do pliku *.lss czyli asemblerowego. Zresztą wtedy możesz poćwiczyć z różnymi wariantami _delay_ms() w C i zobaczyć jak to robi kompilator i jak przygotowuje się do kontrolowanego w czasie opóźnienia <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /> czyli dla różnego taktowania ten sam _delay_ms() będzie bardzo ciekawie różnie wyglądał w ASM i dużo ci to pomoże . Bo to co tu opisałeś to raczej taki delay - nazwałbym go &quot;na czuja&quot; czyli &quot;na oko&quot; dajesz takie wartości na różnych poziomach licznika aby dopasować sobie miganie diody LED<br /><br />A z drugiej strony to i tu da się precyzyjnie powyliczać czas - przecież to asembler - patrzysz więc na czasy wykonywania poszczególych instrukcji asemblerowych - czy zajmują jeden, dwa czy więcej cykli zegara i po kolei liczysz uwzględniając oczywiście działania pętli itp ... no jest z tym trochę zabawy <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /> jak widać - ale da się zrobić<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=54">mirekk36</a> — 26 lip 2015, o 12:21</p><hr />
]]></content>
</entry>
</feed>