Forum: Mikrocontroller und Digitale Elektronik Atmega8 USART Unsauber


von Thomas (Gast)


Angehängte Dateien:

Lesenswert?

Servus,

ich versuche mich grade mit dem Atmega8 und der seriellen
Kommunikation.
Folgender Programmablauf ist gedacht.
Es wird ein Zeichen über die Serielle-Schnittstelle gelesen.
Handelt es sich um eine Eins, werden LED's geschalten und über die
Serielle Schnittstelle "LED" ausgegeben.
Handelt es sich um ein anderes Zeichen, so wird dieses Zeichen über die
Serielle Schnittstelle ausgegeben.

Es funktioniert teilweise - meistens gibt er nur "Müll" zurück, wirre
Zeichenketten etc.

Kann es vielleicht auch daran liegen, das mein MAX232 nicht genügend
Spannung bekommt? Versorgung ist über 9V Block und 7805.

Gruß und vielen Dank fürs durchschauen -> Programm im Anhang

von dave (Gast)


Lesenswert?

9V Block ist wohl nicht die beste Stromversorgung..

nen Anfang wäre vielleicht in der letzten Zeile bei transmit: das RETI
zu nem RET zu machen..

dave

von Thomas (Gast)


Lesenswert?

Hi

Klar - dort sollte ein RET stehen. Aber wenn ich da einen RET hinmache,
dann macht er noch weniger :( Hatte ich schon versucht. Trotzdem danke.

von Thorsten (Gast)


Lesenswert?

Meß mal die Versorgunsspannung, ob se auch wirklich so ca. 5V ist.

von Thomas (Gast)


Lesenswert?

Es klingt vielleicht wirklich blöd, aber ich hab nichts zum Messen da :)

Habe meine Hobby-Elektronik Werkstatt vor Beginn der Technikerschule
aufgegeben. Und jetzt, drei Wochen vor Ende der Technikerschule, hat
mich das Elektronik-Fieber richtig gepackt ;-)

von Thorsten (Gast)


Lesenswert?

Ein Techniker gibt ne Elektronikwerkstatt auf? Verstehe ich nicht...

von dave (Gast)


Lesenswert?

Wie im Tutorial hier:
        ; Frame-Format: 8 Bit
        ldi temp, (1<<URSEL)|(3<<UCSZ0)
        out UCSRC, temp

Außerdem.. haste auch die Taktquelle auf extern umgelegt?

Ist kräftig unlogisch, dass er weniger macht, wenn du das RET
reinsetzt.. ich denke mal, dass er dann jedesmal einen IRQ auslöst,
wenn du sendest..

dave

von Ralf K. (Gast)


Lesenswert?

Hi Thomas,
kenne das Problem leider zu gut.
Hört sich verdammt nach eingestellter Übertragungsrate an.
Mußt du ausprobieren.

z.b. beim ATmega8 hatte ich nur Erfolg bei 4800 Baud bei 1Mhz.
Es hängt von der Taktfrequenz ab.
Natürlich kommen auch andere Fehlerquellen in Frage.
Nur wenn ich bislang wirre Zeichen empfing, dann lag es immer an der
Baudrate.

Viel Glück
lg Ralf

von Thomas (Gast)


Lesenswert?

Servus

Taktquelle ist extern auf 4MHz Quarz.

Ich habe noch einen LED-Blinker eingeaut, der alle 200ms eine LED
schaltet. Wenn ich transmit mit einem RET beende, dann bleibt sogar der
Blinker stehen ?!? HILFE !!!

110baud ... 4800 baud bringen keine Verbesserung.

Ich bin mir fast sicher, das es an der Versorgungsspannung hapert.
Werde morgen mal mit einem Netzgerät noch einen Anlauf starten.

von A.K. (Gast)


Lesenswert?

> r16,3686400/(9600*16)-1
und
> Taktquelle ist extern auf 4MHz Quarz.
passen nicht recht zusammen.

von Thomas (Gast)


Lesenswert?

Mit 4MHz meinte ich die 3686400. Das passt doch, oder?

von A.K. (Gast)


Lesenswert?

Also was hat der Quarz denn nu? 3,6 oder 4,0MHz? Ist bei serieller
Kommunikation nicht ganz unwichtig.

von A.K. (Gast)


Lesenswert?

RETI ist übrigens schon richtig, denn sonst bleibt nach den ersten
Interrupt derselbige abgeschaltet.

von Thomas (Gast)


Lesenswert?

3686400Hz

