Hallo zusammen
Ich möchte momentan eine UART von einem Atmega64 zum laufen bringen.
Habe aber leider Probleme. Momentan denke es liegt an der
Initialisierung. Habe das Datenblatt mehrmals angschaut, konnte den
Fehler aber nicht finden.
Für eure Hilfe wäre ich dankbar.
Angaben:
Atmega64
Interner clock: 8MHz
Falls ihr den Fehler seht wäre mir geholfen.
Ebenso habe ich Probleme beim debuggen mit dem AVR Studio 4.19. Habt ihr
auch Probleme oder mache ich da auch noch Fehler?
> UCSR1B = (1<<RXCIE1) | (1<<TXCIE1) | (1<<RXEN1) | (1<<TXEN1);
Du gibst da zwei Interrupts frei und ich sehe keine ISRs dafür. Es
passiert zwar nix weil das sei() fehlt, aber das scheint mir nicht
duchdacht zu sein.
Wie kommst du auf 51 und wie groß ist der nominelle Baudratenfehler bei
internen 8MHz und der Wunschbaudrate? Ist die 8 MHz tatsächlich wirksam
oder hat der AVR eventuell noch eine andere Taktrate ab Werk?
> while ( !( UCSR1A & (1<<UDRE1)) )> ...> while ( !(UCSR1A & (1<<RXC1)) )
Da fehlen die Anweisungsblöcke der while-Schleifen!
rma schrieb:> while ( !( UCSR1A & (1<<UDRE1)) )>> /* Put data into buffer, sends the data */> UDR1 = data;
Semikolon vergessen, dürfte so übersetzt werden:
1
while(!(UCSR1A&(1<<UDRE1)))UDR1=data;
1
while(!(UCSR1A&(1<<RXC1)))returnUDR1;
Außerdem sind 19200 Baud mit dem eher ungenauen R/C-Oszillator ein
Problem.
Interrupt:
Ich weiss das ich momentan zwei Interupts freigebe. Dies weil ich später
mit Interrupt arbeiten möchte.
Krapao schrieb:> Wie kommst du auf 51 und wie groß ist der nominelle Baudratenfehler bei> internen 8MHz und der Wunschbaudrate? Ist die 8 MHz tatsächlich wirksam> oder hat der AVR eventuell noch eine andere Taktrate ab Werk?
51 habe ich aus dem Datenblatt gelsen für das ubrr1. Nomineller
Bautdrahten fehler ist 0.2%. Die internen 8MHz habe ich bei den Fuses
eingestellt. Und die Wunschbaudrate ist 9600.
Gruss Raphael
rma schrieb:> Interrupt:> Ich weiss das ich momentan zwei Interupts freigebe. Dies weil ich später> mit Interrupt arbeiten möchte.
Den Controller interessiert aber nicht, was du in Zukunft machen willst,
sondern nur das, was ihm gesagt wird:
Bei Auftreten eines Ereignisses am UART soll er die Interrupt-Routinen
anspringen.
Ok ich habe nun die Semikolons beim while eingefügt, und die Interupts
Flag auskommentiert.
Sollte ich den jetzt nicht etwas sehen, wen ich mit TeraTerm (ähnlich
Hyperterminal) etwas sende, auf dem uC etwas sehen?
Schnittstelleneinstellungem im OS ok ?
RXD mit TXD verbinden, (ohne uC), kommen die gesendeten Zeichen im
Terminal zurück ?
Wenn ein Bootloader aktiv ist, alle UART-Register gezielt setzen und
nicht auf Defaults verlassen.
rma schrieb:
> // UCSR1B = (1<<RXCIE1) | (1<<TXCIE1); Interrupt eischalten> UCSR1B = (1<<RXEN1) | (1<<TXEN1);
Nur ein Hinweis für später: Die beiden absoluten Zuweisungen
hintereinander beissen dich, wenn du dein Programm erweiterst.
MWS schrieb:
> ... alle UART-Register gezielt setzen und nicht auf Defaults verlassen.
Kann ich nur unterstreichen. Du setzt UCSR1C nicht. Damit ist dein
Datenformat: 5-Bit (Table 80. UCSZ Bits Settings), No Parity, 1
Stoppbit. Das schafft ein PC nicht so ohne weiteres (spezielles
Terminalprogramm).
Krapao schrieb:> Damit ist dein Datenformat: 5-Bit (Table 80. UCSZ Bits Settings), No> Parity, 1 Stoppbit.
Das Format ist per Default 8 Bit, schau' im Datenblatt unter dem
Register die Bits in "Initial Value" an. Vorher ablaufende SW könnte das
aber ändern.
MWS schrieb:> RXD mit TXD verbinden, (ohne uC), kommen die gesendeten Zeichen im> Terminal zurück ?
Ja die Zeichen kommen wieder zurück.
Wenn ihr sagt die Register gezielt setzen sind dann alle gemeint, oder
nur spezielle die sicher richtig sein müssen. Wenn es nur spezielle sind
welche muss ich dann alle setzen?
@ MWS
Jo danke, die Initial Value (= Werte nach dem RESET) habe ich nicht
beachtet.
> Wenn ihr sagt die Register gezielt setzen sind dann alle gemeint, oder> nur spezielle die sicher richtig sein müssen. Wenn es nur spezielle sind> welche muss ich dann alle setzen?
Setz alle die du für die Funktion brauchst. Beim Lesen einer UART
Initialisierung (und einer Problembeschreibung) erwartet man, dass die
Baudrate eingestellt wird, dass das Datenformat eingestellt wird und
dass der RX und/oder TX eingestellt werden. Eine Zeile weglassen, weil
man sich auf die Voreinstellungen verlässt, ist IMHO kein gelungener
Programmierstil. Mir wäre das zu fehlerträchtig und um des machens
willen eine Kleinigkeit anders zu machen als alle anderen (Tutorial,
Datenblattbeispiele)... warum? Man möchte doch nicht über eine besonders
knappe UART-Init diskutieren, sondern ein Problem in den Griff bekommen.
Dazu benutzt man bewährten Code und kümmert sich dann um eventuelle
Probleme.
Krapao schrieb:> Atmega64 & UART1... hast du dir die M103C Fuse mal angesehen? Nicht dass> der AVR kompatibel zum Atmega103 eingestellt ist, denn der hat keine> UART1!
Du hast den Fehler gefunden. Dieses Fuse war wirklich gesetzt, deswegen
konnte ich die UART1 nicht brauchen.