Forum: Mikrocontroller und Digitale Elektronik µC sendet ungefragt Daten via UART


von Dawamaha (Gast)


Lesenswert?

Hallo zusammen,
ich möchte ein Porgramm schreiben, welches über UART Befehle vom PC 
empfängt und diese dann bestätigt, indem er den Befehl zurücksendet. Das 
soll geschehen, nachdem ein NewLine gesendet wird. Da das nicht 
funktioniert und da nur wirre Bytes zurückkommen, habe ich erstmal 
versucht, dass der µC einfach ein 'Y' zurücksendet, sobald er das Byte 
13 empfangen hat. Dies soll mit folgendem Code geschehen:
1
 
2
.include "m8def.inc"
3
 
4
.def temp = R16
5
6
.equ F_CPU = 3686400
7
8
.equ BAUD  = 9600
9
 
10
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)
11
12
.cseg
13
.org 0x00
14
        rjmp main
15
 
16
.org URXCaddr
17
        rjmp int_rxc
18
 
19
 
20
main:
21
 
22
    ldi     temp, HIGH(RAMEND)
23
    out     SPH, temp
24
    ldi     temp, LOW(RAMEND)
25
    out     SPL, temp
26
 
27
 
28
    ldi     temp, HIGH(UBRR_VAL)
29
    out     UBRRH, temp
30
    ldi     temp, LOW(UBRR_VAL)
31
    out     UBRRL, temp
32
 
33
 
34
    ldi     temp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)
35
    out     UCSRC, temp
36
 
37
    sbi     UCSRB, RXCIE
38
    sbi     UCSRB, RXEN
39
  sbi    UCSRB, TXEN
40
    
41
    sei
42
    
43
loop:
44
    rjmp loop
45
 
46
int_rxc:
47
    push    temp
48
    in      temp, UDR       
49
    cpi    temp  ,  13
50
    breq  return
51
int_rxc2:
52
    pop     temp
53
    reti
54
55
return:  sbis  UCSRA  ,  UDRE
56
    rjmp  return
57
    ldi    r16    ,  'Y'
58
    out    UDR    ,  r16
59
    rjmp  int_rxc2

Nach dem ersten NewLine werden aber zuerst 8 Bytes (64 35 40 21 42 54 5A 
22) gesendet, nachdem dann das Y kommt. Bei weiteren NewLines kommt nur 
das Y zurück.
Wie lässt sich das erklären?

Danke im Voraus,
Dawamaha

von Zapp (Gast)


Lesenswert?

Huuuuiiiii,
Der Interrupt sollte das Statusregister zuerst sichern, sonst ist ganz 
schlecht. Und im Interrupt zu warten ist noch viel schlechter... in die 
Tonne. Das ist alles ganz falsch.

Schau dir mal http://www.ibrtses.com/embedded/avrasmuartint.html an. 
Vielleicht ist da was brauchbares dabei.

von Dawamaha (Gast)


Lesenswert?

> Der Interrupt sollte das Statusregister zuerst sichern
In diesem Fall sehe ich dafür keine Notwendigkeit, da eine 
Endlosschleife kein Statusregister braucht.

> in die Tonne. Das ist alles ganz falsch.
Anscheinend nicht, denn es funktioniert ja, nur nicht beim ersten Mal!

von Reinhard Kern (Gast)


Lesenswert?

Dawamaha schrieb:
>> Der Interrupt sollte das Statusregister zuerst sichern
> In diesem Fall sehe ich dafür keine Notwendigkeit, da eine
> Endlosschleife kein Statusregister braucht.

Wenn das deine Auffassung vom Programmieren ist, hat es keinen Sinn dir 
was zu raten. So kann man nur scheitern.

Gruss Reinhard

von Lehrmann M. (ubimbo)


Lesenswert?

Dawamaha (Gast) - darf ich dir mal was sagen?

DU bist hier der Hilfesuchende. Und ich gebe dir den guten Rat auf 
Reinhard und den Vorposter Zapp zu hören. Das sind Menschen die viel 
Ahnung & Erfahrung haben (Reinhard zumindest). Deinem Code nach zu 
urteilen hast du die nicht. Es ist immer schlecht den Meistern zu 
widersprechen weil sie es einfach besser können - und schon garnicht 
wenn man selber nicht einen Hauch Plan von der Materie hat.

Und wenn du nicht weiterhin so lausige Codes programmieren willst über 
die sich das Forum hier schräg lacht dann würde ich schleunigst damit 
beginnen das zu beherzigen und nicht besserwisserisch rumzuposten.

von Peter R. (gelb)


Lesenswert?

@  Reinhard Kern (Firma: RK elektronik GmbH) (rk-elektronik)
@  Lehrmann Michael (ubimbo)

