Forum: Mikrocontroller und Digitale Elektronik UART Sendeprobleme


von Florian S. (didi34)


Lesenswert?

Hallo, ich versuche schon lange über UART ein Zeichen zu senden und über 
Putty am PC anzuschauen.
1
/* 
2
  UART-Init: 
3
Berechnung des Wertes für das Baudratenregister 
4
aus Taktrate und gewünschter Baudrate
5
*/
6
 
7
#ifndef F_CPU
8
/* In neueren Version der WinAVR/Mfile Makefile-Vorlage kann
9
   F_CPU im Makefile definiert werden, eine nochmalige Definition
10
   hier wuerde zu einer Compilerwarnung fuehren. Daher "Schutz" durch
11
   #ifndef/#endif 
12
 
13
   Dieser "Schutz" kann zu Debugsessions führen, wenn AVRStudio 
14
   verwendet wird und dort eine andere, nicht zur Hardware passende 
15
   Taktrate eingestellt ist: Dann wird die folgende Definition 
16
   nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?) 
17
   von AVRStudio - daher Ausgabe einer Warnung falls F_CPU
18
   noch nicht definiert: */
19
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
20
#define F_CPU 4000000UL  // Systemtakt in Hz - Definition als unsigned long beachten 
21
                         // Ohne ergeben sich unten Fehler in der Berechnung
22
#endif
23
 
24
#define BAUD 9600UL      // Baudrate
25
 
26
// Berechnungen
27
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
28
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
29
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
30
 
31
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
32
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
33
#endif 
34
35
#include <avr/io.h>
36
#include <avr/delay.h>
37
38
void uart_init(void)
39
{
40
  UBRRH = UBRR_VAL >> 8;
41
  UBRRL = UBRR_VAL & 0xFF;
42
 
43
  UCSRB |= (1<<TXEN);  // UART TX einschalten
44
  UCSRC = (1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1 
45
}
46
int uart_putc(unsigned char c)
47
{
48
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
49
    {
50
    }                             
51
 
52
    UDR = c;                      /* sende Zeichen */
53
    return 0;
54
}
55
 
56
 
57
/* puts ist unabhaengig vom Controllertyp */
58
void uart_puts (char *s)
59
{
60
    while (*s)
61
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
62
        uart_putc(*s);
63
        s++;
64
    }
65
}
66
uint8_t uart_getc(void)
67
{
68
    while (!(UCSRA & (1<<RXC)))   // warten bis Zeichen verfuegbar
69
        ;
70
    return UDR;                   // Zeichen aus UDR an Aufrufer zurueckgeben
71
}
72
73
74
int main(void)
75
{
76
   uart_init();
77
   while(1)
78
   {
79
   uart_putc('a');
80
   _delay_ms(1000);
81
   }  
82
   
83
}

Aber ich empfange bei Putty nichts.
Die Taktfrequenz ist intern auf 4 MHZ gesetzt.
Hoffentlich kann mir jemand helfen.

von Andreas B. (andreasb)


Lesenswert?

Nim mal dein Delay raus aus dem Main.

Dann halte mal eine LED (gegen VCC) oder wenn du hast ein Oszi an den TX 
pin, sollte leuchten / flackern. Wenn nicht: Problem mit µC.

Wenn das funktioniert: Nim den RX Eingang des PCs (gleiches Kabel!) und 
halte einen Pullup gegen VCC, z.B. 10k, dann nimmst du ein Massekabel 
und wackelst dann etwas. Dann müsste etwas erscheinen auf dem 
Bildschirm, und wenns nur Vierecke sind.

Sollte das nicht Klappen: Bist du sicher auf dem richtigen COM Port?

Wenn beides funktioniert, hast du die Pins korrekt verbunden? 
Grundsätzlich TX des Controllers auf RX des PCs, USB Module sind 
teilweise aus Mikrocontrolersicht beschrieben, dann wäre TX auf TX... 
Einfach mal probieren...


mfg Andreas

von Ingo (Gast)


Lesenswert?

Musst du den TXD Pin nicht noch als Ausgang setzen? Welchen Treiber 
verwendest du? RXD/TXD vertauscht?


Ingo

von Andreas B. (andreasb)


Lesenswert?

Ingo schrieb:
> Musst du den TXD Pin nicht noch als Ausgang setzen?
Die Lib von Peter Fleury setzt den nicht als Ausgang, und hat zumindest 
bei letzter Verwendung funktioniert;-)



mfg Andreas

von Florian S. (didi34)


Lesenswert?

>Nim mal dein Delay raus aus dem Main.

>Dann halte mal eine LED (gegen VCC) oder wenn du hast ein Oszi an den TX
>pin, sollte leuchten / flackern. Wenn nicht: Problem mit µC.

>Wenn das funktioniert: Nim den RX Eingang des PCs (gleiches Kabel!) und
>halte einen Pullup gegen VCC, z.B. 10k, dann nimmst du ein Massekabel
>und wackelst dann etwas. Dann müsste etwas erscheinen auf dem
>Bildschirm, und wenns nur Vierecke sind.

