Hallo!
Ich beschäftige mich gerade mit der Adressierung der Speicherbereiche
bei Atmega8. Ich habe dazu ein sehr kurzes Assembler Programm
geschrieben, wo mehrere Zeichen per UART vom PC empfangen und im SRAM
abgegelegt werden. Gleich danach werden die gleichen Zeichen aus dem
SRAM abgelesen und wieder per UART an PC gesendet.
Das Problem ist jetzt - die beiden letzten Zeichen sind nicht die, die
am Anfang gesendet worden sind. Egal was für eine Zahl ich bei "counter"
eingebe und viel mehr Zeichen im SRAM speichere. Die letzten beiden
bleiben immer mit Fehlern.
Hoffentlich kann einer mir helfen oder wenigstens ein Tipp geben.
Vielleicht ist die Sache viel einfacher als ich denke!
Hier ist mein Code:
1
.include "m8def.inc"
2
3
.def temp = r16
4
.def counter = r17
5
6
.DSEG
7
8
var1: .BYTE 22
9
10
11
.CSEG
12
anfang:
13
ldi counter,5 ; 5 Zeichen uf einmal senden
14
15
ldi temp, HIGH(23) ; UBRR = 23 bei Baud 9600 und
16
out UBRRH, temp ; F_CPU = 3686400 Hz
17
18
ldi temp, LOW(23)
19
out UBRRL, temp
20
21
ldi temp, (1<<URSEL) | (1<<UCSZ0) | (1<<UCSZ1)
22
out UCSRC, temp ; 8 bit Uebertragung
23
24
sbi UCSRB, TXEN ; Empfaenger und Sender freischalten
Zuvor hat die UART-Verbindung bei mir super funktioniert. Der Fehler
tritt nur dann auf, wenn ich die Daten im SRAM speichere! Vielen Dank
schon mal im vorraus!
MfG
Kerik
Das Programm ist komisch. Spontan frage ich mich nach dem Sinn dieser
Zeilen:
ldi temp, HIGH(23) ; UBRR = 23 bei Baud 9600 und
out UBRRH, temp ; F_CPU = 3686400 Hz
ldi temp, LOW(23)
out UBRRL, temp
Und warum die Stackinitialisierung so spät gemacht wird. Das sieht eher
nach einem zusammengestückelten Werk aus zwei Quellen aus als nach einem
wohlüberlegten Programmablauf.
Helfer schrieb:> Das Programm ist komisch. Spontan frage ich mich nach dem Sinn dieser> Zeilen:>> ldi temp, HIGH(23) ; UBRR = 23 bei Baud 9600 und> out UBRRH, temp ; F_CPU = 3686400 Hz>> ldi temp, LOW(23)> out UBRRL, temp
Hier wird der UART Baud Rate Register initialisiert. Bei einer BAUD von
9600 und dem Takt 3686400 beträgt der Wert 23.
Das kommt aus der Gleichung F_CPU/(16*BAUD)-1
Helfer schrieb:> Und warum die Stackinitialisierung so spät gemacht wird.
Weil der Stackpointer vorher nicht gebraucht wird. Ist doch egal wo man
den initialisiert, sobald das vor der ersten Benutzung gemacht wird,
oder irre ich mich da?
Das Programm wurde wirklich nur dazu geschrieben, um SRAM-Adressierung
und UART Benutzung zu praktizieren. Mittlerweile bin ich etwas weiter -
ich habe zum Test einfach eine Verzögerung von mehreren Milisekunden in
die Loop-Schleife eingebaut und jetzt kriege ich alle Zeichen richtig
angezeigt. Die Lösung ist also da, aber wieso das so ist, verstehe ich
immer noch nicht.
MfG
Kerik
Hallo!
Wenn Du nach
out UDR, temp
sofort
ret
machst und nicht wartest bis alle Zeichen auch wirklich gesendet sind,
sondern gleich wieder auf Anfang springst, wird dem UART Senderegister
und dem Schieberegister der "Hals abgedreht"
Oder anders: Das vorletzte Zeichen ist noch im Schieberegister das
letzte im UDR und du springst auf anfang und initialisierst den UART
neu. Du musst im Programm UP oder zwischen diesen Zeilen
brne loop ;Beide Pointer gleich? -> dann
fertig
rjmp anfang
warten, bis das letzte Zeichen raus ist, und dann erst auf anfang
springen.