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.