>Sollte das nicht Klappen: Bist du sicher auf dem richtigen COM Port?

>Wenn beides funktioniert, hast du die Pins korrekt verbunden?
>Grundsätzlich TX des Controllers auf RX des PCs, USB Module sind
>teilweise aus Mikrocontrolersicht beschrieben, dann wäre TX auf TX...
>Einfach mal probieren...


>mfg Andreas

Habe ich schon alles versucht. Auf dem Oszi habe ich ein Signal. Ich 
bekomme Auch wenn ich das mit dem Wacheln mache und da ich das SDK 500 
von Atmel verwende, sollte es auch keine Verbindungsprobleme geben, da 
alles schön beschriftet ist.

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

Florian Schuller schrieb:
> Habe ich schon alles versucht.

mit welchen Ergebnissen? (bitte jedes der einzeln vorgeschlagenen 
Vorgehensweisen kommentieren mit dem zugehörigen Ergebnis, ggf. 
Screenshot etc

von Andreas B. (andreasb)


Lesenswert?

Wenn das Timing nicht stimmt (z.B. Fuse Falsch) wird gerne mal ein 
Zeichen Verschluckt.

Wenn du nun deinen _delay_ms(1000); raus nimst, und ggf. nicht nur ein A 
sondern auch noch ein 0xaa sendest müsste etwas ankommen.

Und wenn nicht das ankommt was du sendest hast du ein Timing Problem.


Hast du ein Speicheroszi? Ich mach das immer so: Ich sende vom PC einen 
Bekannten String, z.b: "ABC", dieses Muster speichere ich ab. Dann sende 
ich den gleichen String vom AVR, dann lege ich die übereinander und sehe
1) Ist es das richtige Signal
2) Wie falsch ist mein Timing;-) Dann mit Cursor beide Werte berechnen, 
Faktor ausrechnen, und diesen Faktor bei der Baudrate 
mitberücksichtigen.
3) Wundern warum die Berechnung vorher nicht gestummen hat;-)




mfg Andreas

von Florian S. (didi34)


Angehängte Dateien:

Lesenswert?

Ich habe leider nur ein Analogoszi, also kann ich leider keine 
Screenshots machen, aber ich habe am Oszi ein Signal, das nicht so 
schlecht aussieht.

Wenn ich das Verbindungskabel von der UART-Schnittstelle zum COM-Port 
kurz herausziehe und wieder anstecke und das Delay aus dem code 
herausnehme, bekomme ich irgendwelche kryptischen Zeichen(Foto)

von Andreas B. (andreasb)


Lesenswert?

Florian Schuller schrieb:
> Wenn ich das Verbindungskabel von der UART-Schnittstelle zum COM-Port
> kurz herausziehe und wieder anstecke und das Delay aus dem code
> herausnehme, bekomme ich irgendwelche kryptischen Zeichen(Foto)

NUR beim herausnehmen?

Ich vermute deine Timings sind falsch.

Kontrolliere mal deine Fuse / Quarz. Und wen du 0xAA ausgibst solltest 
du auch mit dem Oszi die Timings kontrollieren können.


mfg Andreas

von Florian S. (didi34)


Lesenswert?

>Ich vermute deine Timings sind falsch.

Das habe ich auch schon vermutet, doch ich habe die Fuse schon min. 10 
mal kontrolliert. Ich habe es auf 4 MHZ intern gesetzt. Ich habe auch 
schon einen anderen µC verwendet, doch nichts geht. Ich habe das ganze 
schon mit dem AVR-Studio 4 verwendet und allse hatte bestens 
funktioniert, doch jetzt wollte ich es wieder versuchen und habe 
AVR-Studio 6 installiert. Kann es daran liegen?

von Peter II (Gast)


Lesenswert?

wenn du schon einen Oszi hast, dann miss doch mal die bit-länge.

von Werner (Gast)


Lesenswert?

Florian Schuller schrieb:
> Ich habe leider nur ein Analogoszi, also kann ich leider keine
> Screenshots machen, aber ich habe am Oszi ein Signal, das nicht so
> schlecht aussieht.

Dann erzähl doch mal, wie das Signal aussieht, welche Bitdauer das hat 
und ob es ein 'a' ist.
1
_-_----__--_______

Hast du einen RS232-Pegelwandler zwischen µC und PC?

von Norbert (Gast)


Lesenswert?

Ein kleines 'a' (0x61 / 0b01100001)
Bits drehen wir von links nach rechts (0b10000110), da LSB first.

Startbit low, LSB...MSB, Stopbit high

Dein Oszi sollte also so etwas zeigen
1
~~~~~~~_~____~~_~~~~~~~
2
3
.......S10000110S......

Das Startbit sollte bei 9600 baud 104µs breit sein.

Hoffentlich habe ich mich nicht verrechnet ;-)