Was spielt Ihr euch so auf? Tipps von (selbsternannten) Gurus sind zu 
befolgen, sonst Bann? Ihr seid doch nicht der Papst! (und wenn...)

Die Aussage von Dawamaha (Gast)

> In diesem Fall sehe ich dafür keine Notwendigkeit, da eine
> Endlosschleife kein Statusregister braucht.

ist völlig korrekt. Das Statusregister in einer ISR zu sichern bringt 
nix, wenn es woanders nicht gebraucht wird. Nicht eimal das 
temp-Register müsste gesicher werden.

Grüße, Peter

von spess53 (Gast)


Lesenswert?

Hi

>> Der Interrupt sollte das Statusregister zuerst sichern
>> In diesem Fall sehe ich dafür keine Notwendigkeit, da eine
>> Endlosschleife kein Statusregister braucht.

>Wenn das deine Auffassung vom Programmieren ist, hat es keinen Sinn dir
>was zu raten. So kann man nur scheitern.

Nein. Wo er Recht hat, hat er Recht.

>Und wenn du nicht weiterhin so lausige Codes programmieren willst über
>die sich das Forum hier schräg lacht dann würde ich schleunigst damit
>beginnen das zu beherzigen und nicht besserwisserisch rumzuposten.

Du hast dich hier auch noch nicht mit Ruhm bekleckert. Diese 
Zurechtweisung deinerseits ist total unangebracht.
Der Code ist als Testprogramm absolut OK. Im Simulator läuft er auch 
wie angedacht. Das beschriebene Verhalten ist im Moment für mich nicht 
nachvollziehbar.

MfG Spess

von Zapp (Gast)


Lesenswert?

Was soll die Warteschlaufe im Interrupt ?

return:
 sbis  UCSRA  ,  UDRE
 rjmp  return


Es gibt keine Warteschlaufen in einem Interrupt. So einfach ist das.

von spess53 (Gast)


Lesenswert?

Hi

>return:
> sbis  UCSRA  ,  UDRE
> rjmp  return

>Es gibt keine Warteschlaufen in einem Interrupt. So einfach ist das.

Wo steht das? Im Einzelfall kann das durchaus legitim sein. Regeln sind 
dafür da, gebrochen zu werden.

Im obigen Programm ist es mehr als eine Sicherheitsabfrage zu werten. 
Die Wahrscheinlichkeit, das nach mehreren empfangenen Bytes das Senden 
blockiert ist, geht gegen Null.

MfG Spess

von Reinhard Kern (Gast)


Lesenswert?

Peter Roth schrieb:
> ist völlig korrekt. Das Statusregister in einer ISR zu sichern bringt
> nix, wenn es woanders nicht gebraucht wird. Nicht eimal das
> temp-Register müsste gesicher werden.

Hallo Peter,

wer immer eine main routine schreibt, muss sich drauf verlassen können, 
dass ein Interrupt NICHTS verändert. Und die Behauptung "ich brauche das 
nicht, weil ich alle meine Codezeilen im Kopf habe" ist in 99% der Fälle 
nur Einbildung, von einer Zusammenarbeit mehrerer Leute mal garnicht zu 
reden.

Anwesende natürlich ausgenommen, du persönlich hast ohne jeden Zweifel 
die 100000 Zeilen eines grösseren Programms jederzeit präsent und kannst 
dich daher über uns alte Trottel lustig machen.

Gruss Reinhard

von Carsten S. (dg3ycs)


Lesenswert?

Hallo Reinhard,

Natürlich hast du mit deiner Argumentation grundsätzlich recht!
Warteschleifen in Interrups oder auch das nichtsichern von solch 
elementaren Registern ist eigendlich ein schlechter Programmierstil.
Auch wenn es erst einmal unnötig erscheint...

Nur Bringt es -gerade dem Einsteiger- nichts einfach wie "Zapp" zu sagen 
das ist "Mist", besonders wenn es mit dem hier vorliegenden Problem 
ersteinmal nichts zu tun hat - und für jemanden ohne diese Vorkenntnisse 
ebend NICHT ersichtlich ist warum man nun zu dieser Aussage kommt.

Wenn man auf eine "konkrete" Problemanfrage eines "Einsteigers" mit 
solchen allgemeinen Hinweisen ohne direkten Bezug zum Problem antwortet 
(Was ja grundsätzlich in Ordnung ist), dann sollte es in einem anderen 
Ton und mit Begründung sein!
Kann man ja auch damit ergänzen das man es einfach aus Prinzip so macht, 
einfach um so von Anfang an ein vernünftiges und einheitliches Schema zu 
haben...

