Forum: Mikrocontroller und Digitale Elektronik UART sendet immer nur 00000000


von Basti (Gast)


Lesenswert?

Icbin grade dabei ein kleines programm für den mega8 zu schreiben das
einen zähler hochzählt un den zählerstand über den uart ausgeben soll.
ich habe den uart initialisiert und es macht in der simulation den
anschein als wenn es funktionieren würde. während der übertragung geht
das UDRE bit auf 0 und verhindert so das irgendwie die daten in UDR
überschrieben werden könnten. allerdings ist in der simulation in UDR
keine änderung zu erkennen, also es steht immer 0x00 drin. hab das
grade auch mal in nen µC geschrieben und an den COM-port angeschlossen
aber da kommt wirklich immer 0x00 an. langsam verzweifel ich hier
noch... hab das schon vereinfacht und versuche einfach nur irgendwas
auszugeben aber immer nur 0x00 :-(

hier mal mein c-code

int main (void)
{
UBRRH = ((8000000/16/9600 -1) >>8);
UBRRL = (8000000/16/9600);
UCSRB |= (1<<TXEN);
UCSRC |= (1<<USBS) | (3<<UCSZ0);

while (1)
  {
  if (bit_is_set (UCSRA, UDRE))
    {
    UDR = 0xA2;
                }
  }
}

eigentlich ist alles so wie im datenblatt und auch hier im tutorial
beschrieben...

von A.K. (Gast)


Lesenswert?

Die IO-Adresse UDR hat eine Doppelfunktion. Lesend wird der UART
Empfänger angesprochen, schreibend der UART Sender. Wenn die Simulation
vom Studio das UDR nur als 1 Register zeigt, lässt sich diese
Doppelrolle schlecht darstellen und mag etwas irritieren.

von Profi (Gast)


Lesenswert?

Evtl. klappt das Berechnen der UBRR-Werte nicht, denn der Compiler
rechent Konstanten manchmal nur mit 16 Bit.
Manchmal hilft auch ein 8000000L
Hast Du das kontrolliert?
Rechne die Werte aus und schreib sie direkt rein.

von Johannes (Gast)


Lesenswert?

Der mega8 hat noch keine getrennten Adressen für UBRRH und UCSRC. Damit
UCSRC erreicht wird, musst Du noch das URSEL-Bit setzen:

UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);

sonst schreibts Du (noch einmal) nach UBRRH.
Übrigens, wenn Du nicht wirklich 2 Stoppbits brauchst, kannst Du UCSRC
auch einfach ignorieren. Der Wert für die 8 Bit Daten steht nach dem
Reset schon von alleine drin.

von Basti (Gast)


Lesenswert?

also so weit ich das erkenne wird gesendet, wenn ich in der simulation
gucke wie lange er brauch um ein byte zu senden sind das, ich glaube ca
1ms und wenn ich das ganze bei 9600baud und 10 bit (8daten +2stopp)und
8mhz nachrechne komme ich auf ein ziemlich genau gleiches ergebnis.
also müsste doch die einstellung fürs timing (wenn mans mal so
ausdrücken will) passen. wenn ich das in den µC schreibe und den mit
meinem com-port verbinde erkennt er ja auch das gesendet bzw empfangen
wird. allerding kommt da immer nur 8 an egal was ich in UDR schreibe.

@A.K.: das is ja nich nur in der simulation das da 0 steht sonder der
sendet ja auch "in echt" nur 0 obwohl er wie oben angegeben 0xA2
senden sollte

@profi: hab ich schon nachgerechnet und auch im datenblatt nachgeguckt,
habs jetzt nicht zur hand aber meine 51 dezimal und das steht auch drin
und wenn ich das manuell reinschreibe ändert sich weder in der
simulation noch in echt was

@johannes: hab ich auch ausprobiert -> ändert nix

von Basti (Gast)


Lesenswert?

oh sorry meinte

"...allerdings kommt da immer nur 0 an egal was ich in UDR
schreibe."

also 0 und nicht 8

von Johannes (Gast)


Lesenswert?

Nun, wenn da immer nur 0 ankommt, heißt das immerhin schon mal, dass
Dein UART überhaupt sendet. Sonst würde nämlich gar nichts ankommen.

