Anfänger mit Problemen - Atmega48 & Assemblercode

OP (Firma: MHK) #739034
Lesenswert?

Wir haben in der Schule ein Board mit einem Atmega48.

Dazu soll ich, bzw. darf ich ein kleines Programm schreiben, das die
Funktion des UART im Atmega48 veranschaulichen soll. Ich hab mir dazu
einfach den Code aus dem Tutorial genommen und mal ganz treudoof
assembliert. Da es dann logischerweise Fehler gab, da der Code im
Tutorial für ein Atmega8 ist, habe ich dann auch noch erkannt.
Allerdgins bin ich mir nicht sicher, ob meine "Anpassungen" so richtig
sind. Wenn ich das ganze ausprobieren will, passiert nix.

Ich habe das Programm AVR-Stduio 4 und wollte den Beispielcode (Anhang)
benutzen:

.include "m48def.inc"

.def temp = R16
.def temp1 = R17

.equ F_CPU = 8000000        ; Systemtakt in Hz
.equ BAUD  = 9600           ; Baudrate

; Berechnungen
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille

.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille
Fehler
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit
zu hoch!"
.endif


.org 0x00
        rjmp main

.org URXCaddr
        rjmp int_rxc

; Hauptprogramm
main:
        ldi temp, LOW(RAMEND)
        out SPL, temp
        ldi temp, HIGH(RAMEND)
        out SPH, temp

        ldi temp, 0xFF                    ; Port B = Ausgang
        out DDRB, temp

        ; Baudrate einstellen
        ldi temp, HIGH(UBRR_VAL)
        sts UBRR0H, temp
        ldi temp, LOW(UBRR_VAL)
        sts UBRR0L, temp

        ; Frame-Format: 8 Bit
        ldi temp, (3<<USBS0)|(1<<UCSZ00)
        sts UCSR0C, temp

     lds temp, UCSR0B          ; Interrupt bei Empfang
    sbr temp, RXCIE0
        sts UCSR0B, temp

    lds temp1, UCSR0B                 ; RX (Empfang) aktivieren
        sbr temp1, RXEN0
    sts UCSR0B, temp1

    sei                               ; Interrupts global aktivieren

loop:   rjmp loop                         ; Endlosschleife

; Interruptroutine: wird ausgeführt sobald ein Byte über das UART
empfangen wurde
int_rxc:
        push temp                         ; temp auf dem Stack sichern

        lds temp, UDR0
        cpi temp, '1'                     ; empfangenes Byte mit '1'
vergleichen
        brne int_rxc_1                    ; wenn nicht gleich, dann zu
int_rcx_1
        cbi PORTB, 0                      ; LED einschalten
        rjmp int_rxc_2                    ; Zu int_rxc_2 springen
int_rxc_1:
        cpi temp, '0'                     ; empfangenes Byte mit '0'
vergleichen
        brne int_rxc_2                    ; wenn nicht gleich, dann zu
int_rcx_2
        sbi PORTB, 0                      ; LED ausschalten
int_rxc_2:
        pop temp                          ; temp wiederherstellen
        reti



Das Programm soll ein Signal das seriell über eine Terminalsoftware
gesendet wird, auswerten und der Atmega soll eine LED schalten, je nach
Zustand.


Vielen Dank im Voraus.

Pascal
Angehängte Dateien:
#739057
Lesenswert?

@  Pascal Knies (Firma MHK) (pascal2002)

>Dazu soll ich, bzw. darf ich ein kleines Programm schreiben, das die
>Funktion des UART im Atmega48 veranschaulichen soll. Ich hab mir dazu
>einfach den Code aus dem Tutorial genommen und mal ganz treudoof
>assembliert.

Ist ja erstmal nicht verwerflich ;-)

>Allerdgins bin ich mir nicht sicher, ob meine "Anpassungen" so richtig
>sind. Wenn ich das ganze ausprobieren will, passiert nix.

AVR-Tutorial: UART
http://www.mikrocontroller.net/articles/AVR_Checkliste#UART.2FUSART
Interrupt

Hehe, böser Fehler. Probiers mal so.

1
     lds temp, UCSR0B          ; Interrupt bei Empfang
2
     sbr temp, (1<<RXCIE0)
3
     sts UCSR0B, temp
4

5
     lds temp1, UCSR0B                 ; RX (Empfang) aktivieren
6
     sbr temp1, (1<<RXEN0)
7
     sts UCSR0B, temp1

Siehe Bitmanipulation.

MFG
Falk
OP (Firma: MHK) #739101
Lesenswert?

hmm.....irgendwie bin ich zu doof dafür ^

muss ich da nicht einfach die zwei zeilen:

cpi temp, '1'                     ; empfangenes Byte mit '1' vergleichen

cpi temp, '0'                     ; empfangenes Byte mit '0' vergleichen


umschrieben, das es so aussieht?

cpi temp, '0'                     ; empfangenes Byte mit '1' vergleichen

cpi temp, '1'                     ; empfangenes Byte mit '0' vergleichen


mfg
p.knies
OP (Firma: MHK) #739106
Lesenswert?

habs gefunden, was es war.
hab jetzt sbi und cbi getauscht.


int_rxc:
   push temp                         ; temp auf dem Stack sichern

   lds temp, UDR0
   cpi temp, '1'                     ; empfangenes Byte mit '1' 
vergleichen
   brne int_rxc_1                    ; wenn nicht gleich, dann zu 
int_rcx_1
   sbi PORTB, 0                      ; LED einschalten
   rjmp int_rxc_2                    ; Zu int_rxc_2 springen

int_rxc_1:
   cpi temp, '0'                     ; empfangenes Byte mit '0' 
vergleichen
   brne int_rxc_2                    ; wenn nicht gleich, dann zu 
int_rcx_2
   cbi PORTB, 0                      ; LED ausschalten

int_rxc_2:
   pop temp                          ; temp wiederherstellen
   reti

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren