Fórum témák

» Több friss téma
Cikkek » Távirányító jelének fogadása uC-vel
Távirányító jelének fogadása uC-vel
Szerző: lazsi, idő: Ápr 12, 2010, Olvasva: 18673, Oldal olvasási idő: kb. 4 perc
Lapozás: OK   4 / 6

Talán sokakat visszariaszt az assembly programírástól az a tény, hogy mindenre gondosan oda kell figyelni, de szerintem így alaposabban megismerhető a processzor. Előbb-utóbb mindenki találkozik olyan feladattal, aminek a megoldása sokkal körülményesebb valamilyen magas-szintű nyelven. Talán mások is bátorságot merítenek abból, ha lépésről lépésre elmagyarázom a program működését. A letölthető program AVR Studio segítségével készült, oda egyszerűen ctrl-c - ctrl-v segítségével bemásolható.Elérhető .HEX formátumban is.

Ezen az oldalon a kezdeti beállítások és a PC-s kapcsolat rutinjai vannak, a következőn a távirányítót kezelő megszakítások.

.include "tn2313def.inc"

  • Ez a külső file tartalmazza az ATTiny2313 gyári definícióit. Az AVR Studio tartalmazza, csak a megfelelő elérési utat meg kell adni.

.def    felbit    =r0
.def    vettbyteL    =r1
.def    vettbyteH    =r2
;.def        =r3
;.def        =r4
;.def        =r5
;.def        =r6
;.def        =r7
;.def        =r8
;.def        =r9
;.def        =r10
;.def        =r11
;.def        =r12
;.def        =r13
;.def        =r14
;.def        =r15
.def    vetel    =r16
.def    kuldeni    =r17
.def    valtozo    =r18
.def    IT_valtozo    =r19
.def    IT_valtozo2    =r20
.def    bitek    =r21
;.def        =r22
;.def        =r23
;.def        =r24
;.def        =r25

  • A 26 felhasználható regiszter közül 9-et használok. A definiálás célja, hogy ne keverjem össze őket. A nem használt regiszterek megjegyzésként maradnak.

rjmp    RESET
rjmp    EXT_INT0
rjmp    EXT_INT1
rjmp    T1_CAPT1
rjmp    T1_COMPA
rjmp    T1_OVF
rjmp    T0_OVF
rjmp    UART_RX
rjmp    UART_UDRE
rjmp    UART_TX
rjmp    ANA_COMP
rjmp    PCINT
rjmp    T1_COMPB
rjmp    T0_COMPA
rjmp    T0_COMPB
rjmp    USI_START
rjmp    USI_OVF
rjmp    EE_READY
rjmp    WDT_OVF

  • Ha megszakítás érkezik, ezekre a címekre ugrik. Amelyiket nem használom, ahhoz egyszerűen egy RETI utasítást rendelek, ezek a program végén találhatóak. Ha valamit később mégis használok, akkor ott (a program végén) megjegyzésbe kell tenni.

RESET:
ldi    valtozo, low(RAMEND)
out    SPL, valtozo

  • A megszakítások és szubrutinok visszatérési címét a veremben (stack) tároljuk. A verem visszafelé bővül, ezért kell a memória tetejére tenni.

ldi    valtozo, 13
out    MCUCR, valtozo

  • Beállítom, hogy a külső megszakítás bemenet (EXT_INT0) minden élre aktív legyen. A másik külső megszakítás bemenet (EXT_INT1) pozitív élre aktív, de azt nem használjuk.

ldi    valtozo, 64
out    GIMSK, valtozo

  • Engedélyezem az EXT INT0 megszakítást

in    valtozo, UCSRB
sbr    valtozo, 8+16+128
out    UCSRB, valtozo

  • Engedélyezem a soros adatátvitel adás (B_TXEN : 8) és vétel (B_RXEN : 16) funkcióit, valamint a vétel megszakítást (B_RXCIE : 128). A regiszter többi bitjét nem változtatom meg.

in    valtozo, UBRR
sbr    valtozo, 12
out    UBRR, valtozo

  • Beállítom az adatátvitel sebességét 19200-ra. Az USB miatt lehetne sokkal gyorsabb is, de ez a sebesség garantált az RS232 esetén is, szinte akármilyen vezetékkel. 4 MHz órajel esetén 19200 Baud -> 12, 9600 Baud -> 25

ldi    valtozo, 0           
out    TCCR0A, valtozo
out    TCCR0B, valtozo
out    TCNT0,    valtozo

  •  A 0. időzítő beállítása. Az időzítő előosztója nincs bekapcsolva, ezért az időzítő áll. A számláló értéke 0.

ldi    valtozo, 2
out    TIMSK, valtozo

  • Engedélyezem a 0. időzítő túlcsordulása esetén a megszakítást (T0 OVF).

cbi    DDRD,    2

  • A vevő kimenete a D port 2-es bitjére csatlakozik, ezért azt bemenetnek állítom be. Bár alapértelmezés szerint a bekapcsolás után minden port bemenetként definiált, jobb, ha ezt megerősítem.