Ansonsten hast Du zumindest einen Fehler in Deiner Rechnung, denn 8 Bit
Daten plus 2 Stoppbits ergeben bereits 11 Bits Übertragungzeit, weil Du
das Startbit nicht mitgerechnet hast. Also dann frage ich mal, ob Du
Dir das serielle Signal schon mal am Scope angekuckt hast, und dort das
A2-Schema wiedererkennen konntest, sprich ein Low am AVR-Pin (oder
Plus-Spannung auf der RS232-Leitung) von drei Bitzeiten Dauer (Startbit
+ Datenbits 0 und 1), danach 1 Bitzeit High (oder Minusspannung auf der
RS232-Leitung für Datenbit 2), dann wieder 2 Bitzeiten Low (Datenbits 3
und 4), 1 Bitzeit High (Datenbit 5), nochmal 1 Bitzeit Low (Datenbit 6)
und danach "High bis zum Abwinken" (Datenbit 7 plus Stoppbits).

Frage am Rande: Welches Terminalprogramm benutzt Du auf der PC-Seite?

von Profi (Gast)


Lesenswert?

Hast Du schon einen Pegelwandler drin? diese invertieren das Signal!

Normalpegel am µC: high, an der RS232-Leitung ca. -10V.

Für A2 muss das Signal am µC so aussehen

S01234567SS
000100101111111111111

auf der RS-Leitung genau invertiert
S01234567SS
+++-++-+-------------

Die meisten RS232-Empfänger sind mit TTL-Pegel zufrieden, aber die
Polarität muss invertiert sein. Das kann man auch mit einem Bit
einstellen (zumindest bei den Motorola-µC). Beim Mega8 habe ich gerade
nachgeschaut und auf die Schnelle nichts dergleichen gefunden.

von Johannes.A (Gast)


Lesenswert?

@Profi

Mit welchem Controller arbeitest Du, dass Du mit Bastis Code pro
gesendetem Zeichen noch lockere 10 weitere Stop-Bits erhälst?

So einen wünsche ich mir schon seit bald 3 Jahrzehnten, habe aber immer
noch keinen gefunden...

von Basti (Gast)


Lesenswert?

Terminalprogramm habe ich hyperterminal und dann noch ausm netz
COM-Terminal. hyperterminal zeigt nix an weil eben nur 0x00 ankommt,
man kann aber sehen das der balken schneller blinkt wenn mein µC an is,
wenn ich den abschalte blinkt der balken normal, so wie der eben immer
blinkt, so schnell wie wenn ich ich schreibe. COM-Terminal sagt mir das
0x00 ankommt.

@Profi meinst du ich könnte meinen max232 dazwischen rausnehmen und das
geht trotzdem?

von Karl heinz B. (kbucheg)


Lesenswert?

Wenn du einen Max232 schon drinnen hast, dann lass den
da drinnen.

von Basti (Gast)


Lesenswert?

ich habs hinbekommen. haltet mich für blöd aber ich hab zuerst UBRRH und
UBRRL beschrieben und dann UCSRA - UCSRC und das hat mein UBRRH dann
wieder überschrieben. jetzt erst UCSRx und dann UBRRx und es geht!!

super geil! danke an alle!

von Johannes.A (Gast)


Lesenswert?

Na dann erstmal Glückwunsch zur Problemlösung!

Aber irgendwie gibt mir das doch zu denken. Ich mein, ich hab nun schon
wirklich etliche mega8-Programme gebaut, die den USART im asynchronen
Modus benutzen und nie dieses Problem gehabt. Meine Standardreihenfolge
ist bei allen immer gewesen: erst UBRR (meist nur -L), dann UCSRC und
-A, soweit benötigt, und die Enables per UCSRB ganz zum Schluss, so wie
ich das "vor Urzeiten" mit dem 8251 mal gelernt und auch als sinnvoll
eingesehen habe.

Ich werde bei nächster Gelegenheit aber mal mit Deiner Reihenfolge
spielen. Kann ja immerhin sein, dass ich dabei noch was dazulerne.

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
Noch kein Account? Hier anmelden.