Forum: Mikrocontroller und Digitale Elektronik UART beim atmega8 - Software-Denkfehler oder Hardwareproblem?


von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

Hi!

Meine Schaltung tut in Zusammenhang mit meinem Code nicht das, was ich 
will. Ich hab mit verschiedenen Tutorials gearbeitet und den Code im 
Anhang zusammengestellt. Steckt vielleicht da ein Denkfehler drin oder 
hab ich doch ein Hardwareproblem in der Schaltung?

Am Anfang leuchten beide LEDs -> PD7 und PD4.
Jetzt schicke ich übers Hyperterminal ein Zeichen (z.B. "a"). Erst löst 
der RXC-Interrupt aus und toggelt die eine LED, anschließend soll das 
selbe Zeichen wieder geschickt werden (wird wieder in UDR zurück 
geschrieben) und im TXC-Interrupt die zweite LED getoggelt werden. Das 
passiert so schnell, dass die LEDs scheinbar "gleichzeitig" toggeln. Das 
funktioniert an sich auch.

Nur: es kommt im Hyperterminal nix an. Hin und wieder schiebt er mal ein 
Leerzeichen ein. Zudem kommt es zu unbestimmter Zeit/ nach unbekannt 
vielen Zeichen (Zufall?) dazu, dass die LEDs komplementär leuchten. 
Irgendwo ist eine Fehlerquelle.

Ich verwende einen 16-MHz-Quarz (Atmel Evaluations-Board Version 2.0.1) 
und eine Baudrate von 9600 (vgl. Sourcecode). Das sollte einigermaßen 
fehlerfrei funktionieren: http://www.wormfood.net/avrbaudcalc.php

Die UART-Schnittstelle an sich funktioniert am Rechner: RX und TX 
zusammenschließen an der Leitung geht; auch nach dem MAX232 auf dem 
Board gehts noch. Bleibt also noch der Controller (mit Code) und ein 
bisserl Verkabelung.

Habt ihr Ideen für mich?
Vielen Dank im Voraus!

von Matthias (Gast)


Lesenswert?

kleiner Nachtrag:

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=48188
Daran hab ich mich unter anderem orientiert.

»Over to it. However, we can now remove the two while loops - since the 
ISR only fires when a byte is received, and only one byte is sent after 
each reception we can guarantee that both checks are now redundant. When 
the ISR fires we know that there is both a byte received in the USART 
input buffer, as well as nothing in the output buffer. Using this 
knowledge, we can simplify our ISR code to the following [...]«

Ist es vielleicht doch diese Annahme, die das ganze etwas wackelig 
dastehen lässt?

von Bill (Gast)


Lesenswert?

tag,


ich bin da jetzt nicht so der crack, aber ich mache das anders, weiss 
also nicht warum es nicht funtktionert.

im RX interrupt würde ich das empfangene in ein volatile char speichern 
und noch ein empfangsflag setzen.
ausserhalb vom INT dann eine funktion aufrufen die den UDRE Interrupt 
einschaltet und das zu sendende zeichen in ein sendepuffer schreibt.
1
// UDRE Interrupt einschalten
2
UCSR0B |= (1 << UDRIE0);
3
4
5
// darauf reagieren mit diesem INT:
6
7
ISR(USART0_UDRE_vect) {
8
9
//sendepuffer in UDR
10
}

von Bill (Gast)


Lesenswert?

sorry der flag muss volatile sein nicht der emfangspuffer, sry!

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Habt ihr Ideen für mich?
Probiers doch mal so, dass du erst mal die eine Richtung testest 
(uC->PC), dann die andere (PC-uC).

Mach also im uC eine Routine, die immer ein Zeichen (oder eine 
Zeichenkette sendet). Wenn du die am PC empfangen kannst, bist du bereit 
für die nächste Stufe: sende ein Zeichen vom PC und gib das auf 8 LEDs 
aus.

Ein Tipp:
nimm NICHT Hyperterminal für solche Spielereien. Eine Suche hier im 
Forum (+hyperterm* +problem*) zeigt dir mit fast 1000 Treffern auf, 
wieso :-/

Ich verwende OCConsole und HTERM.

von Bill (Gast)


Lesenswert?

stimmt mit HT hatte ich auch mal probleme.

ich nutze python und pyserial.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

>> #define F_CPU 160000000L
160 000 000