ldi    valtozo, $60
mov    XL, valtozo
clr    XH   

  • A RAM elején ($60 címtől kezdve) fogja tárolni a soros porton kapott adatokat. Az X nevű két byte-os regisztert a vétel megszakítás használja. Az adatsort egy sorvége karakter zárja le, azt is tároljuk. (decimális: 13, hexa: 0x0D) Újabb üzenet felülírja az előzőt, ezért fel kell dolgozni következő érkezéséig. Ez a program nem kezeli.

ldi    kuldeni, 'S'
rcall    EGYBYTEKULD
ldi    kuldeni, 't'
rcall    EGYBYTEKULD
ldi    kuldeni, 'a'
rcall    EGYBYTEKULD
ldi    kuldeni, 'r'
rcall    EGYBYTEKULD
ldi    kuldeni, 't'
rcall    EGYBYTEKULD
rcall SORVEGE

  • Meghívja az EGYBYTEKULD és SORVEGE szubrutinokat.
  • Bejelentkezik, hogy a PC-n futó program tudjon róla. A soros porton elküldi a "Start" + $0A + $0D üzenetet. Itt küldhetne egyedi azonosítót is, de akár el is maradhat ez a pár sor.

sei

  • A megszakítás alapértelmezésben le van tiltva. Mivel végeztünk a kezdeti beállításokkal, most már engedélyezhetjük a megszakításokat.
  • Az eddigi rész bekapcsolás után, illetve szoftver vagy hardver RESET érkezésekor hajtódik végre.
  • Ezután kezdődik a főprogram

LOOP :
rjmp    LOOP

  • Ennyi a főprogramunk... Ez egy végtelen ciklus, vagyis jól elvan magában és semmit sem csinál. A ciklusból csak a megszakítás miatt lép ki, majd ide tér vissza utána.
  • Eddig tart a főprogram. Ezután következnek a megszakítások és az egyéb szubrutinok.

UART_RX:

  • Ez a megszakítás akkor következik be, ha a soros porton érkezett egy byte.
  • Ez a rutin használja az X és a "vetel" nevű regisztereket. Az X által mutatott memóriaterülettől kezdődően adatokat helyez el.

in    vetel,    SREG
push    vetel

  • Minden megszakítást illik úgy kezdeni, hogy az állapotregisztert elmentjük a verembe (stack). Ennek elmulasztása rejtélyes hibákat tud okozni...

in    vetel, UDR
st    X+, vetel

  • A vett byte-okat az X regiszter által mutatott helyen (kezdetben a memória eleje, $60 cím) tárolja. majd az X értékét egyel növeli, így a következő vett byte-ot a következő memóriahelyre teszi.

cpi    vetel, 13
breq FOGAD

  •  Ha a kapott byte értéke 13, akkor megérkezett a teljes üzenet, és azt fel kell dolgozni (FOGAD). Ha még nem, akkor várni kell a következő karakterre.

pop    vetel
out    SREG,    vetel
reti

  • Minden megszakításnak így kell véget érnie. A veremből visszatölti az állapotregisztert és kilép.
  • Ha nem sorvége érkezett, akkor itt van vége az UART_RX nevű megszakítás-rutinnak.

FOGAD:

  • Itt lenne a helye az üzenetet feldolgozó résznek. Ez a program nem erről szól, ezért itt most nincs semmi. A FOGADVEGE címkénél folytatódik.

FOGADVEGE :
ldi    vetel, $60
mov    XL, vetel
clr    XH

  • Visszaállítjuk az X mutatót a memória elejére ($60), vagyis felkészülünk a következő üzenet fogadására.

pop    vetel
out    SREG,    vetel
reti

  • Minden megszakításnak így kell véget érnie. A veremből visszatölti az állapotregisztert és kilép.
  • Ha sorvége érkezett, akkor itt van vége az UART_RX nevű megszakítás-rutinnak.
  • Az EGYBYTEKULD szubrutin a "kuldeni" nevű változóban lévő byte-ot elküldi soros porton a PC felé
  • Ez a rutin használja a "valtozo" nevű regisztert.

EGYBYTEKULD:
in    valtozo, USR
andi    valtozo, 32
breq    EGYBYTEKULD

  • Megnézi, hogy az adó adatregisztere üres-e. Ha nem, akkor visszaugrik az elejére, és ezt ismétli, amíg üres nem lesz a regiszter. Ezzel elkerüljük, hogy adáskor felülíródjon az előző adatunk, és így elvesszen.

out    UDR, kuldeni
ret

  • Ha végre megüresedett az adó adatregisztere, akkor bemásoljuk oda a küldendő tartalmat, és az adó automatikusan elküldi a soros porton. Ezután a szubrutin hívásának a helyétől folytatódik aprogram.
  • A SORVEGE szubrutin elküldi a "Kocsivissza" + "Soremelés" karaktereket (0x0A, 0x0D).
  • Ez a rutin használja a "kuldeni" nevű regisztert, és meghívja az EGYBYTEKULD nevű rutint.

SORVEGE:
ldi    kuldeni, 10
rcall    EGYBYTEKULD
ldi    kuldeni, 13
rcall    EGYBYTEKULD
ret

  • Kétszer meghívja az EGYBYTEKULD szubrutint, majd a szubrutin hívásának a helyétől folytatódik a program.
  • Sok PC-s program igényli, hogy egy üzenet "rendesen" legyen lezárva... 

A cikk még nem ért véget, lapozz!
Következő: »»   4 / 6
É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