Hallo miteinander! Also ich hab irgendwie ein echtes Problem mit meinen UART... Wie im Betreff erwähnt benutze ich einen ATMEGA162 mit dem ich jetzt versuche, das Uart-Programm aus dem Tutorial zum laufen zu bringen... Hier mein Assembler-Programm: .include "m162def.inc" .def temp = r16 .equ CLOCK = 8000000 .equ BAUD = 9600 .equ UBRRVAL = CLOCK/(BAUD*16)-1 ; Stackpointer initialisieren ldi temp, LOW(RAMEND) out SPL, temp ldi temp, HIGH(RAMEND) out SPH, temp ; Baudrate einstellen ldi temp, LOW(UBRRVAL) out UBRR1L, temp ldi temp, HIGH(UBRRVAL) out UBRR1H, temp ; Frame-Format: 8 Bit ldi temp, (1<<URSEL)|(3<<UCSZ0) out UCSR1C, temp sbi UCSR1B,TXEN1 ; TX aktivieren loop: ldi temp, 'T' rcall serout ; Unterprogramm aufrufen ldi temp, 'e' rcall serout ; Unterprogramm aufrufen ldi temp, 's' rcall serout ; ... ldi temp, 't' rcall serout ldi temp, '!' rcall serout ldi temp, 10 rcall serout ldi temp, 13 rcall serout rjmp end serout: sbis UCSR1A,UDRE1 ; Warten bis UDR für das nächste ; Byte bereit ist rjmp serout out UDR1, temp ret ; zurück zum Hauptprogramm end: rjmp end Eine Anmerkung zu der verwendeten Taktfrequenz: hab mal die Einstellungen, die im µC vorprogrammiert waren gelassen (siehe Anhang). Laut Datenblattangebe des Herstellers läuft der µC bei diesen Einstellungen mit einer internen Taktfrequenz von 8 MHz. Irgendwo hier im Forum hab ich aber mal gelesen, dass alle Mega's von Werk ab auf 1 MHz laufen. Hab beides probiert... ES LÄUFT NICHT!!! 8 MHz: Hyperterminal empfängt ÇÇÇÇÇÇÇÇÇÇÇÇÇÇ 1 MHz: Hyperterminal empfängt willkürlich 7 Zeichen Wieso, hab ich KEINE AHNUNG!!! Das Kabel hab ich auch mal getestet (PIN2 + 3 zusammen). Läuft Einwandfrei! Sorry, bin noch Anfänger... Für schnelle Hilfe wär ich super Dankbar! Gruß Waldemar
Sorry, die datei wurde irgenwie nicht hochgeladen... Ich hoffe jetzt gehts...
Der interne Oszillator deines mega162 läuft zwar auf 8MHz, aber durch die gesetzte CLKDIV8 Fuse wird der Takt intern nochmal durch 8 geteilt. Resultat: 1MHz Takt für CPU und synchrone Peripherie. Gruß, Magnetus
Mhh, komisch laut Datenblatt ergibt die Einstellung (CKSEL3) 0010 (CKSEL0) einen devision Faktor von 4. Bei 16 MHz Maximalfreqenz sind das 4 MHz. Durch 8 ergeben das dann 500 kHz. Oder lieg ich da falsch? Um Standartmäßige 4 MHz zu bekommen muss ich demnach CKDIV8 ausmachen. Hier ist mal ein Link zum datenblatt des Mega162: http://pdf1.alldatasheet.com/datasheet-pdf/view/80272/ATMEL/ATMEGA162.html Die Daten von denen ich spreche befinden sich auf seite 37 und 40 Angenommen ich arbeite wirklich mit 1 MHz. Wieso zeigt er ir dann so einen Blödsinn an? Stimmt was mit meinem Programm nicht?
OK, hab mich mal eben durch die letzten Threads in diesem Forum gewühlt... Im Beitrag "Fusebits bei Quarz" von wulf hieß es, dass bei Uart-Anwendungen der interne Oszillator nicht genau genug ist.. Stimmt das? Wie soll ich dann meinen Mega162 fusen, damit ich 'nen normal 4MHz Quarz zwischen XTAL1 und XTAL2 hängen kann? (Hab zwar noch 2 Mega162 da, aber der eine ist vielleich schon geschrottet :( Muss gucken ob ich den noch retten kann... Deshalb probier ich mal lieber nicht einfach so drauf los...)
OK, bemüht euch nicht weiter... hab einfach noch ein bissl im Datenblatt recherchiert und bin auch nach ein wenig probieren auf die richtige einstellung und beschaltung gekommen... Uart läuft! Und es geht wirklich nur mit einem externen Quarz! Tread beendet... Danke nochmal an magnetus!
Ich lasse meinen Mega8 mit internen 8MHz problemlos mit 38,4k übertragen. Warum sollte das bei Dir nicht gehen? Deine Fuse sind auch richtig eingestellt und der Takt wird nicht, wie oben gesagt wurde, nochmal durch 8 geteilt. Hier meine Ini für das URAT im Mega8 (38,4k): URAT_INIT: .equ CLOCK = 8000000 .equ BAUD = 38400 .equ UBRRVAL = CLOCK/(BAUD*16)-1 ; Baudrate einstellen ldi r16, LOW(UBRRVAL) out UBRRL, r16 ldi r16, HIGH(UBRRVAL) out UBRRH, r16 ; Frame-Format: 8 Bit ldi r16, (1<<URSEL)|(3<<UCSZ0) out UCSRC, r16 sbi UCSRB,TXEN ; TX aktivieren ret Hier meine Ini für das URAT im Mega128 (115,2k): USART0_Init: ldi temp, 0 sts UBRR0H, temp ldi temp, 7 out UBRR0L, temp ldi temp, 0b00011000 out UCSR0B,temp ldi temp, 0b00000110 sts UCSR0C,temp ret Die Sequenz "ldi temp, (1<<URSEL)|(3<<UCSZ0)" funktioniert bei meinem 128er nicht, daher habe ich es so gemacht "ldi temp, 0b00011000".
Trotzdem Danke... Hab´es jedenfalls jetzt auf externen Takt eingestellt, wie ich es von anfang an geplant hatte, und funktioniert super. Ich hoffe, der Rest, den ich geplant hatte funktioniert auch noch, aber wenn nicht, weiß ich ja, wen ich löchern kann... ;-)
habe ein ähnliches Problem mit dem At Mega 162, bringt bei mir auch nur wilde Zeichen, habe einen externen 8 MHz Quarz und die Fuses wie im Anhang eingestellt. Kannst Du mir Deine Fuses Einstellung mal sagen, wie Du es mit Deinem externen Quarz hinbekommen hast ? Danke und Grüße, Andi
Grüß Dich Andi! Sorry, dass ich erst jetzt antworte... Also im Anhang ist mal ein Bild meiner Fusebits, wobei die derzeitige Einstellung einem externen Quarz von 4 MHz entspricht. Außerdem arbeite ich mit yaap wo angekreuzte Bit bedeuten, dass sie nicht programmiert sind. Das ist bei dir nicht der Fall, wenn ich das richtig interpretiert hab. Wichtig ist bei dir, dass du die Einstellung (CKSEL3) 1111 (CKSEL0) nimmst... Bei SUT1:0 nimmst du am besten die Einstellung 01. Auf JEDEN Fall musst du CKDIV8 setzen, da sonst alles für die Katz ist, was du an CKSEL3..0 gemacht hast (Gesetzt bedeutet deaktiviert). Ansonsten stell alles so wie bei mir an, dann kann nichts schiefgehen (Merke: Verkehrte Logik!!!) Ich hoffe, ich konnte die Helfen... Gruß Waldemar
Hallo Waldemar, vielen Dank für deine Antwort, aber ich hab jetzt alle Varianten (Fuses und Baud Rates) durchprobiert und bekomme immer noch Müllzeichen. Hab hier mal den Testcode angehängt, vielleicht ist hier ja der Hund begraben. Mit einem AT90S8515 funktionierts super. Auch die Einzelzeichen Rückgabe aus einem Terminal funktioniert zum Teil, aber nur Buchstaben, keine Zahlen keine sonstigen Zeichen. Villeicht fällt die ja was ein... Danke und Grüße, Andi #include <avr/io.h> #include <avr/interrupt.h> #include <string.h> #include <util/delay.h> #define F_CPU 8000000UL // 8 MHz #define BAUD 9600UL #define UBRR_BAUD ((F_CPU/(16*BAUD))-1) #define USART_BUFFER_SIZE 8 void delay_ms(unsigned int millisekunden) { int i; for (i=0;i<(millisekunden*10);i++) _delay_ms(1); } void uart_init(void) { // 1. UART UBRR0H = (unsigned char) (UBRR_BAUD>>8); UBRR0L = (unsigned char) UBRR_BAUD; // 2. UART UBRR1H = (unsigned char) (UBRR_BAUD>>8); UBRR1L = (unsigned char) UBRR_BAUD; UCSR0B = (1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0); UCSR1B = (1<<RXCIE1)|(1<<RXEN1)|(1<<TXEN1); UCSR0A = 0x00; UCSR1A = 0x00; // 8 N 1 UCSR0C = (1<<URSEL0)|(1<<UCSZ10)|(1<<UCSZ00); UCSR1C = (1<<URSEL1)|(1<<UCSZ11)|(1<<UCSZ01); // Interrupts aktivieren sei(); } // einzelnes Zeichen Senden void usart_putc(char zeichen) { while ( !(UCSR0A & (1<<UDRE0)) ); // Wait untill USART data register is empty UDR0 = zeichen; // Transmit data } // ganzen String senden void usart_puts(char *data) { int len, count; len = strlen(data); for (count = 0; count < len; count++) { usart_putc(*(data+count)); _delay_ms(10); } } SIGNAL(SIG_USART0_RECV) // Eingang über RS232 { unsigned char buffer; // Daten aus dem Puffer lesen ... buffer = UDR0; // AVR warten bis der RS232 Sendebuffer leer ist ... while ( !( UCSR0A & _BV(UDRE0)) ) ; // ... und gleich wieder zurück zum RS232 schicken usart_putc(buffer); // AVR warten bis der RS485 Sendebuffer leer ist ... while ( !( UCSR1A & _BV(UDRE1)) ) ; } int main(void) { // USART initialisieren uart_init(); while (1) { usart_puts("2 Das ist der erste Test der RS232 Ausgabe"); delay_ms(4000); } }
Hey andi! Leider muss ich dich enttäuschen... Hab noch nie ein µC-Programm in C geschrieben. Bis jetzt hab ich mich nur auf der Assembler-Schiene gehalten. Vielleicht kann dir ein anderer hier aus dem Forum helfen, was das Programm angeht. Evtl. könntest du mal die Fusebit-Einstellung in yaap programmieren und dann direkt von dem was ich dir gesagt hab ableiten. So wäre zumindest diese Möglichkeit ausgeschlossen. Ansonsten solltest du mal das Datenblatt zwischen 35 und 40 durchstöbern. Kann man bei www.alldatasheet.com als Vollversion downloaden. Vielleicht findest du ja was, was ich übersehen hab. MfG Waldemar
Hallo Waldemar, trotzdem vielen Dank, an den Fuse Bits kann es jetzt wohl nicht mehr liegen, da habe ich alles ausprobiert. Habe sie auch, wie du beschrieben hast, mit yaap geschrieben, aber von den Grundeinstellungen waren sie schon so wie ich sie vorher gesetzt hatte. Aber vielleicht findet ja ein AVRGCC Guru hier aus dem Forum den Fehler. Gruß, Andi
Hallo Waldemar, hab den Fehler gefunden, mit den Fuses hat alles gepasst, nur mit dem initialisieren der Uarts habe ich einen Fehler gemacht: statt: // 8 N 1 UCSR0C = (1<<URSEL0)|(1<<UCSZ10)|(1<<UCSZ00); UCSR1C = (1<<URSEL1)|(1<<UCSZ11)|(1<<UCSZ01); muß es so heißen: // 8 N 1 UCSR0C = (1<<URSEL0)|(1<<UCSZ01)|(1<<UCSZ00); UCSR1C = (1<<URSEL1)|(1<<UCSZ11)|(1<<UCSZ10); dann funktionierts problemlos. Trotzdem nochmals vielen Dank, Gruß, Andi
Super! Tolles Gefühl, wenn man etwas zum laufen bringt, gell? :) Also viel spaß noch beim basteln... Gruß Waldemar
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.