Forum: Mikrocontroller und Digitale Elektronik USART in Assembler


von Phillip P. (cptzero)


Lesenswert?

Guten Abend,

ich möchte/muss eine USART Schnittstelle in Assembler programmieren, als 
IDE wird Eclipse verwendet.
Der Code steht bereits doch ich erhalte keine Ausgabe.
Zum Überprüfen lasse ich das Programm über den avrora Simulator laufen, 
der mir eigentlich den Wert im Datenregister ausgibt (UDR1).
Wäre super wenn ihr mir weiterhelfen könntet.
1
 #include <avr/io.h>
2
3
#ifndef F_CPU
4
#define F_CPU 4000000
5
#endif
6
7
8
.text
9
.global main
10
.global init_USART1
11
12
13
14
.set BAUD_RATE, 9600
15
.set UBRR_VAL, (F_CPU/16/BAUD_RATE)-1
16
17
 main:
18
19
    ; Stack einrichten
20
  ldi r17, lo8(RAMEND)
21
  sts  SPL, r17         ; Lade direkt Stack-Pointer-Low, r16
22
  ldi r17, hi8(RAMEND)
23
  sts  SPH, r17      ; Stack-Pointer-High
24
25
  ; Baudrate einstellen
26
  ldi    r17, hi8(UBRR_VAL)
27
  sts    UBRR1H, r17
28
  ldi    r17, lo8(UBRR_VAL)
29
  sts    UBRR1L, r17
30
31
   call init_USART1   ; Initialisierung USART
32
33
34
  call main_01    // Funktion zum Senden
35
36
37
38
 donothing:
39
   jmp donothing
40
41
42
43
init_USART1:
44
    push r17 ; Inhalt lokal genutzter Register retten
45
    push r18
46
47
48
49
50
    ; Sender und Empfänger einschalten
51
    ldi   r17, (1 << RXEN1)|(1<<TXEN1)  ; Empfänger=1, Sender=1
52
53
    // 2 Stop-Bits einrichten
54
    ldi r17, (1 << USBS1)
55
    lds r18, UCSR1C
56
    or r17, r18
57
    sts UCSR1C, r17
58
59
    pop r18 ; Inhalt lokal genutzter Register wiederherstellen
60
    pop r17
61
    ret ; return
62
63
 main_01:
64
65
66
   ldi r24, 0x65      // ASCII Wert für 'A' in Register r24 schreiben
67
68
69
while1:          // Endlosschleife!!
70
   call putc_USART1  // Läd 'A' aus Register 24 und verschickt es
71
jmp while1
72
73
   ret
74
75
76
77
putc_USART1:
78
  ; Sendet ein Byte (ASCII-Zeichen) über USART1.
79
  ; lokal genutze Register:
80
  ; r24
81
  ; Rückgabewert in Register: keiner
82
  push   r18
83
  push  r17        ; Inhalt von r17 auf dem Stack speichern
84
  lds    r17, SREG    ; Flag-Register einlesen
85
  push  r17        ; Flag-Register auf dem Stack speichern
86
87
88
wait_send:            ; auf freies Senderegister warten
89
  lds    r18, UCSR1A      ; Schreibe Inhalt von UCSR1A in r18
90
  andi   r18, (1 << UDRE1)   ; solange DataRegisterEmpty nicht 0 ist 
91
(nicht leer)
92
  breq   wait_send        ;
93
94
95
  sts   UDR1, r24    ; Daten senden - Lade Inhalt von r24 in UDR1
96
97
  pop   r17
98
  sts    SREG, r17    ; Lade Inhalt von r24 in SREG
99
  pop    r17        ; Inhalt von r24 wieder herstellen - aus Stack lesen
100
  pop   r18
101
102
  ret            ; return

von Spess53 (Gast)


Lesenswert?

Hi

Und um welchen Controller geht es?

MfG Spess

von r. (Gast)


Lesenswert?


von Phillip P. (cptzero)


Lesenswert?

Das Programm soll später mal auf einen ATMega128 aufgespielt werden, 
sofern es mit dem Simulator Avrora erfolgreich getestet wurde.

von Karl H. (kbuchegg)


Lesenswert?

>    ; Stack einrichten
>  ldi r17, lo8(RAMEND)
>  sts  SPL, r17         ; Lade direkt Stack-Pointer-Low, r16
>  ldi r17, hi8(RAMEND)
>  sts  SPH, r17      ; Stack-Pointer-High

Erst High, dann Low.

von Phillip P. (cptzero)


Lesenswert?

r. schrieb:
> Schau ...
> http://www.ibrtses.com/embedded/avrasmuartint.html

wie du an meinem Programmier-Stil oben sehen solltest, bin ich ein 
Assembler Anfänger und kann mit deinem Link relativ wenig anfangen ; )

von Karl H. (kbuchegg)


Lesenswert?

Hä?

  sts    SPL, r17
  sts    UBRR1H, r17
  sts    SREG, r17


ist es bei deinem Assembler wirklich so, dass du alle Register mit ihrem 
Namen über sts erreichen kannst? Unabhängig davon, ob sie mit out 
erreichbar wären oder nicht?

Das kommt mir jetzt ehrlich gesagt ein bischen komisch vor. Denn 
normalerweise muss man da höllisch aufpassen, welche Register per OUT 
angesprochen werden und welche per STS. Denn je nachdem ist die 
Adresslage eine andere.

von Phillip P. (cptzero)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Hä?
>
>   sts    UBRR1H, r17
>
>
> ist es bei deinem Assembler wirklich so, dass du alle Register mit ihrem
> Namen über sts erreichen kannst? Unabhängig davon, ob sie mit out
> erreichbar wären oder nicht?
>
> Das kommt mir jetzt ehrlich gesagt ein bischen komisch vor. Denn
> normalerweise muss man da höllisch aufpassen, welche Register per OUT
> angesprochen werden und welche per STS. Denn je nachdem ist die
> Adresslage eine andere.

Laut Prof. ist das so möglich.
Die Teile Stack einrichten, Baudrate einstellen und Sender und Empfänger 
einschalten wurden von einem funktionierenden Programm kopiert. Hier 
sollte also kein Fehler liegen.

von Phillip P. (cptzero)


Lesenswert?

Das Projekt hat sich soeben erledigt, desweiteren befinden sich nn 
meinem Beitrag / Code viele Fehler!


Bitte schließen bzw. löschen!!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Phillip Pressol schrieb:
> Bitte schließen bzw. löschen!!

Gelöscht wird hier nicht, und geschlossen hast du ihn mit diesem
Schlusswort ja selbst.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.