Warum RETI - Ich rufe aus einem Interrupt eine Subroutine mittels rcall
auf. Ich bin mir jetzt nicht sicher wie der rcall auf dem ATMEGA
arbeitet.

Beim 8086 werden z.B. bei Rücksprung aus einem Interrupt 2 Wörter vom
Stack gelesen. Hingegen beim Unterprogramm nur 1 Wort.

Daher komme ich hier beim RET und RETI durcheinander. Hast Du weitere
Informationen, warum der Interrupt abgeschaltet bleibt?

von dave (Gast)


Lesenswert?

Deine Routine LED muss natürlich am Ende ein RETI bekommen.. Transmit
ein RET..

dave

von Thorsten (Gast)


Lesenswert?

Auszug aus "AVR Instruction Set":

RETI:
Returns from interrupt. The return address is loaded from the STACK and
the Global Interrupt Flag is set.

RET:
Returns from subroutine. The return address is loaded from the STACK.
The Stack Pointer uses a pre-increment scheme
during RET.

> Hast Du weitere Informationen, warum der Interrupt abgeschaltet
> bleibt?

Ist halt so implementiert.

von A.K. (Gast)


Lesenswert?

Bei Transmit gehört wirklich RET rein. Beim "led:" Teil aber gehört
RETI rein - das ist ja kein Unterprogramm.

Allerdings ist das nicht das Problem, weil Du zwar die Interrupts an
der falschen Stelle einschaltest, aber immerhin passiert es.

von Thomas (Gast)


Lesenswert?

@dave - bitte um Erklärung!

von A.K. (Gast)


Lesenswert?

Andere Frage: Du hast den Quarz-Oszillator schon eingeschaltet, also die
Fuses entsprechend gesetzt?

von dave (Gast)


Lesenswert?

Der Interrupt löscht das I-Flag.. RETI setzt es..

du springst bei 1 in LED.. also hast du 2 Orte, wo du zurückspringst..
an die 2 Orte müssen dann natürlich RETIs...
Transmit braucht kein I-Flag.. das soll schön gelöscht bleiben.

dave

von Thomas (Gast)


Lesenswert?

@AK: Fuses sind gesetzt - wie im Tutorial beschrieben.

@Dave: aha...Ich rufe aber doch LED genauso auf wie transmit. Oder muss
ich unterscheiden, wenn ich was aus einer Interrupt-Routine aufrufe?

von dave (Gast)


Lesenswert?

receive:
in data,udr
ldi temp,'1'
cp data,temp
breq led
mov send, data
rcall transmit
reti

Mir kommt das eher so vor ;) als würdest du nur bedingt SPRINGEN und
nicht AUFRUFEN.. breq ist "wenn gleich, dann RJMP"

dave

von Thomas (Gast)


Lesenswert?

Also besser so?

;-------------------------
receive:
  clr  temp
  in  data,udr
  ldi  temp,'1'
  cp  data,temp
  brne  end
  rcall  led
end:
  mov    send, data
  rcall  transmit
reti
;-------------------------
led:
  com    otemp
  ...
ret
;-------------------------


Nochmal zum Verständnis. Wo ich vorher die Routine LED mit reti beendet
habe, bin ich gleich wieder komplett aus dem interrupt raus und nicht
erst zurück in receive?!

Funktioniert so aber auch nicht. Ich werde zusammenpacken und auf das
Netzgerät warten.

Gruß

Thomas

von Thomas (Gast)


Lesenswert?

Und nochmal!

Es muss an der Spannung liegen - selbst das Testprogramm aus dem
Terminal schaut so aus:

Test!
     st!
Tes
Test!
Testá

Test!
Test!
Test
Tesô!
Test!
Te
Test!
     Test!
Ôst!

von A.K. (Gast)


Lesenswert?

> Nochmal zum Verständnis. Wo ich vorher die Routine LED mit
> reti beendet habe, bin ich gleich wieder komplett aus dem
> interrupt raus und nicht erst zurück in receive?!

Ist die Doku vom RETI sooo unverständlich? Oder ist bloss dein Englisch
so gut wie mein Altgriechisch? In letzterem Fall wirst Du mit
Microcontrollern deine liebe Not haben.

von Thomas (Gast)


Lesenswert?

Es tut mir leid, dass ich damit "The Stack Pointer uses a pre-increment
scheme during RET" nichts anfangen kann!

von Simon Küppers (Gast)


Angehängte Dateien:

Lesenswert?

siehe anhang. meine verbesserungsvorschläge

von Thomas (Gast)


Lesenswert?

Es geht!!!

Es lag also wirklich an der Spannungsversorgung!

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.