www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega8, UART@19,2 kHz


Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo miteinander :)

Ich versuche meinen Atmega dazu zu überreden mit meinem Handy über den
UART kommunizieren zu lassen.

Ich kann mittels Hyperterm + einem MAX232 perfekt auf das Handy
zugreifen, ich schicke also z.B.: atd+4399999, das handy piepst und
meldet über UART zurück: NO CARRIER

Nun würde ich das ganze mit einem Atmega8 versuchen.

Dazu habe ich Pin2 (RXD) des Atmega8 mit TXD des Handies verbunden
(über 1kOhm). Ebenso Pin3 (TXD) mit RXD des Handies.

Bezüglich Code habe ich mir die UCR Register folgendermassen überlegt:
* UCSRA = 0x02;
* UCSRB = 0x08;
* UCSRC = 0x06;
* UBRRL = 25;

im Detail:
UCSRA - nur das Bit U2X ist gesetzt (Verdoppelung des Taktes)
UCSRB - TXEN ist gesetzt (ich will vorerst nur mal was senden)
UCSRC - 8N1 (selbe Einstellung wie in Windows Hyperterm)
mit UBRRL = 25 und einem Takt von 4MHz (interner Osz.) sollte ich also
auf die 19,2kHz kommen.
Nur es wird wahrscheinlich genau nichts übertragen. Auch der PC ist
noch angesteckt, ich sollte also sehen, ob da was kommt, aber das Handy
piepst nicht einmal. Zum schreiben verwende ich die folgenden Funktionen
aus dem Tutorial:

int uart_putchar(char c)
{
  if (c == '\n')
    uart_putchar('\r');
  loop_until_bit_is_set(UCSRA, UDRE);
  UDR = c;
  return 0;
}

void uart_puts(const char *s)
{
  char c;

  while ((c = *s++) != '\0')
    uart_putchar(c);
}


Weiss vielleicht jemand was ich denn hier falsch mache? Ich verzweifle
nämlich bald einmal :(
Danke für jegliche Hilfestellung :)

Autor: marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hast du ubbrh gesetzt? mit einem externen quarz probiert? manchmal ist
der interne oszillator zu ungenau für u(s)art...

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
auf was muss ich ubrrh setzen ?

mit einem externen quarz würd ichs nur im notfall probieren wollen
(obwohl ich eh grad 4 MHz herumliegen hätte). ausserdem ist im
Datasheet ja bei 4MHz ein Fehler von 0,2% oder so angegegeben .. das
sollt doch ausreichen, oder ?

weisst du zufällig was der unterschied zwischen synchronem und
asynchronem transfer ist ?

ich kenn das nur so:
synchron: ich sende was, und der uC macht erst weiter wenn das zeugs
weg ist.
asynchron: ich sende was, der uC macht sofort weiter und springt dann
dafür wenn er fertig ist in eine Routine.
Ist das sowas - oder hat das hier eine andere bedeutung ?

anyway, danke mal für deine Antwort :)

Autor: marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also ubbrrh (ein b oder ein r streichen - wer denkt sich diese namen aus
;)) auf 0 setzen, wenn dort ein falscher wert drin steht, dann geht's
nicht (auch nach einem reset den wert setzen)

der interne rc-oszillator hat auch einen fehler und der kommt noch dazu
(auch wenn der kallibriert werden kann).

AFAIK:
synchron und asynchron bezieht sich auf den bus. du hast an dem uart
noch eine takt-leitung dran, im asynchronen modus wird die nicht
genommen und ein interner taktgeber gibt den takt für die bits an.
im synchronen modus gibt das signal am XCK-Pin den takt vor.

Autor: marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das mit dem ubbrrh hängt mit dem ursel bit in dem control register
zusammen (hab nur das mega16 datenblatt hier -> schau mal bei ucsrc
nach)

das mit dem, synchronen und asynchronen modus steht auch im datenblatt