Wobei man natürlich sagen muss das der TE sein Code ja explizit als 
"Testcode" ausgewiesen hat und ich zugeben muss das wenn ich ein kleines 
"Test- oder Dienstprogramm" schreibe das nur den Zweck erfüllt 
kurzfristig ein Signal zu haben oder etwas zu überprüfen,(Und danach im 
Nirvana zu verschwinden) dann schreibe ich sicher auch nicht immer 
"ordentlich" sondern oft nur schnell irgendetwas. Dann nennen sich die 
Variablen auch a,b,c, Kommentare gibt es nicht, übersichtlich ist auch 
nichts ausserdem steht keine Zeile mehr als unbedingt notwendig im 
Code...

Gruß
Carsten

von Arno K (Gast)


Lesenswert?

Moin..

Mal unabhängig von dieser Diskussion, was kann man zur Frage des TE 
sagen?

Mich würde interessieren, was passiert, wenn man vor die sprungmarke 
main:
ein .org 0x....ich glaub 0x1a? setzt? Naja, irgendwas hinter die 
Interrupt-
Sprungtabelle halt. Habe die vom m8 nicht im Kopf, daher muss ich mit 
0x1a
raten, bin gerade zu faul fürs Datenblatt ^^

Den einzigen "Fehler" würde ich dort sehen, da glaub ich bei allen AVR
zuerst RX complete, dann UDRE und dann TX complete kommt (auf die gefahr
hin, da was zu tauschen) .. wer weiss, eigentlich sind die ja nicht 
aktiv,
aber vielleicht liegt's ja trotzdem daran.

Gruss, Arno N.

von Florian L. (muut) Benutzerseite


Lesenswert?

Ein- und Ausgänge definieren?

von Andy H. (vinculum) Benutzerseite


Lesenswert?

Erstmal ist an dem Code nix schlimm, hier müssen sich wohl einige 
Experten abfrusten.

Push und pop temp können auch noch weg.

sbis  UCSRA  ,  UDRE braucht es eigentlich auch nicht, denn es wird ja 
nicht selbstätig mehr gesendet als empfangen.

Ausgänge braucht man nicht setzen

Welchen Assembler hast du?
Schau mal hier Beitrag "GNU Assembler (avr-as) und Interrupt Vektoren fuer ATmega"

Ansonsten mal Hardware angucken. MAX232, 5V ?? Oszillator?

von Bernd (Gast)


Lesenswert?

Florian Löffler schrieb:
> Ein- und Ausgänge definieren?
Soviel ich weis, werden beim Usart die I/O's automatisch richtig 
gesetzt.
Man kann also TX als Eingang deffiniert lassen und man kann trotzdem 
senden.
Das Problem hat eindeutig nichts damit zu tun.

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


Lesenswert?

> Nach dem ersten NewLine werden aber zuerst 8 Bytes
> (64 35 40 21 42 54 5A 22) gesendet
Immer der selbe String?
Welches Terminal-Programm?
Hast du schon andere Terminal-SW ausprobiert?

von Andy H. (vinculum) Benutzerseite


Lesenswert?

Guck mal deine Massen an, wo die verbunden sind. Habe hier gerade ein 
ähnliches Problem

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

Lothar Miller schrieb:
> 64 35 40 21 42 54 5A 22
Das entspricht in ASCII: d5@!BTZ"
Ok, sagt mir auch nichts.

Aber:
Könnte es sein, dass Dein Terminalprogramm im Auto-Echo-Modus steht und 
das diese Zeichenkombination eigentlich nicht von Deinem Prozessor, 
sondern vom Terminalprogramm kommt? So eine Art initialisierungssequenz?

von Dawamaha (Gast)


Lesenswert?

Das Problem tritt bei allen Terminals auf.
Ich verwende allerdings das MK2 USB-Board von myAVR. Daher kann eine 
falsche Schaltung kaum die Ursache sein. Es kann natürlich sein, dass 
der USB-Controller da noch was zumixt, das wäre für mich jetzt die 
einzige plausible Erklärung.
Also falls noch jemand noch eine Idee hätte, wäre das gut, sonst gehe 
ich einfach davon aus, dass es am Board liegt.

Nochmal Danke an alle, die mir hier ernsthaft weiterhelfen wollten!

Ich finde nur, Antworten wie die ersten werfen ein relativ schlechtes 
Licht auf so ein Forum und ich werde mir in Zukunft zweimal überlegen, 
ob ich hier nochmal Fragen stelle beziehungsweise ob ich mich an so 
einem Forum beteiligen möchte.

Mit freundlichen Grüßen,
Dawamaha

von Chris (Gast)


Lesenswert?

Dawamaha schrieb:
> Ich finde nur, Antworten wie die ersten werfen ein relativ schlechtes
> Licht auf so ein Forum und ich werde mir in Zukunft zweimal überlegen,
> ob ich hier nochmal Fragen stelle beziehungsweise ob ich mich an so
> einem Forum beteiligen möchte.
Ach, da musst Du dich hier dran gewöhnen ;-)

Habe dein Programm gerade mal ausprobiert (Mega8 auf STK500). Es macht 
bei mir genau das, was es eigentlich tun soll.

von Carsten S. (dg3ycs)


Lesenswert?

Hi,

wenn  dasselbe PRG ohne änderung auf einer HW Plattform läuft und auf 
einer anderen nicht, dann stellt sich die Frage, ob evtl. die Timings 
stimmen:

Also:
Passen die Einstellungen des Terminal-PRGs?
Passen die in der SW gemachten Baud-Einstellungen (bzw. die 
voreinstellungen der entwicklungsumgebung) zu der Frequenz des 
Bestückten Quarzes?

(=Läuft das PRG im Atmel evtl. zu schnell/langsam?)

Wenn man ein langsames Zeichen als schnelles auswerter kommen ja genau 
solche "wirren Zeichenketten" heraus...

Ein Test dafür währe: Ändert sich die Zeichenkette wenn du ein anderes 
Zeichen sendest?

Falls es daran nicht liegt, dann könnte es an dem My AVR Progger 
liegen...
Baue mal einen einfachen Pegelwandler mit MAX232 auf und schaue was dann 
da raus kommt...

Gruß
Carsten

von Andy H. (vinculum) Benutzerseite


Lesenswert?

Bei mir wars der 7805 Spannungsregler. Es lagen nur knapp 7V am Eingang 
an, das hat ihm nicht gereicht, um stabil während einer DAtenübertragung 
zu liefern.

von oldmax (Gast)


Lesenswert?

hi
@ Dawamaha
Ich will jetzt nicht auf dir rumhacken, aber da du dir Hilfe beieinem, 
sagen wir mal, Standartprogrämmchen suchst, muß hier jeder davon 
ausgehen, das du noch Anfänger bist. Dazu Dein Programmschnipsel. 
Natürlich kann man wesentlich netter sagen, "schau doch bitte, das du 
dir gleich angewöhnst, ISR von vornherein richtig zu programmieren", 
ob's notwendig ist oder nicht. Normalerweise sollte ein Unterprogramm so 
wie es ist, egal in welchem Programm eingesetzt, funktionieren. Auch 
wenn du es an dieser Stelle nicht einsehen willst, aber so kannst du es 
im Programm hinterher nicht einsetzen. Was nutzt dir dann der Test.
> Ich finde nur, Antworten wie die ersten werfen ein relativ schlechtes
> Licht auf so ein Forum und ich werde mir in Zukunft zweimal überlegen,
> ob ich hier nochmal Fragen stelle beziehungsweise ob ich mich an so
> einem Forum beteiligen möchte.

Na ja, beteiligen ist für einen Fragesteller immer so eine Sache.... Ich 
muß ganz ehrlich sagen, an dieser Stelle klingt es nicht nach, sorry für 
den Ausdruck, viel Verstand. Du bist de/die mit einem Problem! Da nutzt 
die Aussage, "Es geht eigentlich, aber nicht immer " Da ist etwas 
fehlerhaft, und du willst dich damit abfinden, nur weil du nicht 
einsehen kannst, das auch die Ratschläge aus den ersten Antworten gut 
gemeint waren... ?
Ok, also zurück zum Thema.
Ich vermute mal, du hast da noch etwas im Empfangspuffer vom PC.
Gruß oldmax

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


Lesenswert?

@ Dawamaha
Überprüfe doch erst mal deine serielle Verbindung:
Was bekommst du, wenn du am Terminalkabel einfach Txd und Rxd 
verbindest?


> Ich finde nur, Antworten wie die ersten werfen ein relativ schlechtes
> Licht auf so ein Forum
Sie sind wenigstens nicht grundlegend falsch.
> und ich werde mir in Zukunft zweimal überlegen, ob ich hier nochmal
> Fragen stelle
Es ist immer gut, sich seine Frage selbst nochmal zu hinterfragen.
> beziehungsweise ob ich mich an so einem Forum beteiligen möchte.
Dir sollte schon klar sein, dass du ein Problem hast, bei dem nur du 
die Möglichkeit hast, den Fehler nachzuvollziehen. Und wenn hier im 22 
Beiträgen langen Fred gerade mal 3 Beiträge von dir sind, davon nur in 
2 davon weiterbringende Informationen auftauchen, dann passt das Wort 
beteiligen schon nicht so richtig, und zudem wird Spekulationen Tür 
und Tor geöffnet...

Summa summarum:  Du solltest dir eine etwas dickere Haut zulegen  ;-)

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.