Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Direttiva .org AVR assembly (atmega8535)

Tipologie, strumenti di sviluppo, hardware e progetti

Moderatore: Foto UtentePaolino

0
voti

[11] Re: direttiva .org avr assembly (atmega8535)

Messaggioda Foto UtenteRabeluk » 22 mag 2013, 20:28

forse sul fatto che moltiplica x 2 ci sono arrivato,
per il motivo che usando lpm Z va a puntare ai byte mentre essendo interessati a word la quinta word dovrebbe trovarsi presso il decimo byte..... spero di non aver sbagliato :D
Avatar utente
Foto UtenteRabeluk
116 1 4 9
Sostenitore
Sostenitore
 
Messaggi: 765
Iscritto il: 30 gen 2011, 22:26

0
voti

[12] Re: direttiva .org avr assembly (atmega8535)

Messaggioda Foto Utentesimo85 » 22 mag 2013, 20:30

Rabeluk ha scritto:solo quando scrive .org non capisco che vuol dire....


Dirlo prima? :?

Una spiegazione riguardo la direttiva ORG la trovi in questa bellissima, semplice ed esplicita AN della ATmel.
Avatar utente
Foto Utentesimo85
30,9k 7 12 13
Disattivato su sua richiesta
 
Messaggi: 9927
Iscritto il: 30 ago 2010, 4:59

0
voti

[13] Re: direttiva .org avr assembly (atmega8535)

Messaggioda Foto UtenteRabeluk » 22 mag 2013, 20:32

ce l'ho quella guida ma sempre che non capisco come la usa nel programma ... boh mi sarò rincretinito io
Avatar utente
Foto UtenteRabeluk
116 1 4 9
Sostenitore
Sostenitore
 
Messaggi: 765
Iscritto il: 30 gen 2011, 22:26

0
voti

[14] Re: direttiva .org avr assembly (atmega8535)

Messaggioda Foto UtenteRabeluk » 22 mag 2013, 20:49

scrivere qui è illuminante :D forse ci sono arrivato per davvero ahah
per sicurezza se qualcuno conferma la mia teoria mi farebbe piacere :D

il 13 è esadecimale quindi sarebbe 19 in decimale... però dovrebbero essere indirizzi di word e non di byte... quindi in pratica sarebbe il 38esimo byte.... quindi la look up table si trova a partire da li

quindi prima di arrivare alla prima istruzione di lpm scorrono 38 (26 in esadecimale) indirizzi che aggiunti al valore attuale di ZLx2 (per avere indirizzo di byte) mi da il valore che sto cercando... considerando il fatto che con .dw le word hanno i bit meno significatifi sul byte + basso prendo proprio quello per prima e poi incrementando ZL di 1 riesco a prendere il byte + significativo che si trova sotto quello preso in precedenza... c'ho azzeccato=?
Avatar utente
Foto UtenteRabeluk
116 1 4 9
Sostenitore
Sostenitore
 
Messaggi: 765
Iscritto il: 30 gen 2011, 22:26

0
voti

[15] Re: direttiva .org avr assembly (atmega8535)

Messaggioda Foto Utentesimo85 » 22 mag 2013, 21:01

La direttiva org setta la posizione del del Program Counter.

Se ci fai caso, la direttiva

Codice: Seleziona tutto
org 0x13


è alla linea 19 del programma (appunto la posizione di memoria). Questo vuol dire che quando il programma arriva ad eseguire la direttiva, passa a LookUPTable.

Giusto per interesse lo stavo commentando, (dato che i programmi vanno sempre commentati :?) però ora devo scappare, puoi continuare tu, così magari ci capiamo meglio tutti e 2 (e non solo)?

Codice: Seleziona tutto
Declaration

.def temo=r16
.def NoteL=r19
.def NoteH=r23
.def Length=r20
.def address=21

;Start of Program

    rjmp init       ; PC jumps to init
    reti            ; Interrupt return
    reti            ; Interrupt return
    reti            ; Interrupt return
    rjmp ToggleOut  ; PC jumps to ToogleOut function
    reti            ; Interrupt return
    rjmp ChangeNote ; PC jumps to ChangeNote function

    .org 0x13       ; Set PC to 0x13

LookUPTable:
   
    .dw  0xecb
    .dw   ....
    .dw   ...
    .dw   ...
    .dw   ...
    .dw   ...
    .dw   ..   
    .dw   ...
    .dw   ...
    .dw   ...
    .dw   ....
    .dw   ...

ToggleOut:

    in temp,PortD   ; Input value from PORTD in temp
    com temp        ; One's complement of temp
    out PortD,temp  ; Output value from temp to PORTD
    reti            ; Interrupt return

