-
Seltsam, ich kann diese Art Formel so nirgends im Datasheet oder in unseren Wiki-Beispielen finden
Deine Formel:
UBRR_VAL = ((F_CPU+BAUD*8 )/(BAUD*16)-1) ; c
AVR-DataSheet PDF Formel:
UBRR = F_CPU / (16*BAUDRATE) - 1;
Versuch doch mal das, bestenfalls geht's auch nicht.
-
Das werde ich machen. Ich habe noch ein paar andere Dinge vor zu probieren.
Im Toturial heisst es mit dieser Formel wird gerundet.
"Beispiel: Bei einem ATMega mit 16MHz und 115200 Baud ist der Wert laut Datenblatt UBBRL=8. Rechnet man mit der Formel UBRRL=(F_CPU / (UART_BAUDRATE* 16L) - 1) ergibt sich ein Wert von 7,680555 und im UBRRL Register steht somit eine 7 statt einer 8. Die Verwendung der Formel aus dem Codebespiel ergibt 8.180555 und im UBRRL Register steht somit der richtige Wert - nämlich 8 "
-
Is wahr. für deine Baudrate kommt so oder so 103 raus.
Versuch aber mal, diesen Wert direkt zu setzen
.equ UBRR_VAL = 103
-
Ich habe es mittlerweile schon hinbekommen. Leider habe ich den Fehler nicht gefunden. Vielen Dank für die Hilfe. Ich hatte leider die letzten Tage wenig Zeit und freue mich darauf, mich endlich mit dem USART an sich zu beschäftigen.
Der funktionierende Code sieht so aus:
Code:
.include "m8def.inc"
.def temp = r16 ; Register für kleinere Arbeiten
.def zeichen = r17 ; in diesem Register wird das Zeichen an die
; Ausgabefunktion übergeben
.equ F_CPU = 16000000 ; 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
; Stackpointer initialisieren
ldi temp, HIGH(RAMEND)
out SPH, temp
ldi temp, LOW(RAMEND)
out SPL, temp
; Baudrate einstellen
ldi temp, HIGH(UBRR_VAL)
out UBRRH, temp
ldi temp, LOW(UBRR_VAL)
out UBRRL, temp
; Frame-Format: 8 Bit
ldi temp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
out UCSRC, temp
sbi UCSRB,TXEN ; TX aktivieren
loop:
ldi zeichen, 'T'
rcall serout ; Unterprogramm aufrufen
ldi zeichen, 'e'
rcall serout ; Unterprogramm aufrufen
ldi zeichen, 's'
rcall serout ; ...
ldi zeichen, 't'
rcall serout
ldi zeichen, '!'
rcall serout
ldi zeichen, 10
rcall serout
ldi zeichen, 13
rcall serout
rcall sync
rjmp loop
serout:
sbis UCSRA,UDRE ; Warten bis UDR für das nächste
; Byte bereit ist
rjmp serout
out UDR, zeichen
ret ; zurück zum Hauptprogramm
; kleine Pause zum Synchronisieren des Empfängers, falls zwischenzeitlich
; das Kabel getrennt wurde
sync:
ldi r16,0
sync_1:
ldi r17,0
sync_loop:
dec r17
brne sync_loop
dec r16
brne sync_1
ret
-
Fehler doch noch gefunden. Ich habe erst einen ATmega16 benutzt. Hier ging es nicht weil ich mich bei der Taktfrequenz vertan habe. Den Fehler hab ich aber erst gefunden als ich den ATmega16 gegen einen ATmega8 ausgetauscht habe. Das hab ich dann korrigiert. Aber beim AVR-Studio war noch der ATmega16 ausgewählt. Somit müsste sich ein Fehler beim assemblieren ergeben haben.