Fórum témák

» Több friss téma
Cikkek » AVR Assembly kezdőknek
AVR Assembly kezdőknek
Szerző: sgt, idő: Nov 23, 2011, Olvasva: 33097, Oldal olvasási idő: kb. 3 perc
Lapozás: OK   10 / 12

Jöjjenek hát a megszakítások. Mint már említettem a program memória elején van a megszakítás tábla. A megszakítás forrásától függ, hogy ezen a táblán hova fog ugrani. Úgy van megcsinálva a tábla, hogy a megszakításhoz egy ugró utasítást tudunk tenni, és ez még nem lóg bele a másik memória területre, ami a másik forrásé. Így olyan hosszú megszakítási rutint írhatunk, amit nem szégyellünk. Alábbi program annyit csinál, hogy ha az INT1 lábon történik valamilyen változás, akkor megszakít, és a B port 0. lábát negáljuk.

  1. .include "m16Adef.inc"
  2. .org 0x0000
  3.     jmp init
  4.  
  5. .org INT1addr
  6.     jmp interrupt
  7.  
  8. .org 0x002A
  9.  
  10. interrupt:
  11.     sbic PORTB, 0
  12.     jmp loop
  13.     sbi PORTB, 0
  14.     reti
  15. loop:
  16.     cbi PORTB, 0
  17.     reti
  18.  
  19. init:
  20.     ldi r21, HIGH(RAMEND)
  21.     out SPH, r21
  22.     ldi r21, LOW(RAMEND)
  23.     out SPL, r21
  24.     sbi DDRB, 0
  25.     ldi r21, (1<<ISC10) ; ezzel csak az ISC10 állítjuk be
  26.     out MCUCR, r21
  27.     ldi r21, (1<<INT1)
  28.     out GICR, r21
  29.     sei
  30.  
  31. main:
  32.     jmp main ; ez pedig azért kell, hogy legyen honnan megszakítani

Visszatérve az include fájlhoz, ebben tulajdonképpen csak rövidítések vannak. Ha a legvégét megnézzük, akkor ott találjuk a megszakításokhoz használt azonosításokat. Használjuk bátran ezeket (és az ez előtt lévőket is), mert olvashatóbbá teszi a programunkat.

Most viszont használjuk az SRAM-t, és fibonacci számokkal írjuk teli. Fibonacci sorozat abból áll, hogy az első két eleme 0, és 1, majd a következő mindig az előző két elem összege lesz.

  1. .include "m16Adef.inc"
  2.  
  3. .def F1=r25 ; olvashatóbb formára definiáljuk a regiszter nevét
  4. .def F2=r24
  5. .def temp=r23
  6. .def cyc=r22
  7.  
  8. .org 0x0000
  9.     jmp init
  10.  
  11. .org 0x002A
  12. init:
  13.     ldi r27, 0x00
  14.     ldi r26, 0x60 ; innen indul az SRAM
  15.     ldi F1, 0
  16.     ldi F2, 1
  17.     st X+, F1
  18.     ldi cyc, 13
  19.  
  20. loop:
  21.     mov temp, F1
  22.     add F1, F2
  23.     mov F2, temp
  24.     st X+, F1
  25.     dec cyc
  26.     brne loop
  27.  
  28. end:
  29.     jmp end

.def szintén egy direktíva. Ezzel regisztereket nevezhetünk el könnyebben megjegyezhető formává. Ennek az algoritmusnak eme formája csak erős megkötésekkel működik. Hiszen gondoljunk bele ez csak 8 biten képes ábrázolni, ami maximálisan 255 lehet. Természetesen, ha más elgondolás alapján csináljuk, akkor ki lehet ezt bővíteni 16 bitre, vagy akár 32 bitre is.

Végül egy "komolyabb" algoritmust mutatok be, még pedig a buborék rendezés. Mint tudjuk ez úgy működik, hogy összehasonlítja az első két elemet, majd ha nincs jó sorrendben akkor cseréli. Majd ugrik a második és harmadikra. Ha nincs jó sorrendben akkor cseréli. Egészen el megy a végéig, majd ismét elkezdi előröl, és csinálja egészen addig, amíg csere nélkül végig tud futni. Ez alábbi program pontosan ezt csinálja. 4 elemet képes rendezni, de ha cyc-t nagyobbra írjuk, akkor többet is. Már a szimulációs lapon említve lett a Toggle Memory Window. Erre szükségünk lesz, és az első négy elemét írjuk át random számokra. Végül mehet a próba.

  1. .include "m16Adef.inc"
  2.  
  3. .def temp=r20
  4. .def data1=r21
  5. .def data2=r22
  6. .def cyc=r19
  7.  
  8. .org 0x0000
  9.     jmp init
  10.  
  11. .org 0x002A
  12. init:
  13.     ldi XH, 0x00 ; XH mint regiszter az inc-ben már benne van
  14.     ldi XL, 0x60
  15.     ldi YH, 0x00
  16.     ldi YL, 0x60
  17.     ldi cyc, 3 ; ha ezt növeljük, akkor több elemet képes rendezni
  18.     set
  19.     jmp main
  20.  
  21. smaller:
  22.     mov temp, data1
  23.     mov data1, data2
  24.     mov data2, temp
  25.     st Y+, data1
  26.     st Y, data2
  27.     clt
  28.     jmp loop
  29.  
  30. main:
  31.     ld data1, X+
  32.     ld data2, X
  33.     cp data2, data1
  34.     brlt smaller
  35.     inc YL
  36. loop:
  37.     dec cyc
  38.     brne main
  39.     brtc init
  40.  
  41. end:
  42.     jmp end

Ez már túl bonyolult ahhoz, hogy csak úgy bemásoljam leírás nélkül. Init-ben történik meg a regiszterek inicializálása, értelemszerűen. Ennek  mindig le kell futnia, ha a program az adatsor végére ért, hogy az adatsor elején kezdhesse előröl. Main-ben történik meg a soron következő két elem kiolvasása, majd az összehasonlítása. Csak akkor kell tennünk valamit, ha a komparálás eredménye azt hozza ki, hogy kisebb. Ekkor a smaller fut le, ahol kicseréli a két adatot, és visszaírja az SRAM-ba. Az, hogy mikor lettek az adatok sorba rendezve, az a T bit segítségével derül ki. Minden újra kezdésnél "1"-be állítom a T bitet, és ha történik csere, akkor törlöm, ha nem történik egyszer sem, akkor a program végén a brtc branch tovább fogja engedi, és vége. Sorba lett rendezve, még ha ez a legbutább algoritmussal is történt.


A cikk még nem ért véget, lapozz!
Következő: »»   10 / 12
Értékeléshez bejelentkezés szükséges!
Bejelentkezés

Belépés

Hirdetés
Lapoda.hu     XDT.hu     HEStore.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem