PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] USART Problem Atmega32



neo98
29.09.2011, 15:42
Hallo zusammen,

ich versuche schon seit einer Weile die Usart-Verbindung von meinem Atmega32 über das MySmartUsb mk2 auf die Reihe zu bekommen. Zum empfangen/senden benutze ich das HyperTerminal. Das was der Atmega sendet empfange ich auch, allerdings kann ich nichts an den Atmega senden da er offenbar aus der Lesefunktion rausspringt. Hier mal meine Einstellungen zwecks Baudrate und Lesefunktion(diese hab ich zugegeben aus der Asuro lib "geklaut").



#include <avr/io.h>

#ifndef MCU
#define MCU atmega32
#endif

#ifndef F_CPU
#define F_CPU 16000000
#endif

#include <util/delay.h>

#define USART_BAUD_RATE 9600
#define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16L)-1)

void SerRead (
unsigned char *data,
unsigned char length,
unsigned int timeout)
{
unsigned char i = 0;
unsigned int time = 0;
UCSRB = (1<<RXEN); // Empfaenger einschalten
if (timeout != 0)
{
/*
Die Funktion wird auf alle Faelle, auch ohne empfangene Daten, wieder
verlassen. --> nonblocking mode
*/
while (i < length && time++ < timeout)
{
if ((UCSRA & (1<<RXC)))
{
data [i++] = UDR;
time = 0;
}
}
if (time > timeout)
data [0] = 'T';
}
else
{
/*
Die Funktion wird auf alle Faelle erst nach dem Empfang von der
vorgegebenen Anzahl Zeichen verlassen. blocking mode
*/
while (i < length)
{
while(!(UCSRA & (1<<RXC)));
data [i++] = UDR;
}
}
}

int main()
{
unsigned char data[4];

UBRRH = (unsigned char) (USART_BAUD_SELECT>>8);
UBRRL = (unsigned char) USART_BAUD_SELECT;
UCSRB = (1 << RXEN) | (1 << TXEN);
UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);

SerRead(data, 2, 0);
//...weiterer Code
}

Schreibe ich in die letzte while-Schleife der SerRead-Funktion rein, dass bei jedem Durchlauf/bei jeder Abfrage eine "hallo" gesendet wird, werd ich "zugespammt". Wenn ich das nicht tue, wird einfach der weitere Code ausgeführt und nichts gelesen.

markusj
29.09.2011, 20:46
[...]


{
/*
Die Funktion wird auf alle Faelle erst nach dem Empfang von der
vorgegebenen Anzahl Zeichen verlassen. blocking mode
*/
while (i < length)
{
while(!(UCSRA & (1<<RXC)));
data [i++] = UDR;
}



Da ist der Fehler: In der While-Schleife prüfst du, ob das RXC-Bit NICHT (!!!) gesetzt ist, du möchtest eigentlich das Gegenteil machen (Abbruch wenn das Bit gelöscht ist, sonst weitermachen).

mfG
Markus

neo98
29.09.2011, 21:15
Ich würde sagen dass das so richtig ist. Hast du das ';' hinter der Schleife gesehen? (Der Code ist falsch eingerückt) Die Schleife wird solang ausgeführt bis RXC gesetzt ist. Steht auch so in der Doku...

markusj
30.09.2011, 11:19
Mea culpa, du hast recht. Das kleine Semikolon habe ich doch glatt übersehen. Später gehe ich den Code nochmal durch, jetzt ist erstmal Klausur schreiben angesagt.

mfG
Markus

markusj
30.09.2011, 19:24
Ich kann in dem Code keinen Fehler erkennen, ABER: SerRead schreibt den Wert von UCSRB neu (und macht dabei den Transmitter aus). Evtl. gibt es in anderen Codeteilen ähnliche Seiteneffekte.

mfG
Markus

seite5
01.10.2011, 14:53
Hallo,
in main() ist beim serread-aufruf das timeout auf 0 gesetzt ?!
mein Compiler würde auch in dem Ausdruck while (i < length && time++ < timeout) ein paar Klammern anfordern,
aber das ist wohl von Compiler zu Compiler unterschiedlich.
mfg
Achim

neo98
06.10.2011, 15:45
@markusj: Ich habs mal rausgenommen, und siehe da, mein Atmega kann auf einmal warten. ;) Aber warum wird dabei der Transmitter(du meinst Empfänger oder?) ausgeschaltet? RXEN wird doch nur nochmal auf 1 gesetzt.
@seite5: Ich hab jetzt mal die Klammern gesetzt, aber auch ohne bekomm ich keine Warnung/Fehler.

Immerhin wartet der Atmega jetzt, allerdings liest er nicht, sondern bleibt immer an der stelle stehn egal was ich ins HyperTerminal eintippe. Mein mySmartUsb zeigt an das Daten gesendet werden, die ignoriert mein Atmega aber anscheinend. Beim anschließen hab ich am Anfang nicht gewusst dass man RxD und Txd kreuzen muss, kann es sein das es mir dabei einen Pinn verheizt hat?

markusj
06.10.2011, 19:57
Nein, RXEN wird nicht einfach gesetzt, das Register wird neu beschrieben und NUR RXEN dabei gesetzt. (da steht = und nicht |= ...)
Die ASURO-Routinen sind nicht auf Duplex-Betrieb ausgelegt, entweder sie senden oder sie Empfangen und nehmen daher keine Rücksicht aufeinander. gleichzeitiges Senden und Empfangen ist nicht vorgesehen!

