www.mikrocontroller.net

Forum: Compiler & IDEs UART will nicht (Atmega88)


Autor: Thomas L. (tom)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ?

Autor: Thomas L. (tom)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Never mind - alles funktioniert auf einmal, wenn man das Ding am
richtigen Pin anschliesst :)

Danke :)

Autor: Thomas L. (tom)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Thomas L. (tom)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ...

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> aber die Fuses sagen 8MHz ...

Sicher?  1 MHz ist doch der Default...

Autor: Thomas L. (tom)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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) ...

Autor: Frank Schuessler - fs0001 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Thomas L. (tom)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: JürgenR (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Thomas L. (tom)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Thomas L. (tom)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke. Da werde ich wohl noch öfters drüber stolpern. Das werd ich mir
jetzt mal merken müssen. :)

Autor: Thomas L. (tom)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 :)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.