ChangeNote:
   
    dec Length      ; Decrement Lenght by 1
    breq PC+2       ; Increment PC by 2 if ...
    reti

Rest:
   
    in temp,TIFR    ; Input from TIFR register
    sbrs temp,1     
    rjmp Rest
    ldi temp,0b00000010
    out TIFR,temp
    Read_EEprom:
    out EEARL,address
    sbi EECR,0

    in ZL,EEDR

    andi ZL, 0b00001111

    cpi ZL,0x0C
    breq Reset
    brlo PC+2
    ldi ZL,0x0B

    lsl ZL
    subi ZL,-0x26
    lpm
    mov NoteL,R0
    inc ZL
    lpm
    mov NoteH,R0
Avatar utente
Foto Utentesimo85
30,9k 7 12 13
Disattivato su sua richiesta
 
Messaggi: 9927
Iscritto il: 30 ago 2010, 4:59

4
voti

[16] Re: direttiva .org avr assembly (atmega8535)

Messaggioda Foto UtenteDirtyDeeds » 22 mag 2013, 22:37

simo85 ha scritto:La direttiva org setta la posizione del del Program Counter.


Uhm, non è proprio così. Normalmente, la direttiva .org definisce la posizione in memoria della successiva porzione di codice. In questo caso dovrebbe far sì che LookUPTable cominci alla locazione 0x13.

E' una direttiva che può essere usata per allocare codice o dati a partire da precise locazioni di memoria. Per esempio, nel vecchio PIC 16c74a la routine di interrupt doveva cominciare obbligatoriamente all'indirizzo 0x004. Questo qui sotto è allora un pezzo di un programma in assembler che avevo scritto che fa in modo che la routine di interrupt venga proprio allocata a partire da quell'indirizzo (in realtà, è una porzione di codice abbastanza standard: salva il contesto, chiama l'effettiva interrupt service routine e all'uscita ripristina i registri):

Codice: Seleziona tutto
      ORG     0x004           ; interrupt vector location
      movwf   w_temp          ; save off current W register contents
      movf   STATUS,w        ; move status register into W register
      bcf       STATUS,RP0      ; ensure file register bank set to 0
      movwf   status_temp     ; save off contents of STATUS register

      call   isr

      bcf     STATUS,RP0      ; ensure file register bank set to 0
      movf    status_temp,w   ; retrieve copy of STATUS register
      movwf   STATUS          ; restore pre-isr STATUS register contents
      swapf   w_temp,f
      swapf   w_temp,w        ; restore pre-isr W register contents
      retfie                  ; return from interrupt


Quando l'interrupt viene chiamato il processore salta alla locazione 0x004 e continua l'esecuzione a partire dall'istruzione

Codice: Seleziona tutto
movwf   w_temp
It's a sin to write sin instead of \sin (Anonimo).
...'cos you know that cos ain't \cos, right?
You won't get a sexy tan if you write tan in lieu of \tan.
Take a log for a fireplace, but don't take log for \logarithm.
Avatar utente
Foto UtenteDirtyDeeds
55,9k 7 11 13
G.Master EY
G.Master EY
 
Messaggi: 7012
Iscritto il: 13 apr 2010, 16:13
Località: Somewhere in nowhere

0
voti

[17] Re: direttiva .org avr assembly (atmega8535)

Messaggioda Foto Utentesimo85 » 22 mag 2013, 23:03

DirtyDeeds ha scritto:E' una direttiva che può essere usata per allocare codice o dati a partire da precise locazioni di memoria. Per esempio, nel vecchio PIC 16c74a la routine di interrupt doveva cominciare obbligatoriamente all'indirizzo 0x004.


Perché nei PIC, per esempio anche nel PIC16F887 e molti altri, 0x004 è la direzione di memoria dell' interrupt vector.

Bisogna appunto far "saltare" il program counter a quella direzione di memoria altrimenti l'interrupt non viene eseguita.
Avatar utente
Foto Utentesimo85
30,9k 7 12 13
Disattivato su sua richiesta
 
Messaggi: 9927
Iscritto il: 30 ago 2010, 4:59

6
voti

[18] Re: direttiva .org avr assembly (atmega8535)

Messaggioda Foto UtenteDirtyDeeds » 22 mag 2013, 23:12

simo85 ha scritto:Bisogna appunto far "saltare" il program counter


No, attenzione: la direttiva .org non c'entra nulla col program counter: il PC è un registro del micro e non è influenzato dalla direttiva .org. Tale direttiva è un'istruzione per l'assemblatore che dice: prendi tutto il codice che segue e posizionalo a partire da tale locazione.

