Moin,
ich hab momentan ein Problem mit dem UART-Codeteil meines Projekts. Im
großen und ganzen wird das ganze die Elektronik eines Spektrometers,
liest also ne CCD-Zeile schnell aus, speichert die Daten im SRAM und
sendet die Daten über UART an den PC. Das ganze Programm ansich läuft,
allerdings schickt der µC die ins UDR0-Senderegister geladenen
Datenblöcke nich raus. Momentan nutze ich einen Logic Analyser zum test
der Software indem ich einfach Testpulse über nen separaten Port
ausgeben lasse. Der LA sagt mir hierbei auch das die Sendeschleife läuft
und sich wiederholt wie gewünscht. Allerdings kommen eben keine Daten
raus über den UART Tx-Pin.
Der LA sagt das regelmäßig 3 Testpulse erzeugt werden (wie gewünscht
werden 3 Datenblöcke ins UDR0-Register geladen: Daten, New Line und
Carriage Return). Eine Variation der Baudrate von 9600 auf 28800 Baud
brachte auch keine Änderung.
Wobei die gleiche hardware allerdings mit dem UART-Beispielcode aus der
Artikelsammlung von µc.net funzt (natürlich abgewandelt auf den
ATMega2560 und seine Register).
Hier mal das Codefragment, kann auch gerne den vollständigen Code
reinstellen.
Quarzfrequenz is momentan 24MHz (funzt wie gesagt mit dem
UART-Codebeispiel ausm Artikelbereich)
;---------------------------------------------------------
;----------------------Daten senden-----------------------
;---------------------------------------------------------
; Baudrate einstellen
ldi temp, HIGH(UBRR_VAL) ; Wert = 58dec, für 8MHz und 9600Baud
sts UBRR0H, temp
ldi temp, LOW(UBRR_VAL)
sts UBRR0L, temp
; Frame-Format: 8 Bit
ldi temp, (1<<UCSZ01)|(1<<UCSZ00)
sts UCSR0C, temp
ldi temp, (1<<TXEN0)
sts UCSR0B, temp ; TX aktivieren
Speicherabbruch: ; Speichern beendet, Speicherschleife fertsch
durchlaufen
.EQU Sendedurchlaeufe = 0x1068 ; wieder festlegung der Größe der
Zählschleife fürs Senden, 0x1068 = 4200Dec
LDI ZH, High(Sendedurchlaeufe) ; Z-Pointer als 16bit-Zähler für
Sendeschleife
LDI ZL, Low(Sendedurchlaeufe)
LDI temp2, 0x00 ; dient als Vergleichszahl = 0 für
BREQ-Sendeabbruch
Daten_laden:
SBIW ZH:ZL, 1 ; Subtrahiert 1 vom Z-Pointer
CP ZH, temp2 ; Vergleich Z-Pointer-Highbyte
CPC ZL, temp2 ; Vergleich Z-Pointer-Lowbyte
BREQ Sendeabbruch ; springe zu Sendeabbruch wenn Schleife
durchlaufen
LD temp, -X ; lade obersten Datenblock ins Temp-register,
dekrement dann X-Pointer
rjmp Senden ; rjmp zu senden um dort den datenblock
wegzusenden
Sendeabbruch:
nop
rjmp Sendeabbruch ; Programm fertsch, vllt noch n Taster dran
damit er wieder zur Main springt um den
; ganzen kram nochma durchläuft->tasterentprellung,
muss aber nich da er
; höchstwahrscheinlich schon ganz woanders im
Programm is wenn der Taster wieder
; zurückprellt und ihn dann der Tasterzustand
nichmehr interessiert, noch gucken
; wegen
Senden:
mov zeichen, temp ; Unterprogramm aufrufen
rcall serout
ldi zeichen, 10 ; New_Line_ASCII-Befehl!
rcall serout
ldi zeichen, 13 ; Carriage Return, Zeichen an
Zeilenanfang darstellen
rcall serout
rcall sync
rjmp Daten_laden
serout:
LDS temp,UCSR0A ; Prüfen auf leeren Datensendepuffer
SBRS temp,UDRE0 ; Skip if bit in register set
rjmp serout
sts UDR0, zeichen
LDI testpuls, 0x00
OUT PORTC, testpuls
LDI testpuls, 0xFF
OUT PORTC, testpuls
LDI testpuls, 0x00
OUT PORTC, testpuls
ret ; zurück zum Hauptprogramm
; kleine Pause zum Synchronisieren des Empfängers,
falls zwischenzeitlich
; das Kabel getrennt wurde
sync:
ldi warten1,0
sync_1:
ldi warten2,0
sync_loop:
dec warten2
brne sync_loop
dec warten1
brne sync_1
ret
MfG Echo
Echo schrieb: > Quarzfrequenz is momentan 24MHz ^^^^^ [...]
1 | > ldi temp, HIGH(UBRR_VAL) ; Wert = 58dec, für 8MHz und 9600Baud |
2 | ^^^^ |
wäre es möglich, dass hier schon der hund begraben liegt? 24MHz und ein UBRR wert von 58 für 9600 kann eigentlich nicht stimmen - soweit ich mich erinnere, hatte ich neulich einen ubrr-wert von 63 für 9,8304 MHz und 9600...
Hmm, eigentlich errechnet sich der UBBR-Val-Wert automatisch durch das Konstrukt: .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 MfG Echo
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.