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
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.
> 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!
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
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.
@ 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
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
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
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
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
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.
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?
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.
> 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?
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?
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
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.
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
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.
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
@ 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 ;-)