Autor: dave (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du bit 7 (URSEL (Uart Register SELect, logische Namen)) setzt, dann
kannste an UCSRC kommen, sonst erwischte UBBRH.

Wenn ich das so ansehe hat marcel Recht... du hast in UBBRH 6
reingeschrieben.. du musst 6+128 reinschreiben.. nimm bitte die
Schreibweise: UCSRC = (1<<URSEL)+ oder |....

dave

Autor: marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
lad dir avr studio runter und probier den code im simulator.
dann musst du zwar die funktion der interrupt flags per hand emulieren,
mir ist dabei auch der "fehler" mit dem ubbrh aufgefallen
(hatte das selbe problem)

mögen die register mit dir sein!

Autor: Tom (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
sooo .. erstmal ein herzliches Danke an alle, die geantwortet haben.

Habe jetzt mal den Code etwas leserlicher geschrieben (es hat sich nur
mal das uart init geändert):

void UARTinit(void)
{
  UCSRA |= (1<<U2X);
  UCSRB |= (1<<TXEN);
  UCSRC |= (1<<URSEL);
  UCSRC |= (1<<UCSZ1) | (1<<UCSZ0); // write Character Size into UCSRC

  UCSRC &= ~(1<<URSEL); // now select the UBRRH
  UBRRH = 0x0; // write 0
  UBRRL = 25;
}

allerdings dürfte da immer noch was nicht so ganz stimmen. im simulator
wird nämlich immer das UBRRH mitgesetzt. Weiss vielleicht jemand woran
das liegt?
Ich mache es ja folgendermaßen:
UCSRC |= (1<<URSEL); - selektiere das UCSRC Register
UCSRC |= (1<<UCSZ1) | (1<<UCSZ0); - Character Size setzen
UCSRC &= ~(1<<URSEL); - UBRRH selektieren
UBRRH = 0x0; - 0 schreiben (sind ja nur 4 Bits).

aber irgendwie ändert sich das UCSRC auch mit?!? Was wäre denn die
Korrekte schreibweise?

Ich habe mir erlaubt mal das .elf anzuhängen - Plattform ist ein
Atmega8

Autor: marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich glaub der simulator kann das nicht unterscheiden, weil die daten die
selbe adresse haben.
dann steht da noch im datenblatt, dass das lesen aus ubrrh "etwas
schwieriger" sei... also proggen und probieren (es sieht korrekt aus),
...

häng den atmega am besten über den max (bzw. einpaar zdioden) mit einem
(null)modem kabel an den computer und schau mit hyperterminal o.Ä. nach
was ankommt.

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
verdammt ... blödes ubrrh ...

der uC hängt eh wie auch das handy am MAX232 (über 1kOhm) .. nur es
kommt eben rein gar nichts am PC an.

--PC -- MAX232 --- Handy
               --- uC

wobei der uC direkt mit dem Handy verbunden ist ...

Ich werd jetzt wohl mal das handy abstecken und schauen was passiert :)

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nachtrag: danke marcel, für deine bemühungen :)

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zu was willst Du denn dazu-verodern?
Ich weiss nicht welcher schrott vorher drinstand, das mach keinen
sinn.
Im simulator steht immer null drin, in real life ???


void UARTinit(void)
{
  UCSRA |= (1<<U2X);
  UCSRB |= (1<<TXEN);
  UCSRC |= (1<<URSEL);

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
da muss ich jetzt aber mal wiedersprechen ...
bspsweise UCSRA: da ist das UDRE standardmässig auf 1 (lt. Datenblatt).
Ebenso im Simulator, dort ist standardmässig UCSRA = 0x20 (was dem
obigen entspricht).

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... und bei einem schnellen Blick aufs Programm nicht mehr
nachvollziehbar. Hier fehlt die Tranzparenz.

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Werner B.: sollte ich deiner meinung nach also immer nur = statt |=
verwenden?
Das bezüglich der Transparenz stimmt natürlich. Man kann ja das DB
nicht auswendig kennen:)


Bzgl. Anderem: Es funktioniert mittlerweile. Anscheinend hatte ich
einen Denkfehler mit TXD und RXD, dann noch ein paar kleinere Dinge und
mittlerweile wählt mein Atmel meine Rufnummer :)

Einen herzlichen Dank derweil mal an alle die mitgeholfen haben, es
geht sicher bald wieder weiter :)

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nicht immer, aber wenn es der nachvollziehbarkeit des codes dient.
Warscheinlich bist Du es selbst der ihn irgenwann einmal ändern muss.

Code möglicht selbstdokumentierend schreiben. Das ist auch der vorteil
wenn man die macros verwendet (1<<irgendwas) statt nur z.B. 64.
Ebenso für UBRR den wert die formel als macro unter Verwendung der
baudrate (BAUDRATE/16)-1; (Irgendwie muss bei Dir noch der U2X
berücksichtigt werden). Der compiler/präprozessor kann das ausrechnen
und mit einem blick in den sourcecode weiss man was eingestellt wird
bzw werden soll ohne lange zurückrechnen zu müssen.

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hmm .. ja . .diesbezüglich hast natürlich recht :)
Musste mich erstmal an die Schreibweise gewöhnen - meine C Zeiten sind
halt doch schon länger vorbei ...
Doku ist sowieso selbstverständlich :)

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.