Forum: Mikrocontroller und Digitale Elektronik Newbe braucht Hilfe bei UART


von maini (Gast)


Lesenswert?

Hey! Ich wollte grade mal eine einfache UART Kommunikation zw. Atmega8 
und PC machen, allerdings bekomme ich nichts raus...
Als Hardware benutze ich das myAVR board mit dem mysmartUSB-Programmer. 
Aufm PC verwede ich Putty für die COM-Schnittstelle (mangels 
Hyperterminal unter Win7)...

Das Testprogramm hab ich aus dem Netz, weshalb ich noch frustrierter 
bin, dass es nicht klappt!
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
/* Prototypes */
5
void InitUART (unsigned char baudrate);
6
unsigned char ReceiveByte (void);
7
void TransmitByte (unsigned char data);
8
9
/* Main - simple program that recieves a character then
10
transmits back the next character.  An example would be if you send in an A, the chip will return a B */
11
int
12
main (void)
13
{
14
  unsigned char i;
15
  InitUART (95);               /* Set the baudrate to 2400 bps using a 3.6864MHz crystal */
16
  while (1)
17
    {
18
      TransmitByte (ReceiveByte () + 1);        /* Echo the received character + 1.  Example send in A then send out B */
19
      //for (i = 0; i < 200; i++);
20
    }
21
}
22
23
24
/* Initialize UART */
25
void
26
InitUART (unsigned char baudrate)
27
{
28
  /* Set the baud rate */
29
  UBRRL = baudrate;
30
31
  /* Enable UART receiver and transmitter */
32
  UCSRB = (1 << RXEN) | (1 << TXEN);
33
34
  /* 8 data bits, 1 stop bit */
35
  UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
36
37
}
38
39
/* Read and write functions */
40
unsigned char
41
ReceiveByte (void)
42
{
43
  /* Wait for incomming data */
44
  while (!(UCSRA & (1 << RXC)));
45
46
  /* Return the data */
47
  return UDR;
48
}
49
50
void
51
TransmitByte (unsigned char data)
52
{
53
  /* Wait for empty transmit buffer */
54
  while (!(UCSRA & (1 << UDRE)));
55
56
  /* Start transmittion */
57
  UDR = data;
58
}

Das Programm soll halt einfach nur einen empfangenen Char erhöhen und 
zurückgeben! Ich bekomme aber immer nur ein NULL zurück....

Was mach ich falsch?! Ich bin am Verzweifeln...

Greetz

von maini (Gast)


Lesenswert?

sry für den Double Post! Hab aber was vergessen:

An dem Programmer liegt es nicht, ich stelle den PID Schalter so ein, 
dass ich die Serielle Kom. erzwinge. Wenn ich mit Putty eine Eingabe 
sende, kommt diese (lt. LED) auch mindestens beim 
Programmer/Pegelwandler an...

nun aber

von Timer (Gast)


Lesenswert?

Die AVR Checkliste ist bereits abgearbeitet oder noch nicht?

von Nicolas I. (freeint)


Lesenswert?

Stimmt die Taktfrequenz?

Der Code wie du ihr gepostet hast sieht einen 3.6864MHz crystal vor. 
Wenn dein Atmega nicht mit 3.6864Mhz läuft, musst du den Wert für die 
InitUART(Wert) Funktion anpassen. Dafür gibts genügend Tabellen für alle 
erdenklichen Taktraten im Datenblatt des ATmega.

Liebe Grüße,
Nico

von Karl H. (kbuchegg)


Lesenswert?

maini schrieb:

> Das Testprogramm hab ich aus dem Netz, weshalb ich noch frustrierter
> bin, dass es nicht klappt!

Nicht alles was man 'irgendwo' im Netz findet, ist auch korrekt.
Anstatt irgendwo, schau lieber im AVR-GCC-Tutorial nach. Die dort 
angegebenen Codestückchen wurden getestet und wenn es Besonderheiten bei 
bestimmten Prozessoren gibt, dann wird auch darauf hingewiesen.

>   /* 8 data bits, 1 stop bit */
>   UCSRC = (1 << UCSZ1) | (1 << UCSZ0);


Gratuliere.
Damit ist die vorhergehende Einstellung der Baudrate überschrieben und 
nicht mehr gültig.

> Was mach ich falsch?!

Du klaust Codestückchen (oder ganze Programme), ohne sie zu verstehen 
und vor allen Dingen die Konfiguration mit dem Datenblatt deines 
Prozessors zu kontrollieren bzw. anzupassen.

> Ich bin am Verzweifeln...

