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: 33223, Oldal olvasási idő: kb. 2 perc
Lapozás: OK   9 / 12

Mivel minden programindulás resettel indul, ezért magát a programot is innen kell indítani. Következő lépésként ezt írjuk be:

  1. .org 0x0000
  2.      jmp reset

.org egy direktíva, amellyel azt lehet megmondani, hogy az ezután lévő utasításokat a program memória melyik címére írja. Ez ebben az esetben nagyon fontos, mert a program memória elején a megszakítás tábla van. Amikor mi szeretnénk ezt a megszakítás táblát használni, akkor könnyen előfordulhat olyan, hogy egymásra írtuk a megszakítást, és a programunkat. Azt, hogy honnan kezdhetjük a programunkat, azt az adatlapban találhatjuk meg. Interrupts könyvjelző alatt találhatjuk meg. Atmega16A esetén 0x002A címről fog kezdődni a program. Jelen esetben mivel resetről van szó így alapértelmezetten minden uC-nél ennek a címe 0x0000.


Írjuk meg az első programunkat. Ez semmi mást nem fog csinálni, csak a B port minden lábát magas szintre emeli.

  1. .include "m16Adef.inc"
  2. .org 0x0000
  3.      jmp main
  4. .org 0x002A
  5. main:
  6.      ldi r19, 0xFF ; r19-be töltünk 255-t
  7.      out DDRB, r19 ; a B portot kimenetre állítjuk
  8.      out PORTB, r19 ; és magaszintre emeljük
  9. end:   ; hogy a program soha ne érjen véget, így szokták lezárni
  10.      jmp end

Ha az I/O View-ban rákattintunk a PORTB-re, akkor az alatta lévő ablakban megjelenik három regiszter. Itt nagyszerűen követhetjük, hogy hogyan tölti fel egymás után a regisztereket, de természetesen használható a Szimulációs részben leírtak is.

Következő program azt fogja csinálni, hogy az A port 0. bitjét figyeljük, és ha „0” szintű lesz, akkor az 1. biten ezt egy „1”-el jelezzük.

  1. .include "m16Adef.inc"
  2. .org 0x0000
  3.   jmp main
  4.  
  5. .org 0x002A
  6. main:
  7.   sbi DDRA, 1 ; A port 1. bit kimenet
  8.   sbi PORTA, 0 ; A port 0. bitjének a felhúzó ellenállás bekapcsolva
  9.  
  10. recovery:
  11.   cbi PORTA, 1
  12. loop:
  13.   sbis PINA, 0 ; figyeljük az adott lábat
  14.   jmp recovery  ; mivel már nem magas szintű ezért az A 1. bitjét visszeállítjuk alacsonyra.
  15.   sbi PORTA, 1
  16.   jmp loop ; mivel nem szeretnénk rögtön visszaállítani ezért a loopra ugrunk

Most pedig futófény következik.

  1. .include "m16Adef.inc"
  2. .org 0x0000
  3.     jmp main
  4.  
  5. .org 0x002A
  6. main:
  7.     ldi r20, 0xFF
  8.     out DDRC, r20
  9.     ldi r20, 1
  10.     out PORTC, r20
  11.  
  12. loop:
  13.     out PORTC, r20
  14.     rol r20
  15.     brcc loop
  16.     out PORTC, r20
  17.     rol r20
  18.     ldi r20, 1
  19.     jmp loop

Futófény, de úgy, hogy ha megnyomjuk a gombot akkor vált, és minden gombnyomáskor vált. Ehhez egy cselre lesz szükségünk, aminek a neve T bit.

  1. .include "m16Adef.inc"
  2. .org 0x0000
  3.     jmp main
  4.  
  5. .org 0x002A
  6.  
  7. main:
  8.     ldi r20, 0xFF
  9.     out DDRC, r20
  10.     ldi r20, 1
  11.     jmp loop
  12.  
  13. Tbitset:
  14.     clt
  15.     jmp left
  16.  
  17. change:
  18.     brts Tbitset
  19.     set
  20.     jmp right
  21.  
  22. loop:
  23.     sbic PINA, 0
  24.     jmp change
  25.     jmp right
  26.  
  27. beforeright:
  28.     ldi r20, 0x80
  29. right:
  30.     brtc left ; ha T=0 - bal, T=1 - jobb
  31.     out PORTC, r20
  32.     lsr r20
  33.     breq beforeright
  34.     jmp loop
  35.  
  36. beforeleft:
  37.     ldi r20, 1
  38. left:
  39.     out PORTC, r20
  40.     lsl r20
  41.     breq beforeleft
  42.     jmp loop

Eddigi kódok csak szimulációban működtek jól, hiszen a futófényből gyakorlatilag egy csíkot látunk, mert a szemünk nem tudja követni a gyorsaságot. Ezért alap időzítőt fogunk használni egy egyszerű programban. Ehhez szubrutin hívást fogunk alkalmazni, amihez pedig be kell állítani a stacket.

  1. .include "m16Adef.inc"
  2. .org 0x0000
  3.     jmp init
  4.  
  5. .org 0x002A
  6.  
  7. init:
  8.     ldi r21, HIGH(RAMEND)
  9.     out SPH, r21
  10.     ldi r21, LOW(RAMEND)
  11.     out SPL, r21 ; ezzel a négy sorral be van állítva a stack
  12.     sbi DDRB, 4
  13.     jmp main
  14.  
  15. subroutine: ; ez a mi kis időzítőnk egészen a RET-ig
  16.     clr r22
  17.     clr    r23
  18. loop:
  19.     dec r22
  20. loop1:
  21.     nop
  22.     dec r23
  23.     brne loop1
  24.     tst r22
  25.     brne loop
  26.     ret
  27.  
  28. main:
  29.     sbi PORTB, 4
  30.     rcall subroutine
  31.     cbi PORTB, 4
  32.     rcall subroutine
  33.     jmp main

Ha még ez is túl gyors lenne, akkor lehet még egy hurkot bele tenni a szubrutinba vagy még egy pár nop-t a legbelső ciklusba, ezzel meg van oldva.


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

Belépés

Hirdetés
XDT.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