kermit Napisano Wrzesień 16, 2012 Udostępnij Napisano Wrzesień 16, 2012 Witam w drugiej częśći kursu programowania w języku assembler, w pierwszej części trochę was oszczędziłem, ale dziś bierzemy się ostro do roboty. W tej lekcji dowiemy się co to są etykiety, zajmiemy się opóznieniami, zaimpelementujemy do programu obsługę stosu oraz nauczymy sie obsługiwać przycisk(tzw. microswitch). Ćwiczenie 1- przycisk i etykiety: w poprzedniej części jedynie zapaliliśmy naszą diodę led podłączoną anodą(+) do linii PC0, dzisjaj wykonamy już bardziej ambitne zadanie i sprawimy, że nasza dioda zapali się dopiero po przyciśnięciu przycisku, a zgaśnie gdy przycisk zostanie zwolniony. Montujemy układ wg. Poniższego schematu: Lewa strona układu, pozostała bez zmian względem schematu który widzieliśmy w pierwszej części kursu, natomiast po prawej stronie jak widzimy przybył nam jeden microswitch oraz kondensator o pojemności 100nF, po co nam ten kondensator? Otóż microswitche mają to do siebie, że po wciśnięciu przez kilkanaście/kilkadziesiąt milisekund występuje tzw. Efekt drgania styków, który objawia się tym, że zamiast czystego zwarcia, styki przycisku są zwieranie i rozwieranie, zjawisko takie może być bardzo nie pożądane, więc najlepiej za wczasu nauczyć się je eliminować .Jest jeszce druga tzw. Programowa metoda eliminacji drgania styków, ale o tym powiem póżniej. Gdy zmontujemy nasz układ, uruchamiamy AVR studio, tworzymy nowy projekt i przystępujemy do pisania programu: .nolist .include "m32def.inc" .list .cseg .org 0 cbi DDRA,0 // ustawiamy jako linie WEJŚĆIOWĄ pin do którego podlączony jest microswitch sbi PORTA, 0 //podciągamy go przez wewnętrzny opornik do napięcia zasilania sbi DDRC,0 //ustawiamy jako linie WYJŚCIOWĄ pin do którego podłączonona jest nasza dioda LED main: cbi PORTC, 0 //wyłącz diodę led sbic PINA, 0 //jeśli bit nr0 w rejestrze PINA jest wyzerowany(przycisk wciśnięty) pomiń następną instrukcję rjmp main //jeśli bit jest ustawiony (przycisk zwolniony)instrukcja nie zostanie pominięta i nastąpi skok do main rjmp LED_on // jeśli bit jest wyzerowany skocz do funkcji która zapali diode LED_on: sbi PORTC, 0 //ustaw bit nr0 w rejestrze PORTC (zapal diodę led) sbic PINA,0 //jeśli bit nr0 w rejestrze PINA jest wyzerowany(przycisk zwarty do masy,czyli wscisniety),pomin nastepna instrukcje rjmp main //jesli przycisk został zwolniony(bit nr0 w rejestrze PINA jest ustawiony)zostanie wykonany skok do funckji main rjmp LED_on //jesli przycisk jest nadal wcisniety(bit nr0 w rejestrze PINA jest wyzerowany) to nastąpi skok do etykiety LED_on najpierw wpisaliśmy dyrektywy dla kompilatora i ustawiliśmy nasze piny, czyli linię nr0 portu A jako linię wejściową, czyli musieliśmy wyzerować bit o numerze 0 w rejestrze DDRA (wszystkie bity w rejestrach I/O są domyślnie ustawione jako zero, ale lepiej nie ufać wartościom domyślnym i wyzerować konkretny bit), następnie podciągamy nasza linie wejściową poprzez rezystor wewnętrzny do napięcia zasilania(gdy przycisk będzie zwolniony bit nr0 w rejestrze PINA, będzie ustawiony), robimy to poprzez ustawienie(wpisanie wartości 1, używamy instrukcji sbi) bitu 0 rejestru PORTA, ostatnim krokiem jest ustawienie linii 0 portu C do której jest podłączona nasza dioda, jako linie wyjściową . omówmy teraz pętle główną: pętla główna(main) sprawdza nam czy przycisk został wciśnięty(bit nr0 w rejestrze PINA wyzerowany), jeśli tak, następuje skok(instrukcja rjmp) do podprogramu "LED_on" który włącza diode, oraz sprawdza czy przycisk nie został zwolniony(czyli bit nr0 w rejestrze PINA ustawiony ), jeśli został, wykonywany jest skok do pętli "main" i po kolei, co oznaczają poszczególnie linie: " main: "- jest to tzw. Etykieta, czyli adres w pamięci programu, jest nam ona potrzebna wtedy gdy chcemy za pomocą instrukcji (w tym wypadku "rjmp") wykonać skok do miejsca w programie gdzie została użyta ta etykieta. Etykiety zapisujemy ze znakiem dwukropka na końcu . rjmp - Relative Jump- skocz do etykiety "nazwa etykiety" sbic – Skip if Bit in I/O Register Cleared – nie wykonuj następnej instrukcji jeśli bit w rejestrze wejścia/wyjścia jest wyzerowany "którym rejestrze", "numer bitu" Cwiczenie 2 -opóżnienia, stos Pora abyśmy nauczyli się powodować opóznienia w programie, do tego posłuży nam ten sam układ który wykorzystywaliśmy w ćwiczeniu poprzednim, zmienimy tylko trochę jego działanie, otóż gdy przycisk zostanie wciśnięty-dioda zacznie mrugać (z opózniem 250ms) .nolist .include "m32def.inc" .list .cseg .org 0 cli //wyłączenie przerwań ldi R16, HIGH(RAMEND) //załadowanie adresu końca pamięci[stała RAMEND - zdefiniowana w pliku m32def.inc](starszej jego częśći) SRAM do R16 out SPH, R16 //załadowanie zawartości rejestru R16 do SPH(starszej częśći) rejestru który przechowuje tzw. wskaźnik końca stosu ldi R16, LOW(RAMEND) //załadowanie (mlodszej czesci) adresu konca pamieci sram do R16 out SPL, R16 //przepisanie R16 do SPL -rejestru który przechowuje wskażnik końca stosu(młodszej czesci) cbi DDRA,0 // ustawiamy jako linie WEJŚĆIOWĄ pin do którego podlączony jest microswitch sbi PORTA, 0 //podciągamy go przez wewnętrzny opornik do napięcia zasilania sbi DDRC,0 //ustawiamy jako linie WYJŚCIOWĄ pin do którego podłączonona jest nasza dioda LED main: cbi PORTC, 0 //wyłącz diodę led sbis PINA, 0 //jeśli przycisk jest zwolniony pomiń następną instrukcje rjmp LED_on //instrukcja wykonywana gdy przycisk jest wciśnięty, skok do etykiety LED_on rjmp main //instrukcja wykonywana gdy przycisk jest zwolniony ,skok do etykiety main LED_on: //tutaj następuje skok gdy przycisk został wciśnięty = bit nr0 w PINA wyzerowany sbi PORTC, 0 //zapal diodę LED rcall delay //wywołaj podprogram opózniający cbi PORTC, 0 //zgaś diode LED rcall delay //wywołaj podprogram opózniający sbic PINA,0 //pomin następna instrukcje jeśli bit nr 0 w PINA jest wyzerowany = przycisk wicsniety rjmp main //instrukcja wykonywana gdy przycisk zostanie zwolniony ,skok do etykiety main rjmp LED_on //instrukcja wykonywana gdy przycisk jest wcisniety, skok do etykiety LED_on delay: ; ============================= ; delay loop generator ; 250000 cycles: ; ----------------------------- ; delaying 249999 cycles: ldi R16, $A7 WGLOOP0: ldi R17, $02 WGLOOP1: ldi R18, $F8 WGLOOP2: dec R18 brne WGLOOP2 dec R17 brne WGLOOP1 dec R16 brne WGLOOP0 ; ----------------------------- ; delaying 1 cycle: nop ; ============================= ret na początku program może wyglądać na trochę skomplikowany, ale starałem się opisac go jak najdokładniej komentarzami i myślę, że to powinno wystarczyć do zrozumienia idei jego działania.Tutaj chciałbym wyjaśnić tylko kilka spraw które mogą być nie jasne otóż po pierwsze: po co nam stos ? Fragment kodu odpowiedzialny za jego implementację w programie: cli //wyłączenie przerwań ldi R16, HIGH(RAMEND) //załadowanie adresu końca pamięci[stała RAMEND - zdefiniowana w pliku m32def.inc](starszej jego częśći) SRAM do R16 out SPH, R16 //załadowanie zawartości rejestru R16 do SPH(starszej częśći) rejestru który przechowuje tzw. wskaźnik końca stosu ldi R16, LOW(RAMEND) //załadowanie (mlodszej czesci) adresu konca pamieci sram do R16 out SPL, R16 //przepisanie R16 do SPL -rejestru który przechowuje wskażnik końca stosu(młodszej czesci) otóż jest on nam potrzebny ,ponieważ używamy pózniej instrukcji rcall jest to instrukcja która wykonuje skok do podprogramu (podobnie jak instrukcja rjmp) tyle, że po napotkaniu w podprogramie instrukcji ret następuje powrót do adresu(powiększonego o 1) z którego nastąpił skok do podprogramu. W naszym programie instrukcje "rcall" używamy do wywołania podprogramu opózniającego, po wykonaniu tego podprogramu (i co za tym idzie opóznienia trwającego 250ms)po powrocie wykonywana jest instrukcja "sbic PINA,0", czyli do powrotu nie potrzebujemy etykiety. I jeszcze słów kilka o podprogramie opózniającym, otóż nie napisałem go sam, ponieważ w przypadku assemblera pisanie pętli opózniających jest bardzo czasochłonne, użyłem do tego specjalnego programu który generuje nam kod pożądanego opóznienia, program ten jest darmowy i można go pobrać ze strony: http://www.home.unix-ag.org/tjabo/avr/AVRdelayloop.html gdy uruchomimy program wybieramy jakie potrzebujemy opóznienie, jakie jest taktowanie naszego mikrokontrolera oraz jakich rejestrów chcemy użyć w pętli, następnie klikamy przycisk "go" i w polu obok zostaje wygenerowana pętla opózniająca, wystarczy skopiować ją do naszego programu i gotowe. Jeżeli będziemy używali tego podprogramu częśćiej niz raz możemy dodać nad nim etykietę(w przypadku naszego programu to "delay:") a na końcu rozkaz "ret". Za pomocą pętli opóżniających możemy również programowo eliminiować drgania styków, a polega to na tym, że po wykryciu wciśnięcia przycisku w programie następuje opóżnienie trwające co najmniej 50ms, następnie po raz kolejny sprawdzamy czy przycisk jest wciśnięty,jeśli tak program idzie dalej, jeśli nie następuje powrót do pętli sprawdzającej stan przycisku. nowe instrukcje które pojawiły się w programie: rcall - Relative Call Subroutine - skok względny do podprogramu,"etykieta do której ma odbyć się skok" ret – powrót z podprogramu do miejsca z którego nastąpił skok dec - decrement – dekrementuj(pomniejsz o 1), "nazwa rejestru" brne – branch if not equal – skocz jeśli nie jest równe, " do etykiety " nop – no operation – nic nie rób Sbis - Skip if Bit in I/O Register Set, czyli pomiń następną instrukcje, jeśli bit w rejestrze I/O jest ustawiony "nazwa rejestru", "numer bitu" . Na zakończenie słów kilka o symulatorze: w AVR studio 4 mamy dostępny również symulator, który bardzo pomaga w diagnozowaniu błędów w programie, oraz gdy chcemy zobaczyć jak będzie przebiegało jego wykonywanie, aby uruchomić symulator musimy skompilować program-> na górnym pasku wybrać debug-> w rozwiniętym pasku wybrać start debugging-> klikamy F11 -> przeskakująca strzałka wskazuje nam instrukcję która zostanie wykonana w następnym kroku . Stan rejestrów możemy modyfikować i podglądać po prawej stronie okna programu,po lewej stronie widzimy informacje dt. Jednsotki centrlanej przydatne pdfy: http://www.atmel.com/Images/doc1022.pdf - poradnik dla użytkownika assemblera AVR ,możemy znależć tu wsyztskie instrukcjie wypisane w tabeli http://www.atmel.com/images/doc0856.pdf - zdecydowanie bardziej rozbudowany przewodnik, jak widać mamy opisaną po kolei każdą instrukcje i nie tylko. http://www.atmel.com/Images/doc2503.pdf - nota aplikacyjna naszej atmegi32 Starałem się uniknąć błędów w artykule, ale jeśli jednak jakiś znajdziecie, czy to rzecozwy, czy ortograficzny to proszę śmiało pisać. To by było na tyle, do zobaczenia w następej części. 1 Cytuj Link do komentarza Share on other sites More sharing options...
BlackJack Wrzesień 16, 2012 Udostępnij Wrzesień 16, 2012 Hm.. Szczytna seria artykułów, tylko pytanie kto dzisiaj programuje w ASM. Poza mną 😉 i to jeszcze tylko specyficzne wypadki. Co do samego arta, to aby opis programowania w ASM miał spójność, najpierw należałoby by przedstawić rdzeń AVR, tryby adresowania i całą listę instrukcji, a dopiero potem podawać przykłady programów. Tak to powstaje kogel mogel, który tylko miesza początkującemu w głowie, bo zachodzi tylko skąd co się bierze i dlaczego tak a nie inaczej. A w ASM często można napisać to samo na 5 sposobów, używając różnych podejść i instrukcji. Ogólnie artykuł o robieniu wstawek ASM np. w C czy BASCOM byłby git w tej formie, ale o samym ASM, to trzeba liczyć się z 7-10 częściowym artem na dzień dobry jak ma to być spójne i porządne. Sam kurs ASM na 8051 z EDW ma chyba z dobre 24 części, z czego połowa to tylko opis procesora i instrukcji ASM. Cytuj Link do komentarza Share on other sites More sharing options...
kermit Wrzesień 16, 2012 Autor tematu Udostępnij Wrzesień 16, 2012 Jak pisałem już w pierwszej części ,umiejętność programowania w asm jest przydatna ,więc zawsze warto umieć posługiwać się tym językiem ,nawet programując w C (np. czasem zachodzi konieczność napisania wstawki). A co do tego ,że w artykule jest kogel mogel ,po części masz trochę racji, ale nie do końca się z tobą zgadzam, ponieważ czytanie, że gdzieś tam występują takie a takie rejestry czy że mamy architekturę 8-bitową itp. bez napisania co to oznacza z punktu widzenia programisty, nie jest zbyt pouczające i w sumie po przeczytaniu suchych faktów o architekturze i tak nam niewiele daje. edit:to widać mamy trochę odmienne zdanie bo wg. mnie asm jest właśnie takim językiem ,że jak załapiemy na czym polega idea programowania w tym języku niewiele trzeba ,aby swobodnie go używać. Wydaję mi się, że trochę demonizujesz ten język 😉 __________ Komentarz dodany przez: Treker Interpunkcja. Spacje po, a nie przed... 🙂 Cytuj Link do komentarza Share on other sites More sharing options...
BlackJack Wrzesień 16, 2012 Udostępnij Wrzesień 16, 2012 Dla tego napisanie dobrego kursu o ASM jest tak trudne, trzeba umiejętnie pokazywać wiele rzeczy naraz. ASM jest przydatny i to bardzo, szczególnie jak się pisze GRY :-> , albo programy gdzie trzeba wycisnąć ostatni dech z proca, czy pracować ekstremalnie energo oszczędnie, na np. kwarcu zegarkowym i takie rzeczy jak czas wykonania pojedynczej instrukcji, czy dostępu do danych nabierają znaczenia. Cytuj Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
Mars Wrzesień 16, 2012 Udostępnij Wrzesień 16, 2012 Jestem zielony w sprawach architektury uC, ale ogólnie wiem co to rejestr, itp. Póki co rozumiem o czym się do mnie pisze : D (Ciekawe jak będzie później ^^) Bym potestował na medze 8, ale czekają mnie poprawki na dniach (ehh te studia nieszczęsne 😃), więc nie mam "aż" tyle czasu 😉 Cytuj Link do komentarza Share on other sites More sharing options...
Shayoki Wrzesień 19, 2012 Udostępnij Wrzesień 19, 2012 Poradnik trafia w sedno, fakt faktem poznaj assembler a reszta języków programowania to już małe piwo 😉 Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!