musst du nicht. Einfach nicht jedem Code aus dem Netz trauen. 
AVR-GCC-Tutorial ist ein guter Anlaufpunkt für erste Codeteile, da 
dieses Tutorial rigoros von einer großen Cummunity kontrolliert wird. 
Und ansonsten: die einzige Autorität ist das Datenblatt zu deinem 
Prozessor.

von maini (Gast)


Lesenswert?

Hey! Die Checkliste bin ich mal eben durchgegangen, allerdings konnte 
ich dort keinen Fehler finden. Die Takfrequenz lässt sich mit dem dort 
geposteten Testprogramm als richtig einschätzen (die LED blinkt im 
Sekundentakt)!

Muss ich unter WIN im Gerätemanager auch die Richtige Baud für den COM 
Port einstellen? Hatte dies schon versucht, führte aber auch zu keinem 
Ergebnis...

von I. L. (Gast)


Lesenswert?

maini schrieb:
> /* Set the baud rate */
>   UBRRL = baudrate;
>
>   /* Enable UART receiver and transmitter */
>   UCSRB = (1 << RXEN) | (1 << TXEN);
>
>   /* 8 data bits, 1 stop bit */
>   UCSRC = (1 << UCSZ1) | (1 << UCSZ0);

Karl Heinz Buchegger schrieb:
> Gratuliere.
> Damit ist die vorhergehende Einstellung der Baudrate überschrieben und
> nicht mehr gültig.

Wieso? Das sind doch unterschiedliche Register?! Oder was meinst du?

Gruß Knut

von I. L. (Gast)


Lesenswert?

maini schrieb:
> Muss ich unter WIN im Gerätemanager auch die Richtige Baud für den COM
> Port einstellen?

Na sicha ;-)

maini schrieb:
> Hatte dies schon versucht, führte aber auch zu keinem
> Ergebnis...

Hast du ma oszillographiert was aus dem Pin rauskommt?



Knut

von Karl H. (kbuchegg)


Lesenswert?

I. L. schrieb:
> maini schrieb:
>> /* Set the baud rate */
>>   UBRRL = baudrate;
>>
>>   /* Enable UART receiver and transmitter */
>>   UCSRB = (1 << RXEN) | (1 << TXEN);
>>
>>   /* 8 data bits, 1 stop bit */
>>   UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
>
> Karl Heinz Buchegger schrieb:
>> Gratuliere.
>> Damit ist die vorhergehende Einstellung der Baudrate überschrieben und
>> nicht mehr gültig.
>
> Wieso? Das sind doch unterschiedliche Register?!

No, sind sie nicht.
Im Datenblatt die Beschreibung des URSEL Bit im UCSRC nachlesen!
Der Mega8 hat ein UBRRH und ein URSEL Bit im UCSRC.
Und
1
   UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
verändert NICHT das UCSRC.