Wenn das Empfangen nicht klappt, stimmt entweder die Verdrahtung nicht, die eingestellte Baudrate, der Takt des AVRs ist zu ungenau oder du hast tatsächlich den Pin gegrillt.
Äh moment, WAIT: Du setzt RXEN jetzt gar nicht? Dann funktioniert das natürlich auch nicht ... du musst UCSRB |= (1 << RXEN); machen!

mfG
Markus

neo98
06.10.2011, 22:13
1. Heißt das jetzt dass TXEN oder RXEN nicht gleichzeitig gesetzt sein dürfen? Komm grad nicht ganz mit was du meinst... (Entweder sende ich oder ich empfange)
2. Verdrahtung: Ich hab mal meinen 2. Atmega rausgekramt und den angeschlossen, genau das selbe. Bin mir ziemilch sicher das ich alles richtig angeschlossen habe, da ich schließlich am PC empfangen kann. Und empfange tu ich genau das was der Atmega sendet, also müsste die Baudrate ja auch übereinstimmten (sonst Kauderwelsch oder nicht) und dann denke ich müsste der Takt auch ungefähr stimmten. Pin kann ja jetzt auch fast nicht mehr hinüber sein da ja neuer Atmega.

Vielleicht sollte ich mal den ganzen Code posten??

Ich bekomm hier gleich die Krise:eek:

markusj
07.10.2011, 10:40
Es können TXEN und RXEN sehr wohl gleichzeitig gesetzt sein, (das ging nur beim ASURO nicht sinnvoll), das Problem besteht darin, dass du eben NUR das Bit RXEN setzen (bzw. evtl auch wieder löschen) möchtest, und nicht alle anderen Bits im Register gleich mit.

Gleichzeitiges Senden/Empfangen funktioniert aber nur, wenn eine der beiden Aufgaben in einer Interruptroutine behandelt wird, oder du deinen Code etwas komplexer gestaltest ...

mfG
Markus

neo98
07.10.2011, 13:13
Ich hab jetzt nochmal rumprobiert und es geht immer noch nichts. Ich hab auch mal die Codebeispiele von http://www.rn-wissen.de/index.php/Sourcevergleich ausprobiert. Aber empfangen tut der Atmega absolut nichts. Ich hab jetzt noch bemerkt dass das was ich sende sofort wieder zurückkommt und im HyperTerminal angezeigt wird, auch wenn ich das nicht einprogrammiert hab. Ich denke das einzigste was noch übrig bleibt ist das es den Pin am mySmartUSB-Board gegrillt hat...

sternst
07.10.2011, 14:27
Verlässt denn das, was du sendest, überhaupt den PC?
Hast du in HyperTerminal die Hardware-Flusskontrolle abgeschaltet?

neo98
07.10.2011, 15:27
Das mySmartUSB zeigt durch ein kurzes aufflackern der LED an ob Daten übertragen werden. Und das tut es auch.

sternst
07.10.2011, 15:55
Und verlassen die Daten dann auch das mySmartUSB? Wie verhält sich das Teil, wenn die Schnittstelle mit Hardware-Flusskontrolle konfiguriert ist?

Kontrolliere die entsprechende Einstellung in HyperTerminal!

Richard
07.10.2011, 16:20
Ich hab jetzt nochmal rumprobiert und es geht immer noch nichts. Ich hab auch mal die Codebeispiele von http://www.rn-wissen.de/index.php/Sourcevergleich ausprobiert. Aber empfangen tut der Atmega absolut nichts. Ich hab jetzt noch bemerkt dass das was ich sende sofort wieder zurückkommt und im HyperTerminal angezeigt wird, auch wenn ich das nicht einprogrammiert hab. Ich denke das einzigste was noch übrig bleibt ist das es den Pin am mySmartUSB-Board gegrillt hat...

Wenn im Hyper Terminal unter Einstellungen "Echo" aktiviert ist, wird alles was eingegeben wird auch gleich wieder ausgegeben. Das wir z.B. gemacht wenn Daten an ein Gerät gesendet werde das nur lesen aber nicht senden kann, um sehen zu können was man gesendet hat. Um zu sehen ob der µC empfängt und auch sendet, kann man RX und TX eine LED mit passenden Widerstand Parallel schalten. Man muss dann natürlich eine sehr langsame Baudrate wählen um das Blinken im Takt der Daten sehen zu können.Bei einem Kurzschluss zwischen RX/TX bekommt man allerdings auch ohne Aktiviertes "Echo" sofort eine Rückmeldung, der PC "Spricht" dann mit sich selber.....

Der häufigste Fehler den auch "alte Hasen" immer gerne machen, vertauschte Daten Leitungen....richtig ist hier.

µC Wandler PC
TX>>>>Wandler>>>>>RX
RX<<<<Wandler<<<<<TX
GND...........................GND

Grüße Richard

neo98
07.10.2011, 17:01
TX>>>>Wandler>>>>>RX
RX<<<<Wandler<<<<<TX
GND...........................GND


TX und RX hab ich gekreuzt aber GND hab ich gar nicht erst angeschlossen. Jetzt läufts genau so wie es laufen soll, ich glaubs ja nicht... jiiihhaaaaaa :-)

vielen vielen Dank an alle

P.S.: Wie kann ich das Thema als Erledigt kennzeichnen?

markusj
07.10.2011, 18:41
m(

Erledigen kannst du das Thema irgendwo bei den Themen-Optionen, wenn ich mich richtig erinnere.

mfG
Markus