von Florian S. (didi34)


Lesenswert?

>Hast du einen RS232-Pegelwandler zwischen µC und PC?

Ja der ist schon im SDK 500 integriert.

Der Signalverlauf sieht so aus, jedoch die länge des Startbits liegt ca. 
bei 45ms. Wie kann das sein?

von spontan (Gast)


Lesenswert?

Diese Zeilen sehen sehr eigenartig aus


>#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
>#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate


Hast Du die richtig abgeschrieben?

von Norbert (Gast)


Lesenswert?

Florian Schuller schrieb:
> Der Signalverlauf sieht so aus, jedoch die länge des Startbits liegt ca.
> bei 45ms. Wie kann das sein?

Nehmen wir an das die Quarzfrequenz korrekt ist, so ergibt sich eine 
UART Schrittgeschwindigkeit von 22,22 baud  ????

Nehmen wir an das der UART korrekt gesetzt ist, so ergibt sich eine CPU 
Frequenz von 9244,44 Hz ????

Ergibt beides keinen Sinn, also schauen wir auf den Controller.
Was ist es denn für einer und gibt's beim kompilieren irgendwelche 
Warnungen?

von Peter II (Gast)


Lesenswert?

kannst du erstmal verschen eine LED mit sekunden tankt (_delay_ms(1000) 
) blinken zu lassen?

von Stefan E. (sternst)


Lesenswert?

Vermutlich einer der Controller, bei denen sich UBRRH und UCSRC eine 
Adresse teilen. Dann geht nämlich dieses Schreiben
1
UCSRC = (1<<UCSZ1)|(1<<UCSZ0);
in Wirklichkeit nach UBRRH und die resultierende Baudrate ist damit sehr 
niedrig.

PS: Es ist immer eine gute Idee, von vornherein mit anzugeben, welchen 
Controller man benutzt.

von Florian S. (didi34)


Lesenswert?

Ich verwende den ATMEGA8 und habe es auch schon mit dem ATMEGA32 
versucht.


>kannst du erstmal verschen eine LED mit sekunden tankt (_delay_ms(1000)
>) blinken zu lassen?

Dies habe ich auch schon versucht und was eigenartiges bemerkt. Wenn die 
Takkfrequenz default 1 MHZ gesetzt ist, schaltet es jede Sekunde um. 
Jedoch bei 4 MHZ geht es viel schneller.

von Stefan W. (dl6dx)


Lesenswert?

spontan schrieb:
> Diese Zeilen sehen sehr eigenartig aus

Im Tutorial findest du die gleichen Makros:

UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)
BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))

Dort steht auch, wieso.

An den TO die Frage: Wie genau ist die Messung der Bitdauer von 45 ms? 
45 ms wären etwa 22,22 bit/s. (Hast du vermutlich auch schon 
ausgerechnet.)

Welches Zeichen sendest du für die Messung wiederholt? 0xAA oder 0x55?

Bei 0x55 hast du eine saubere Folge von 0 und 1:
1
S01234567S
2
0101010101

Bei 0xAA hast du am Anfang ein doppeltes "0"-Bit (Startbit und LSB) und 
am Ende eine doppelte "1" (MSB und Stopbit):
1
S01234567S
2
0010101011

0x55 wäre also der bessere Wert für den Timingtest. Versuch doch mal, so 
eine ununterbrochene 0-1-Folge hin zu bekommen und miss mal über 10 Bit.

Grüße

Stefan

von Stefan E. (sternst)


Lesenswert?

Florian Schuller schrieb:
> Ich verwende den ATMEGA8

Dann meinen Post oben lesen.

von spess53 (Gast)


Lesenswert?

Hi

>Ich verwende den ATMEGA8 und habe es auch schon mit dem ATMEGA32
>versucht.

Dann hast du, wie Stefan Ernst (sternst) schon bemerkt hat, das 
Umschaltbit vergessen

UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);

Ohne 1<<URSEL landet das ganze in UBRRH.

MfG Spess

von Norbert (Gast)


Lesenswert?

Aha, ein mega8!

Stefan hat Recht!

UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);

von Norbert (Gast)


Lesenswert?

ups...

von Florian S. (didi34)


Lesenswert?

spess53 schrieb:
> Hi
>
>>Ich verwende den ATMEGA8 und habe es auch schon mit dem ATMEGA32
>>versucht.
>
> Dann hast du, wie Stefan Ernst (sternst) schon bemerkt hat, das
> Umschaltbit vergessen
>
> UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
>
> Ohne 1<<URSEL landet das ganze in UBRRH.
>
> MfG Spess
 Danke das wars. Ich habe das noch von einem alten Projekt vom ATMEGA128 
herrausen gehabt.
Vielen Dank!

von spess53 (Gast)


Lesenswert?

Hi

>Danke das wars. Ich habe das noch von einem alten Projekt vom ATMEGA128
>herrausen gehabt.

Dort gibt es das nicht.

MfG Spess

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.