von I. L. (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Im Datenblatt die Beschreibung des URSEL Bit im UCSRC nachlesen!

[Zitat]
 • Bit 7 – URSEL: Register Select
This bit selects between accessing the UCSRC or the UBRRH Register. It 
is read as one when
reading UCSRC. The URSEL must be one when writing the UCSRC.
[/]

Gilt doch nur für das UBRRH-Register. Er beschreibt doch aber das 
UBRRL-Register. Oder was übersehe ich grade?


Gruß Knut

von I. L. (Gast)


Lesenswert?

I. L. schrieb:
> The URSEL must be one when writing the UCSRC.

Jo, dass is es. Aber warum überschereibe ich denn UBRRL??? Im DB steht 
ich überschreiben dann das UBRRLH!

Karl Heinz Buchegger schrieb:
>>   /* 8 data bits, 1 stop bit */
>>   UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
>
>
> Gratuliere.
> Damit ist die vorhergehende Einstellung der Baudrate überschrieben und
> nicht mehr gültig.

Klär mich bitte auf


Gruß Knut

von Karl H. (kbuchegg)


Lesenswert?

I. L. schrieb:

>>>   /* 8 data bits, 1 stop bit */
>>>   UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
>>
>>
>> Gratuliere.
>> Damit ist die vorhergehende Einstellung der Baudrate überschrieben und
>> nicht mehr gültig.
>
> Klär mich bitte auf

Das hier

> Im Datenblatt die Beschreibung des URSEL Bit im UCSRC nachlesen!
> Der Mega8 hat ein UBRRH und ein URSEL Bit im UCSRC.
> Und
>    UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
> verändert NICHT das UCSRC.

verändert UBRRH(!) und nicht UCSRC

UBRRH und UBRRL bestimmen gemeinsam die Baudrate! Und damit hat die 
Zuweisung, so wie sie geschrieben wurde, keinen Einfluss auf UCSRC aber 
auf die Baudrate.
Zum Beschreiben des UCSRC muss beim Mega8 IMMER URSEL gesetzt sein. 
ANsonsten verändert man eben nicht UCSRC sondern das Baudratenregister, 
betsehend aus UBRRL und UBRRH.

von I. L. (Gast)


Lesenswert?

Ja, hast Recht. Ich glaube wir reden aneinander vorbei.
Du schriebst:


> UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
> Gratuliere.
> Damit ist die vorhergehende Einstellung der Baudrate überschrieben
> und nicht mehr gültig.

Nein, damit hat er nichts überschrieben, nur zusätzlich auch das UBRRH 
beschrieben. Ich habe dich da etwas missverstanden, ok!

Nichts für ungut...



Gruß Knut

von Christopher G. (cbg)


Lesenswert?

Jetzt streitet doch nicht über die Interpretation des Satzes - 
eigentlich über die Bedeutung von "überschreiben".
Fakt ist Karl Heinz hat das Problem erkannt und auf seine Weise indirekt 
angesporchen.
Einmal ins Datenblatt schauen um zu schauen worauf er hinaus will, 
Fehler korrigieren und "Danke, das wars" wäre in diesem Forum besser 
angebracht als ein Rhetorikkurs.

von Karl H. (kbuchegg)


Lesenswert?

I. L. schrieb:
> Nein, damit hat er nichts überschrieben, nur zusätzlich auch das UBRRH
> beschrieben.

Welchen Teil des Satzes (aus dem Datenblatt)

 The URSEL must be one when writing the UCSRC.

hast du nicht verstanden.

Das hier
1
  /* Set the baud rate */
2
  UBRRL = baudrate;
3
4
  /* Enable UART receiver and transmitter */
5
  UCSRB = (1 << RXEN) | (1 << TXEN);
6
7
  /* 8 data bits, 1 stop bit */
8
  UCSRC = (1 << UCSZ1) | (1 << UCSZ0);

ist 100% gleichwertig zu
1
  /* Set the baud rate */
2
  UBRRL = baudrate;
3
4
  /* Enable UART receiver and transmitter */
5
  UCSRB = (1 << RXEN) | (1 << TXEN);
6
7
  /* 8 data bits, 1 stop bit */
8
  UBRRH = (1 << UCSZ1) | (1 << UCSZ0);

Die letzte Zuweisung beschreibt NICHT UCSRC sondern das Register 
UBRRH. Es tut mir leid, aber das ist Faktum. Da gibt es nichts daran zu 
rütteln oder miszuverstehen.

>  nur zusätzlich auch das UBRRH beschrieben

nicht zusätzlich. Das eigentliche UCSRC wurde nie beschrieben!

von I. L. (Gast)


Lesenswert?

@Christopher

gucka ma:
I. L. schrieb:
> Ich habe dich da etwas missverstanden


Gruß Knut

von I. L. (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Die letzte Zuweisung beschreibt NICHT UCSRC sondern das Register
> UBRRH. Es tut mir leid, aber das ist Faktum. Da gibt es nichts daran zu
> rütteln oder miszuverstehen.

Ok, nochmal. Das er das UBRRH (unwissentlich) beschreibt ist mir 
bekannt.

Karl Heinz Buchegger schrieb:
> nicht zusätzlich.

natürlich, denn das hat er nie beschreiben wollen.
Er wollte das UBRRL beschreiben, hat nun aber (zusätzlich + 
unwissentlich) das UBRRH Register auch beschrieben. Das UCSRC hat er nie 
angerührt.

Nochmals...

I. L. schrieb:
> Ich habe dich da etwas missverstanden, ok!


Gruß Knut

von Karl H. (kbuchegg)


Lesenswert?

Das einzige was den TO jetzt noch gerettet haben könnte, ist die 
Reihenfolge. Der Baudratenteiler wird erst mit dem beschrieben von UBRRL 
tatsächlich upgedatet. Von daher könnte er tatsächlich die richtige 
Baudrate haben. Was nicht heißt, dass die Zuweisung korrekt ist. Die ist 
immer noch falsch, wirkt sich aber nicht direkt aus :-)
Insofern hatte ich also weiter oben unrecht.


>  allerdings bekomme ich nichts raus...

ist eine schwammige Formulierung. Das könnte auch ein falsch gekreuztes 
Kabel sein :-)
Warten wir mal ab, was das Abarbeiten der Checkliste ergibt. Am 
wahrscheinlichsten ist halt immer noch eine falsche Taktfrequenz.

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.