160 MHz? Krass!

von Oliver (Gast)


Lesenswert?

>Habt ihr Ideen für mich?

Jeder einzelnen Compilerwarnungen nachgehen (wobei die je nach Optionen 
nicht alle angezeigt werden)
1
In file included from main.c:3:
2
c:/programme/winavr/lib/gcc/../../avr/include/util/delay.h:85:3: warning: #warning "F_CPU not defined for <util/delay.h>"
3
c:/programme/winavr/lib/gcc/../../avr/include/util/delay.h:90:3: warning: #warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"
4
* main.c, line 5: 1: warning: "F_CPU" redefined
5
c:/programme/winavr/lib/gcc/../../avr/include/util/delay.h:86:1: warning: this is the location of the previous definition
6
main.c: In function 'main':
7
* main.c, line 33:  warning: large integer implicitly truncated to unsigned type

Die haben alle mit deinem Problem zu tun, die letzte hätte dich auf das 
Problem aufmerksam gemacht. Denn das ist ein Fehler, den man selber 
niemals findet.
1
#define F_CPU 160000000L

Zähl mal die Nullen...

Oliver

von Johannes M. (johnny-m)


Lesenswert?

Der ATMega8 ist nur bis 16 MHz spezifiziert. Ein 10-faches Übertakten 
mit 160 MHz macht der sicher nicht mit...

EDIT:
Hmmm... Zu spät.

von Matthias (Gast)


Lesenswert?

Ups.. ja 160 MHz wären dann doch ein bissl viel.
Aber dann hätte meine Blinke-LED (die ich mal in der main-Loop hatte + 
dafür die delay) auch 10mal so schnell blinken müssen. g Und das wäre 
schon aufgefallen. F_CPU war also bei mir auch schon im Makefile 
definiert. Da sollte man dann vielleicht ein wenig mit dem Präprozessor 
arbeiten und Compiler-Warnungen nicht ignorieren, stimmt. Die hatte ich 
gar nicht entdeckt, weil das ziemlich schnell wegscrollt. Werde ich in 
Zukunft drauf schauen, merci.

Auch die weiteren Ideen bringen schon mal Versuchsansätze, die ich 
ausprobieren werde. Danke!

von Johannes M. (johnny-m)


Lesenswert?

Matthias wrote:
> Aber dann hätte meine Blinke-LED (die ich mal in der main-Loop hatte +
> dafür die delay) auch 10mal so schnell blinken müssen.
Eher im Gegenteil! Wenn die Baudrate so eingestellt ist, als ob der µC 
mit 160 MHz läuft, er aber in wirklichkeit nur mit 16 MHz tickt, dann 
käme ein 10-mal zu langsames Blinken raus.

Allerdings kommt ja bei der Baudratenberechnung schon Müll raus, d.h. in 
UBRRH/L steht ein unsinniger Wert. Deshalb ist das Verhalten gar nicht 
so trivial.

von Oliver (Gast)


Lesenswert?

>Aber dann hätte meine Blinke-LED (die ich mal in der main-Loop hatte +
>dafür die delay) auch 10mal so schnell blinken müssen.

Wenn du, wie oben in deinem Programm, F_CPU erst nach delay.h definiert 
hast, nicht.

Oliver

von Matthias (Gast)


Angehängte Dateien:

Lesenswert?

Hey zusammen!

Ein kleines Update von mir. Habe eben wieder Zeit zum "entwickeln" 
gehabt. g Dabei hab ich den Quellcode einfach mal entsprechend auf den 
wichtigen Teil gekürzt. Davor hab ich das alte auf dem µC noch mal im 
Terminal getestet, da kam ziemlicher Buchstabensalat (was ja eigentlich 
auf Unstimmigkeiten mit der Taktfrequenz bzw. der Baudrate schließen 
ließe glaube ich). Mit der aktuellen Version geht's momentan aber (gut, 
ich toggle zwei LEDs auf dem Board). Das Problem, dass die LEDs 
teilweise unterschiedlich leuchten ist dennoch reproduzierbar (beim 
Rollen über die Tastatur z.B.; Anschlag auf einer Taste ist kein 
Problem).

Immerhin etwas.. darauf lässt sich jetzt evtl. wieder Stück für Stück 
dranbauen und schauen, ob es noch funktioniert, wie es soll!

Gruß

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.