Hallo zusammen :) Nachdem ich mit heute schonmal mit dem define blamiert habe, versuche ich es jetzt gleich noch mal aufs Neue :) Ich nutze einen UART(0) von einem Atmega88. Kommunizieren soll er mit einem USB/Serial Wandler von FTDI. Der FTDI wird korrekt erkannt - hier dürfte es also keine Probleme geben. Es handelt sich dabei um ein fertiges Modul von www.elk-tronic.de. Angeschlossen sind einzig und allein TXD und RXD. Sonst nichts - das Ding sollte sich den Saft ja vom USB holen. Ich habe jeweils RXD an TXD angeschlossen. Dieser Code soll den UART initialisieren: ---snip--- // USART // 8N1, Parity: None, 9600 Baud UBRR0H = 0x00; UBRR0L = F_CPU / (UART_BAUD_RATE * 16L) - 1; UCSR0B |= (1 << TXEN0); UCSR0C |= ((1 << UCSZ00) | (UCSZ01)); ---snip--- F_CPU ist 8 MHz (habe ich auch im AVR Studio überprüft) UART_BAUD_RATE ist 9600 Meine Endlosschleife habe ich etwas modifiziert: ---snip--- while(1) { writeChar('A'); } ---snip--- Die dazugehörige Methode ist: ---snip--- void writeChar(char c) { while (!(UCSR0A & (1<<UDRE0))); UDR0 = c; } ---snip--- Wenn ich mir das am Oszi anschaue, dann sehe ich auch etwas - deuten kann ich es zwar nicht, aber es sieht mir wie ein digitales Signal aus. Daher jetzt meine Frage - woran könnte es liegen, dass ich am PC nichts sehe ?
Never mind - alles funktioniert auf einmal, wenn man das Ding am richtigen Pin anschliesst :) Danke :)
Sooo .. Kommando retour ... es kommt zwar was an .. scheint mir aber nur Blödsinn zu sein grmml. Findet vielleicht jemand oben einen Fehler ? Anstatt Buchstaben bekomme ich nur ein \0 .. also drei Zeichen. dabei ist es egal, was ich sende ... seufz
ok .. bin knapp davor ... wenn ich im terminal programm auf 1200 Baud stelle, passts ... aber wo ist der Hund? Die Berechnung habe ich aus dem Atmel Datasheet - stimmen tuts um einen Faktor 8 nicht ... würde eigentlich auf eine falsch eingestellte F_CPU deuten .. aber die Fuses sagen 8MHz ...
> aber die Fuses sagen 8MHz ...
Sicher? 1 MHz ist doch der Default...
beim atmega8 ist standard 1 MHz ... ich verwende den Atmega88 - den kann man bei den Fuses nichtmal auf 1MHz stellen (da gibts nur 8MHz oder externer Quarz) ...
Hi, versuchs mal ganz quick an dirty ob's an Deiner Kalkulation der Baudrate liegt, lass das mal weg: UBRR0H = 0x00; UBRR0L = F_CPU / (UART_BAUD_RATE * 16L) - 1; und ersetze es durch: UBRR = 51; schau ob dann die Kommunikation mit 9600 Baud bei 8 Mhz geht; wenn ja ist noch irgendwas an der Definition Deiner Konstanten bzw. Baudrateneinstellung falsch. Mehr dazu im Atmega88 Datenblatt ( ATmega48/88/168 Preliminary Complete (361 pages, revision F, updated 06/05) auf Seite 194. Gruss Frank
Hallo :) Hab ich auch schon versucht ... Leider selbiges Ergebnis .. Zeichen kommen laut hterm mit 1200Baud an. Als Register habe ich UBRR0 verwendet - das stimmt schon, oder? (weil du UBRR schreibst). Im Datasheet habe ich eben gelesen: "The Transmitter divides the baud rate generator clock output by 2,8 or 16 dependinung on mode." ... (Seite 170). Kanns damit zusammenhängen?
Datenblatt Seite 25 : Default Clock Source: The device is shipped with internal RC oscillator at 8.0MHz and with the fuse CKDIV8 programmed, resulting in 1.0MHz system clock. Wird also bei Standard-"fuses" mit 1MHz laufen.
Ahhhhhhhhhhhh ... DAS hab ich übersehen ... Herzlichen Dank - das war des Rätsels Lösung ... Da hätte ich noch ewig gesucht ... habe bei den Fuses nur gelesen: 8MHz .. und mir gedacht, das passt ... Danke
Nö, praktisch alle AVRs kommen mit 1 MHz daher (mittlerweile). Der Grund ist einfach: die 8 MHz sind nicht für den kompletten Betriebsspannungsbereich zulässig. Die Einstellung über CKDIV8 hat Ursachen im internen Design. Früher haben sie den RC-Oszillator variabel gebaut, dafür brauchte der dann mehrere Kalibrierbytes usw. Jetzt läuft der auf einer festen Frequenz, die durch ein IO-Register dann runtergeteilt werden kann. Die CKDIV8-Fuse macht nun weiter nichts, als den power-on default für den Taktteiler festzulegen.
Danke. Da werde ich wohl noch öfters drüber stolpern. Das werd ich mir jetzt mal merken müssen. :)
Aaaaaalso ... So .. das Empfangen eines Bits mittels Interrupt habe ich nun auch geschafft, aber nun fehlts mir ein wenig an Logik. Angenommen ich habe eine Befehlssequenz, bestehend aus mehreren Chars, die ich dem Atmega zukommen lassen möchte. Wie würde ich da am intelligentesten vorgehen. Was ich mir bereits überlegt habe: * fixes Datenformat (z.B. 5 Byte) * Datenformat mit variabler Länge (Ringspeicher?) * nach gewisser Inaktivität array löschen (timer benötigt). * Delimiter verwenden. Was würdet ihr als brauchbar erachten. Das fixe Datenformat wäre wohl am einfachsten, was passiert jedoch, wenn mal ein Command nicht ankommt, dann hängt das Ganze in irgendeinem unbrauchbaren Zustand. Der Ringspeicher ist sicher praktisch, kann bis zu einer x-beliebigen Länge genutzt werden - braucht jedoch Speicher .. und: welches Zeichen soll ich als "Endzeichen" nehmen. Dazu kam dann eben die Idee, nach einer gewissen Zeit das array zu löschen und somit zurückzusetzen. Da bräuchte ich jedoch einen Timer dazu (Verschwendung). Ich würde mich über Anregungen freuen :)
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.