mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Anfänger mit Problemen - Atmega48 & Assemblercode


Autor: Pascal Knies (Firma: MHK) (pascal2002)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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_Checkl...
Interrupt

Hehe, böser Fehler. Probiers mal so.

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

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

Siehe Bitmanipulation.

MFG
Falk

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Ersetze mal 'sbr temp, RXCIE0' durch 'sbr temp, 1<<RXCIE0' und 'sbr 
temp1, RXEN0' durch 'sbr temp1, 1<<RXEN0'

'sbr' erwartet eine Bitmaske, keine Bitnummer.

MfG Spess

Autor: Pascal Knies (Firma: MHK) (pascal2002)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
habs geändert, passiert aber trotzdem nichts. :(

mit einem basic code gehts einwandfrei


EDIT: jetzt geht es, allerdings so das bei 0 die LED leuchtet anstatt 
bei 1

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Pascal Knies (Firma MHK) (pascal2002)

>EDIT: jetzt geht es, allerdings so das bei 0 die LED leuchtet anstatt
>bei 1

Logisch, die werden ja auch LOW aktiv angesteuert.

MFG
Falk

Autor: Pascal Knies (Firma: MHK) (pascal2002)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
naja eigentlich will ich es aber anderstrum ^^

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Pascal Knies wrote:
> naja eigentlich will ich es aber anderstrum ^^

Dann drehs halt um. Wo liegt das Problem?

Autor: Pascal Knies (Firma: MHK) (pascal2002)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Ja. Oder du tauscht die Befehle 'cbi PORTB, 0' und 'sbi PORTB, 0'.

MfG Spess

Autor: Pascal Knies (Firma: MHK) (pascal2002)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Pascal Knies (Firma: MHK) (pascal2002)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 wrote:
> Hi
>
> Ja. Oder du tauscht die Befehle 'cbi PORTB, 0' und 'sbi PORTB, 0'.
>
> MfG Spess

ah danke....habe es auch gerade gemerkt ^^

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.