Considera questo pseudocodice:

Codice: Seleziona tutto
.org 0x0000
istruzione 1
istruzione 2

.org 0x1000
istruzione 3


Se tu assemblassi un codice simile e lo eseguissi, il micro eseguirebbe prima istruzione1, poi istruzione2, ma poi non salterebbe a istruzione3 (perché non viene modificato il PC), bensì eseguirebbe tutta l'immondizia (perché locazioni non definite) che c'è tra le locazioni 0x0002 e 0x0fff.
It's a sin to write sin instead of \sin (Anonimo).
...'cos you know that cos ain't \cos, right?
You won't get a sexy tan if you write tan in lieu of \tan.
Take a log for a fireplace, but don't take log for \logarithm.
Avatar utente
Foto UtenteDirtyDeeds
55,9k 7 11 13
G.Master EY
G.Master EY
 
Messaggi: 7012
Iscritto il: 13 apr 2010, 16:13
Località: Somewhere in nowhere

0
voti

[19] Re: direttiva .org avr assembly (atmega8535)

Messaggioda Foto Utentesimo85 » 22 mag 2013, 23:20

Foto UtenteDirtyDeeds, ora non posso andare più a fondo anche perché il lavoro mi chiama.

Appena ho tempo, dato che è parecchio che non apro MPLAB o avr-gdb, vedo di fare un debug così siamo tutti più contenti. :mrgreen:
Avatar utente
Foto Utentesimo85
30,9k 7 12 13
Disattivato su sua richiesta
 
Messaggi: 9927
Iscritto il: 30 ago 2010, 4:59

5
voti

[20] Re: direttiva .org avr assembly (atmega8535)

Messaggioda Foto UtenteDirtyDeeds » 22 mag 2013, 23:32

simo85 ha scritto:Appena ho tempo, dato che è parecchio che non apro MPLAB


Fidati che è così, in assembler ci ho programmato parecchio ;-)

Incidentalmente ho ancora l'output dell'assemblatore per il codice che ti ho scritto sopra, vediamolo:

Codice: Seleziona tutto
0000                00073                 ORG     0x000
0000 018A           00074                 clrf    PCLATH
0001 280F           00075                 goto    main
                    00076
                    00077
0004                00078                 ORG     0x004
0004 00A0           00079                 movwf   w_temp
0005 0803           00080                 movf    STATUS,w
0006 1283           00081                 bcf     STATUS,RP0
0007 00A1           00082                 movwf   status_temp
                    00083
                    00084
0008 20EE           00085                 call    isr
                    00086
                    00087
0009 1283           00088                 bcf     STATUS,RP0
000A 0821           00089                 movf    status_temp,w
000B 0083           00090                 movwf   STATUS
000C 0EA0           00091                 swapf   w_temp,f
000D 0E20           00092                 swapf   w_temp,w 
000E 0009           00093                 retfie


La prima colonna di numeri rappresenta l'indirizzo di memoria dell'istruzione; la seconda colonna rappresenta l'opcode; la terza, la linea di programma, ma non ci interessa. Il programma inizia con ORG 0x0000: questa non è un'istruzione, infatti non viene generato codice (se guardi, in corrispondenza di ORG 0x0000 non c'è l'opcode). In 0x0000 viene posizionata l'istruzione che segue la direttiva ORG:

Codice: Seleziona tutto
0000 018A           00074                 clrf    PCLATH


L'istruzione successiva, in 0x0001, è "goto main"; dopo questa, c'è di nuovo una direttiva ORG: nota che anche lì non viene generato l'opcode, ma l'istruzione successiva inizia proprio da 0x0004:

Codice: Seleziona tutto
0004 00A0           00079                 movwf   w_temp


Se non ci fosse stata l'istruzione goto main in 0x0001, il programma avrebbe eseguito anche il codice -indefinito!- che c'è alle locazioni 0x0002 e 0x0003, per poi continuare a eseguire la isr (anche se non chiamata).
It's a sin to write sin instead of \sin (Anonimo).
...'cos you know that cos ain't \cos, right?
You won't get a sexy tan if you write tan in lieu of \tan.
Take a log for a fireplace, but don't take log for \logarithm.
Avatar utente
Foto UtenteDirtyDeeds
55,9k 7 11 13
G.Master EY
G.Master EY
 
Messaggi: 7012
Iscritto il: 13 apr 2010, 16:13
Località: Somewhere in nowhere

PrecedenteProssimo

Torna a Realizzazioni, interfacciamento e nozioni generali.

Chi c’è in linea

Visitano il forum: Nessuno e 7 ospiti