USART in Assembler

OP #2947718
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
#2948150
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.
OP #2948160
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.

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