Forum: Mikrocontroller und Digitale Elektronik Sende/Empfangsvorgang mittels nur 1St. µC


von Wolle G. (wolleg)


Angehängte Dateien:

Lesenswert?

Ich suche eine „neue“ Idee, wie 2 Vorgänge verschachtelt werden könnten, 
da meine bisherigen Programmierversuche nicht den richtigen Erfolg 
hatten.
Worum geht es?
Ein Sende-Empfangsmodul (G1) soll an ein 2. Sende-Empfangsmodul (G2) 
einen „Code“ senden, der im zweiten Modul (G2) eine Antwort auslöst. Die 
Antwort enthält Temperaturmesswerte, welche vom ersten Modul (G1) 
empfangen und dann zunächst auf einer Flüssigkristallanzeige (FKA) 
angezeigt werden sollen.

Mit 3 Modulen funktioniert es in abgewandelter Form.
Und zwar so, dass Modul 3 (G3) nach Tastendruck nur die Adresse und 
einen ID_Code an Modul 2 G(2) sendet. Wird von G2 der ID_Code erkannt, 
sendet Modul 2 die Messwerte an Modul G1. G1 wartet in einer 
while-Schleife darauf, dass Daten eintreffen.
Da G1 in der while-Schleife solange in der Zeile (D1=RXBUF1) wartet, bis 
ein Wert eintrifft, bleibt der µC hier zunächst „hängen“. Jeder neue 
Tastendruck fordert einen neuen Messwert an.
Wie schon gesagt, soll das Ganze anstatt mit 3 Geräten jetzt mit nur 2 
Geräten ablaufen.
Aktuell bin ich soweit gekommen:
Mein Programm von Gerät G1 wartet in der for-Schleife (in main) so 
lange, bis die Taste P2.0 gedrückt wird, wodurch ein Sendevorgang zum 
Gerät G2 (Messmodul) ausgelöst wird. G2 antwortet, indem der Messwert an 
G1 zurück gesendet wird. Die Funktion "antwort_empfangen ()" in der 
Tasten-ISR  empfängt die Daten. (siehe Anhang)
Bis hierhin funktioniert es aber nur dann, wenn der µC vorher 
zurückgesetzt wurde.
Jetzt das Problem:
ein weiterer Tastendruck löst keinen erneuten Sendevorgang aus
bzw. das Messdatenmodul antwortet nicht noch einmal?).
Wie schon mal gesagt, soll nur auf Anforderung gesendet und nur 2 Module 
eingesetzt werden.
Hoffentlich habe ich mich verständlich genug ausgedrückt.
(Evtl. auch Fragen stellen.)
Oder wie könnte man es evtl. auch ganz anders machen?
(ein Gerät mit Timer nur als Sender, der in bestimmten Abständen 
Messwerte sendet und  das andere Gerät nur als Empfänger --> dies wird 
nicht gewünscht)

Als µC werden MSP430F1611 bzw. MSP430F1232 eingesetzt. Die Schnittstelle 
zwischen dem Modul (E32_868T) und dem µC ist UART.
Im Anhang die aus meiner Sicht entscheidenden Programmschnipsel für den 
aktuellen Programmentwurf vom Sende-Empfangsgerät G1.

: Bearbeitet durch User
von Max M. (Gast)


Lesenswert?

'interessanter' Programmierstil ;-)

Du verwendest u.a. Endlosschleifen die nie wieder verlassen werden 
können.

Verwende mal lieber den Debugger und setze Breakpoints, um Dich durch 
das Chaos durchzuackern.

von W.S. (Gast)


Lesenswert?

Wolle G. schrieb:
> Ich suche eine „neue“ Idee, wie 2 Vorgänge verschachtelt werden könnten,
> da meine bisherigen Programmierversuche nicht den richtigen Erfolg
> hatten.

Also wenn ich mal alles Unwichtige weglasse, dann willst du mehrere 
Geräte so kommunizieren lassen, daß Gerät 1 an Gerät 2 ne Botschaft 
schickt, dieses dann als Reaktion auf diese Botschaft seinen Senf 
dazugibt und das Ganze an Gerät 3 schickt, dieses dann ebenso seinen 
Senf dazugibt und das Ganze dann weiterschickt. Entweder an ein Gerät 4 
oder zurück an Gerät 1.

Und das Ganze zu dem Zweck, an jedem Gerät lediglich eine serielle 
Schnittstelle zu belegen, damit Gerät 1 nicht mehrere serielle 
Schnittstellen haben muß.

Ist das richtig verstanden?
Quasi System Schneeball? bei jedem Gerät wird's mehr.

Nun ja, sowas kannst du machen, aber du mußt bei allen Geräten eben 
nichtblockierend deine Firmware schreiben, damit sie zugleich empfangen 
und senden können. Und du mußt dir ein Kommandoprotokoll ausdenken, das 
so gemacht ist, daß jedes Gerät damit zurecht kommt.

W.S.

von Falk B. (falk)


Lesenswert?

Wolle G. schrieb:
> Ich suche eine „neue“ Idee, wie 2 Vorgänge verschachtelt werden könnten,

Nennt sich Multitasking.

> Ein Sende-Empfangsmodul (G1) soll an ein 2. Sende-Empfangsmodul (G2)
> einen „Code“ senden, der im zweiten Modul (G2) eine Antwort auslöst. Die
> Antwort enthält Temperaturmesswerte, welche vom ersten Modul (G1)
> empfangen und dann zunächst auf einer Flüssigkristallanzeige (FKA)
> angezeigt werden sollen.

Klingt nicht so schwer.

> Mit 3 Modulen funktioniert es in abgewandelter Form.
> Und zwar so, dass Modul 3 (G3) nach Tastendruck nur die Adresse und
> einen ID_Code an Modul 2 G(2) sendet. Wird von G2 der ID_Code erkannt,
> sendet Modul 2 die Messwerte an Modul G1. G1 wartet in einer
> while-Schleife darauf, dass Daten eintreffen.

Hehe, oder ewig und drei Tage.

> Da G1 in der while-Schleife solange in der Zeile (D1=RXBUF1) wartet, bis
> ein Wert eintrifft, bleibt der µC hier zunächst „hängen“.

MÖÖÖÖÖP! Siehe Multitasking!

> Jeder neue
> Tastendruck fordert einen neuen Messwert an.
> Wie schon gesagt, soll das Ganze anstatt mit 3 Geräten jetzt mit nur 2
> Geräten ablaufen.

Nicht wirklich schwer, wenn man weiß wie.

Wenn man dein Programm nur überfliegt, sieht man viele rote Warnlampen.

[c]
void pause400(void) {
unsigned int i;
for (i=400;i>0;i--);               // warten ca.360ms
}

void pause40000(void) {
unsigned int i;
for (i=40000;i>0;i--);               // warten ca.360ms
}

So NICHT!

Außerdem hast du keinerlei Funktionalität in der normalen 
Hauptschleife,. die ist bei dir komplett leer. Alles steckt in 
Interrupts. Das KANN man machen, wenn man es drauf hat. Du gehörst nicht 
dazu.

> Mein Programm von Gerät G1 wartet in der for-Schleife (in main) so
> lange, bis die Taste P2.0 gedrückt wird,

Bitte? Deine Hauptschleife ist eine leere for-Schleife!

> wodurch ein Sendevorgang zum
> Gerät G2 (Messmodul) ausgelöst wird. G2 antwortet, indem der Messwert an
> G1 zurück gesendet wird. Die Funktion "antwort_empfangen ()" in der
> Tasten-ISR  empfängt die Daten. (siehe Anhang)

Vollkommen falsch!

> Oder wie könnte man es evtl. auch ganz anders machen?

Siehe oben.

> (ein Gerät mit Timer nur als Sender, der in bestimmten Abständen
> Messwerte sendet und  das andere Gerät nur als Empfänger --> dies wird
> nicht gewünscht)

Ist auch Käse.

> Als µC werden MSP430F1611 bzw. MSP430F1232 eingesetzt. Die Schnittstelle
> zwischen dem Modul (E32_868T) und dem µC ist UART.
> Im Anhang die aus meiner Sicht entscheidenden Programmschnipsel für den
> aktuellen Programmentwurf vom Sende-Empfangsgerät G1.

Kann man zu 90% wegwerfen und neu machen. Außer der Initialisierung 
bleibt da nix übrig.

von Falk B. (falk)


Lesenswert?

Ach ja, deine Quelltextformatierung sit ein Graus, vor allem die 
Einrückungen. Die sind WICHTIG!

Strukturierte Programmierung auf Mikrocontrollern

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

@ OP

Naja, da humpelt ein "Hobbyprogrammierer" durch den Wald . . .

Wenn man Daten empfangen will, muss man VORHER prüfen, ob welche 
empfangen wurden, nicht danach. Eben so beim Senden. Man nuss VORHER 
prüfen, ob das Senderegister frei ist.

Man kann nicht naiv in einer einfache Schleife auf korrekte Daten 
warten, das geht schief. Man muss auch was tun, wenn die Daten, warum 
auch immer, in einer bestimmten Zeit nicht eintreffen (timeout). Dann 
muss es weiter gehen.

Man schreibt nicht für einzelne Daten eine Ausgaberoutine, sondern 
verwendet Funktionsparameter!

Du gibst bei der UART-Ini die beiden Interrupts frei, deine ISRs sind 
aber leer! Was soll das? Du brauchst hier keine UART-Interrupts! Die 
Interrupt-Flags werden auch gesetzt, wenn die Interrupts nicht 
freigegeben sind. Nur die ISR wird dann nicht ausgeführt. Damit kann man 
die Flags abfragen, neudeutsch pollen.

Nutze KEINE selbstgestrickten Warteschleifen, die fliegen bei der 
Optimierung durch den Compiler raus! Es gibt auch beim MASP430 schon 
vorbereitete Funktionen mit delay irgendwas, die sicher funktionieren.

Nutze lokale Variablen und nur sparsam globale Variablen. Erst recht für 
Schleifenzähler etc.!

In deiner Empfangsroutinie wird D5 verwendet, um daten2 zu berechnen, 
aber D5 wird nirgends beschrieben.

Nutze Arrays und keine Einzelvariablen. Arrays fangen mit Index 0 an, 
nicht 1.

Nutze eine for-Schleife, wenn du was zählst, kein while.

Schreib dir eine handvoll sinnvolle Funktionen, z.B. lcd_setcursor(x, 
y). Deine kryptischen

 lcd_write_command(LCD_CMD_CURSOR_LA,52);    //26 Zeilenanfang 2.Zeile 
--> 26 Zeichen pro Zeile

Versteht kein Mensch. Auch du nicht.

Siehe Anhang. Ich habs mal bissel formatiert und strukturiert. So könnte 
es laufen. Ist aber nur im Editor geschrieben, nix Compiler. Hab keinen 
MSP430er. Aber das sollte man hinkriegen. Vor allem solltest du sehen, 
wie man bestimmte Dinge besser und übersichtlicher macht, nicht so sehr 
BASCOM-Style.

von Falk B. (falk)


Lesenswert?

Ok, die Interrupts für die Tastereingänge noch ausschalten und die 
Abfrage direkt über die Eingänge machen.

von Stefan F. (Gast)


Lesenswert?

Ich weiß nicht wer das war, aber ich finde es unverschämt dem Falk für 
so viel Mühe ein -1 zu verpassen.

von Falk B. (falk)


Lesenswert?

Stefan ⛄ F. schrieb:
> Ich weiß nicht wer das war, aber ich finde es unverschämt dem Falk für
> so viel Mühe ein -1 zu verpassen.

War bestimmt ein BASCOM-Fan! ;-)

"Was stört es eine deutsche Eiche, wenn sich ein Schwein dran scheuert?"

von W.S. (Gast)


Lesenswert?

Falk B. schrieb:
> Nutze KEINE selbstgestrickten Warteschleifen, die fliegen bei der
> Optimierung durch den Compiler raus!

Naja, poltere du mal nicht gar so laut. Was du da schreibst, sieht für 
mich aus wie nur auf den GCC bezogen. Andere Compiler fahren dem 
Programmierer nicht so rüde über's Maul und erzeugen dennoch einen 
besseren Maschinencode. Aber über eine bestimmte Zielplattform bzw. eine 
bestimmte Programmiersprache sollten wir hier lieber nicht schreiben, 
sondern das eigentliche Problem angehen. Das heißt nicht wirklich nur 
'Multitasking', sondern schlichtweg nur saubere Lowlevel-Treiber für die 
seriellen Schnittstellen und eine saubere Kommandozeilen-Auswertung. Das 
sollte reichen.

Und dann braucht der TO auch keine elendiglichen 
Warte-Trampel-Funktionen mehr.

W.S.

von Wolle G. (wolleg)


Angehängte Dateien:

Lesenswert?

Falk B. schrieb:
> Naja, da humpelt ein "Hobbyprogrammierer" durch den Wald . . .
"Hobby..." würde ich eigentlich nicht sagen wollen.
Hier "programmiert" ein alter Knacker (Ü80), der um Nachsicht bittet.

Vielen Dank für Deinen Programmschnipsel, welchen ich mit einem 
IAR_Programm getestet habe. Die Zeilen, wo der Compiler gemeckert hatte, 
habe ich korrigiert bzw. die Stellen, die nicht unbedingt nötig sind, 
heraus genommen.

Leider kein Erfolg.
Die gewählte Art der Tasteneingabe funktioniert nicht.
Das ist daran erkennbar, dass die Kontroll-LED nicht aufleuchtet und 
auch der Empfänger (Gerät 2) nicht reagiert.
Im Anhang das verwendete Programm.
Vielleicht gibt es weitere Ideen bzw. Vorschläge zu einem weiteren 
Programmentwurf.

: Bearbeitet durch User
von Rainer V. (a_zip)


Lesenswert?

Falk B. schrieb:
> "Was stört es eine deutsche Eiche, wenn sich ein Schwein dran scheuert?"

Ja, ist wieder ein Blödmann dabei...

Der Vorschlag von W.S. wäre schon der richtige Ansatz, habe aber große 
Zweifel, ob der TO sowas hinkriegt! Aber vielleicht erbarmt sich ja 
jemand...
Gruß Rainer

...wird sicher die nächste -1 :-)

von Falk B. (falk)


Lesenswert?

Wolle G. schrieb:
> Falk B. schrieb:
>> Naja, da humpelt ein "Hobbyprogrammierer" durch den Wald . . .
> "Hobby..." würde ich eigentlich nicht sagen wollen.
> Hier "programmiert" ein alter Knacker (Ü80), der um Nachsicht bittet.

UFFF!!! Respekt! Vor allem, wenn du 0x80 bist ;-)

> Im Anhang das verwendete Programm.
> Vielleicht gibt es weitere Ideen bzw. Vorschläge zu einem weiteren
> Programmentwurf.

Ja, du hast meine letzten Hinweise nicht beachtet und eingebaut. Ich 
mach das dann mal. Aber ich brauche noch ein paar Informationen.

Mit welcher Taktfrequenz läuft deine CPU?
Wie sind deine Taster beschaltet?
Hast du einen Schaltplan?

von Falk B. (falk)


Lesenswert?

Ich hab mir mal die IAR Workbench runtergeladen und installiert. Für's 
Compilieren brauche ich aber die Datei TS_LC7981.h. Bitte hier anhängen 
oder einen Link auf die Datei setzen. Ach ja, die dazugehörige .c Datei 
brauche ich natürlich auch ;-)

: Bearbeitet durch User
von W.S. (Gast)


Angehängte Dateien:

Lesenswert?

Falk B. schrieb:
> Mit welcher Taktfrequenz läuft deine CPU?

Eigentlich egal. Der µC von Wolle wird gewiß schneller laufen als eine 
gewöhnliche Serielle mit 9600-8N1.

Also haben wir hier erstmal 2 Probleme für Wolle zu lösen:

1. einen Treiber für einen UART des verwendeten µC schreiben. Sowas habe 
ich schon vor Jahren mal für die damalige Lernbetty gepostet. Hätte 
seitdem jeder lesen können, der einen Bedarf an sowas hat. Ist im Grunde 
völlig einfach. Ich hab aber keinen MSP da. Den einzigen, den ich je 
hatte, hab ich vor Zeiten mal verschenkt. Da wäre jemand gefragt, der 
sowas hat. Ich hänge mal etwas dran, was eventuell als Vorlage dienen 
kann. Ist aber NICHT für einen MSP gedacht, sondern für einen 
STM32F103C8T6. Das Ding kann man auch ziemlich zusammenkürzen, wenn man 
nur einen UART braucht.

2. einen Satz von Kommandos ausdenken, die zum Problem passen. Mir fällt 
da erstmal sowas aus dem Stegreif ein:

REPORT cr lf
ANTWORT (eigener Text) cr lf

Wobei das Wort REPORT als Startbotschaft dient. Es wird zuerst von Gerät 
1 an Gerät 2 geschickt.
Wenn Gerät 2 dieses Kommando erkennt, dann fragt es seinen eigenen 
Zustand (was auch immer) ab und sendet seinerseits ein Kommando, das mit 
dem Wort ANTWORT beginnt. Anschließend sendet Gerät 2 dann ebenfalls das 
Kommando REPORT.

Genauso funktionieren Gerät 3 und eventuelle weitere Geräte.

Wenn eines dieser Geräte (ab 2) ein Kommando empfängt, das mit ANTWORT 
beginnt, dann sendet es dieses Kommando (d.h. die gesamte Zeile) einfach 
weiter, ohne sich selbst um deren weiteren Inhalt zu kümmern. Nur das 
Gerät 1 muß sich um all die Antworten der übrigen Geräte kümmern und die 
Antworten irgendwie auswerten.

So, das Gerät 1 wird also nach Wolles Gusto dem Gerät 2 zurufen "REPORT" 
und es wird dann von jedem Gerät eine Text-Zeile empfangen, bei 100 
Geräten eben 100 Textzeilen und zum Schluß eine Zeile mit "REPORT", 
worum sich Gerät 1 jedoch nicht schert.

W.S.

von Falk B. (falk)


Lesenswert?

W.S. schrieb:
>> Mit welcher Taktfrequenz läuft deine CPU?
>
> Eigentlich egal.

Nö. Für definierte Delays braucht man schon die CPU-Frequenz.

> Also haben wir hier erstmal 2 Probleme für Wolle zu lösen:
>
> 1. einen Treiber für einen UART des verwendeten µC schreiben.

Nö. Der Op will mit minimalem Aufwand und ebensolchem Verständnis für 
Programmieren im Allgemeinen und C im Speziellen sein Ziel erreichen.

> 2. einen Satz von Kommandos ausdenken, die zum Problem passen. Mir fällt
> da erstmal sowas aus dem Stegreif ein:

Nö. Es gibt nur eine Kommandosequenz, die sein anderes Modul haben will. 
Anfrage senden, Antwort empfangen, auswerten und anzeigen. Fertig.

> So, das Gerät 1 wird also nach Wolles Gusto dem Gerät 2 zurufen "REPORT"
> und es wird dann von jedem Gerät eine Text-Zeile empfangen, bei 100
> Geräten eben 100 Textzeilen und zum Schluß eine Zeile mit "REPORT",
> worum sich Gerät 1 jedoch nicht schert.

Alles viel zu kompliziert. Der OP ist mit der Minimalversion schon gut 
ausgelastet, aber auch zufrieden.

von Wolle G. (wolleg)


Lesenswert?

Ich merke, jetzt läuft es in die falsche Richtung.
Deshalb "verordne" ich eine kurze Pause und werde mein Problem
und das Ziel sowie den aktuellen Stand in einem weiteren Beitrag noch 
einmal formulieren.

von jo (Gast)


Lesenswert?

Wolle G. schrieb:
> Ich merke, jetzt läuft es in die falsche Richtung.
> Deshalb "verordne" ich eine kurze Pause

Darf ich trotzdem noch ganz kurz meinen Senf dazu geben?

Ohne Begründung:
- Gleichzeitiges Senden und Emfangen geht nicht.
- Ist die Luftschnittstelle belegt, darf niemand anderes senden.
- Wieso kommuniziert nicht direkt G3 mit G1, G2 ebenso?
- G1 braucht immer nur einen UART.

von Wolle G. (wolleg)


Lesenswert?

Zunächst erst noch einmal eine kurze Beschreibung der bereits 
funktionierenden Lösung. (Verwendung von 3 Geräten)

Gerät A sendet nach einem Tastendruck an das Gerät B Daten. Gerät B ist 
auf die Adresse 0x0202 und dem Kanal 09 konfiguriert. ( gesendete Daten: 
0x02, 0x02, 0x09, 0x56.)
Gerät B erkennt an der „Marke“ 0x56, dass es Messwerte senden soll.
Dazu sendet das Gerät B an das Gerät C den Datenstrom 0x03, 0x03, 0x09, 
0xXX, 0xYY, 0xZZ.
0x03, 0x03, 0x09 sind die Adresse + der Kanal von Gerät  C.
 XX, YY, ZZ usw. sind die eigentlichen zu übertragenden Messwerte.

Jetzt soll Gerät A entfallen, sodass der Datenverkehr nur noch über 2 
Geräte erfolgt.
Dazu sendet das ehemalige  Gerät C nach einem Tastendruck die Daten, die 
vorher das Gerät A gesendet hatte und löst damit wieder eine Antwort 
von Gerät  B mit den Messwerten aus.
Die Antwort (Messwerte) wird von Gerät C empfangen und weiter 
verarbeitet.
Somit werden nur die mit B und C bezeichneten Geräte verwendet.
Ich würde mir wünschen, dass neue Vorschläge direkt in Form von 
Änderungen an  meinen Programmcode 
(0198b_send_an_0202_G1_antwort_empfangen.c) mit Kommentar gemacht 
werden.

von Falk B. (falk)


Lesenswert?

Wolle G. schrieb:
> Somit werden nur die mit B und C bezeichneten Geräte verwendet.
> Ich würde mir wünschen, dass neue Vorschläge direkt in Form von
> Änderungen an  meinen Programmcode
> (0198b_send_an_0202_G1_antwort_empfangen.c) mit Kommentar gemacht
> werden.

Das hab ich schon so verstanden. Aber ich brauche trotzdem deine 
Zuarbeit.

Mit welcher Taktfrequenz läuft deine CPU?
Wie sind deine Taster beschaltet?
Hast du einen Schaltplan?

Ist dein Gerät C selbst gebaut oder ein gekauftes Board? Wenn gekauft, 
zeig mal einen Link auf die Seite oder noch besser dessen Beschreibung.

von W.S. (Gast)


Lesenswert?

Wolle G. schrieb:
> Jetzt soll Gerät A entfallen,

Also, du verwirrst mich. Was zum Kuckuck sollen sich die unterschiedlich 
vielen Geräte denn gegenseitig sagen? Das ist ja schlimmer als in einer 
Beziehungskomödie, wo man nie so recht sagen kann, wer mit wem im 
nächsten Kapitel ins Bett steigen wird...

Versuche doch lieber, dein eigentliches Anliegen mal 
allgemeinverständlich zu formulieren.

W.S.

von Rainer V. (a_zip)


Lesenswert?

Wolle G. schrieb:
> Zunächst erst noch einmal eine kurze Beschreibung der bereits
> funktionierenden Lösung. (Verwendung von 3 Geräten)

Kann ehrlich gesagt dein Problem nicht verstehen. Abgesehen davon, dass 
du vielleicht deine Schnittstellen an den einzelnen Controllern nicht 
sauber programmiert hast (was ich nicht prüfen kann) hast du doch 2 
recht überschaubare Flußdiagramme beschrieben. Im zweiten Fall, also 
ohne A, macht B doch genau das, was vorher A gemacht hat und während 
vorher C Daten von B empfangen hat, soll nun C auch noch Daten an A 
(zurück)senden.
Wünsche dir jedoch Erfolg, denn falls die Hardware wirklich tadellos 
funktioniert, dann wird es bestimmt ein Denkfehler in deinen Programmen 
sein. Gruß Rainer

von Rainer V. (a_zip)


Lesenswert?

Rainer V. schrieb:
> soll nun C auch noch Daten an A

sorry, soll natürlich heißen: soll nun C auch noch Daten an B, um im 
Bild zu bleiben...

von Falk B. (falk)


Lesenswert?

Rainer V. schrieb:
> Kann ehrlich gesagt dein Problem nicht verstehen.

Ich schon. Der Wolle hat schon ne Menge Semester auf dem Buckel und war 
nie wirklich Programmierer. Schau dir seinen ersten Quelltext an.

von Hannes (Gast)


Lesenswert?

Wolle G. schrieb:
> Gerät A sendet nach einem Tastendruck an das Gerät B Daten ...
> [viel Zeugs gelöscht...]

Kann man das so zusammenfassen?

B sitzt nur da und wartet auf ein "Kommando". Trifft "Kommando" ein, 
schickt es "Daten" an C.

A wartet auf "Taste", und schickt dann "Kommando" an B.

C macht daselbe wie A, aber zusätzlich wartet es auf "Daten"

von Rainer V. (a_zip)


Lesenswert?

Falk B. schrieb:
> Schau dir seinen ersten Quelltext an.

Na ja, ich kenn die Controller nicht...aber wenn die "ABC"-Version 
funktioniert, dann ist die Umsetzung auf "BC" doch wirkich kein 
Hexenwerk. Ob ich jetzt 3 (gleiche) Schnittstellen habe, die miteinander 
"sprechen" oder 2, ist doch irgenwie Wurscht oder?
Gruß Rainer

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

Ein Bild sagt mehr als 1000 Worte.

von Falk B. (falk)


Lesenswert?

Rainer V. schrieb:
> Na ja, ich kenn die Controller nicht...aber wenn die "ABC"-Version
> funktioniert, dann ist die Umsetzung auf "BC" doch wirkich kein
> Hexenwerk.

Für den Op in seiner Situation und seinem Wissen und Erfahrung schon.

von Rainer V. (a_zip)


Lesenswert?

Falk B. schrieb:
> Für den Op in seiner Situation und seinem Wissen und Erfahrung schon.

OK, dann sind die Leute gefordert, die die MSP430F1611 bzw. MSP430F1232 
kennen. Wage jetzt erst mal nicht zu bestreiten, dass auch die erste 
Version noch nicht so richtig funktioniert...aber das hilft natürlich 
auch nicht weiter, sorry.
Gruß Rainer

von Wolle G. (wolleg)


Lesenswert?

Hannes schrieb:
> Kann man das so zusammenfassen?
>
> B sitzt nur da und wartet auf ein "Kommando". Trifft "Kommando" ein,
> schickt es "Daten" an C.
>
> A wartet auf "Taste", und schickt dann "Kommando" an B.
>
> C macht daselbe wie A, aber zusätzlich wartet es auf "Daten"

Nicht ganz.
B ist das Gerät, welches die Messwerte erfasst und wartet, bis das 
"Kommando" 0x56, gesendet von A, eintrifft.
Wird 0x56 von Gerät B erkannt, dann sendet Gerät B an Gerät C 
Messwerte, welche auf einem Display angezeigt werden.
Das Ganze funktioniert bei mir problemlos.

Analog ähnlich soll es nun mit nur 2 Geräten ablaufen.
Man könnte das Verfahren evtl. auch mit der Funkfernablesung bei den 
Heizkostenverteilern vergleichen.

von W.S. (Gast)


Lesenswert?

Wolle G. schrieb:
> Nicht ganz.

Also, wenn ich dich jetzt verstanden habe, sieht das so aus:
A ist quasi die Start-Taste, die B startet
B ist quasi das Meßgerät, das seine Resultate an C sendet
C ist quasi die Anzeige, die die Resultate anzeigen soll.

Es ist also schlichtweg keine Art von Ring, wo die Resultate von 
mehreren Geräten gesammelt und zusammen an das kommandierende Gerät 
gesendet werden sollen, sondern lediglich eine lineare Verbindung dreier 
Geräte: Knopf, Meßgerät, Anzeige.

W.S.

von Stefan F. (Gast)


Lesenswert?

Wenn man so einen Auftrag in China oder Indien entwickeln lassen würde 
käme niemals etwas brauchbares heraus.

von Rainer V. (a_zip)


Lesenswert?

W.S. schrieb:
> A ist quasi die Start-Taste, die B startet
> B ist quasi das Meßgerät, das seine Resultate an C sendet
> C ist quasi die Anzeige, die die Resultate anzeigen soll.

Und nun soll, wie im Blockschaltbild weiter oben richtig gezeichnet, C 
die Start-Taste sein und B die Messwerte wieder an C senden, zwecks 
Anzeige!?
Ich schlage dem TO vor den Ablauf anhand des Blockschaltbilds noch mal 
seine bisher benutzten Befehle für A,B und C drunter zu schreiben und 
dann auf die B, C-Version neu zu verteilen. Muß man halt mal ein wenig 
knobeln :-)
Viel Spass und Gruß Rainer

von Wolle G. (wolleg)


Lesenswert?

W.S. schrieb:
> Also, wenn ich dich jetzt verstanden habe, sieht das so aus:
> A ist quasi die Start-Taste, die B startet
> B ist quasi das Meßgerät, das seine Resultate an C sendet
> C ist quasi die Anzeige, die die Resultate anzeigen soll.

Richtig verstanden.
Diese Arbeitsweise ist eigentlich nur eine Art Übungsaufgabe gewesen, um 
schrittweise die Funktionsweise und Ansteuerung der Sende/Empfangsmodule 
besser kennen lernen zu können.

Jetzt soll aber die Verbindung mit nur 2 Geräten erfolgen.
Wie schon mal gesagt, funktioniert es unter Verwendung des 
Programmentwurfs
0198b_send_an_0202_G1_antwort_empfangen.c (erster Beitrag) erst 
teilweise.
D.h., das erste Gerät sendet nach Tastendruck den
„Schlüssel“ 0x56 (willkürliche Zahl), das zweite Gerät antwortet mit der 
Sendung der Messdaten an das erste Gerät, welches die Messwerte dann 
anzeigt.
Dieser Vorgang läuft mit meinem Programmentwurf leider nur einmal ab 
("hängt sich auf"). Erst nach dem Zurücksetzen des ersten Gerätes führt 
ein weiterer Tastendruck zum Auslösen des Vorgangs.

von Hannes (Gast)


Lesenswert?

Rainer V. schrieb:
> Ich schlage dem TO vor den Ablauf anhand des Blockschaltbilds noch mal
> seine bisher benutzten Befehle für A,B und C drunter zu schreiben und
> dann auf die B, C-Version neu zu verteilen.

Blockschaltbild? Mir wird das langsam zu hoch. Ich kenne mich nur mit 
Ablauf- oder auch State-Diagrammen aus.

Hab mir die Mails des TO nochmals durchgelesen - mehrfach. Wie mir 
scheint ist die Version mir 3 Geräten nicht mehr gefragt, sondern nur 
noch die mit 2.

Das würde dann imho bedeuten:
- B erfasst Daten und wartet auf ein "Kommando". Trifft "Kommando" ein,
schickt es "Daten" an A.
- A wartet auf "Taste", und schickt dann "Kommando" an B. Zusätzlich 
wartet es auf "Daten" und zeigt diese ggf. an.

Kann der TO das bitte so bestätigen?

von Rainer V. (a_zip)


Lesenswert?

Hannes schrieb:
> Blockschaltbild? Mir wird das langsam zu hoch

Himmel, ein paar Posts nach oben, da hat Falk B. ein Blockschaltbild 
gepostet. Ist das denn so schwer??
Und jetzt halt dich doch bitte wenigstens an die bisherige 
"Nummerierung"!

Hannes schrieb:
> - B erfasst Daten und wartet auf ein "Kommando". Trifft "Kommando" ein,
> schickt es "Daten" an A.
> - A wartet auf "Taste", und schickt dann "Kommando" an B. Zusätzlich
> wartet es auf "Daten" und zeigt diese ggf. an.

A ist raus!! Und Prosa muß jetzt auch nicht mehr sein. Wir haben 
Blockschaltbild...
Rainer

von Hannes (Gast)


Lesenswert?

Rainer V. schrieb:
> Hannes schrieb:
>> Blockschaltbild? Mir wird das langsam zu hoch
>
> Himmel, ein paar Posts nach oben, da hat Falk B. ein Blockschaltbild
> gepostet. Ist das denn so schwer??
> Und jetzt halt dich doch bitte wenigstens an die bisherige
> "Nummerierung"!

Du meinst die Nummerierung von Falk?

Falk B. schrieb:
>> Ein Sende-Empfangsmodul (G1) soll an ein 2. Sende-Empfangsmodul (G2)
>> einen „Code“ senden, der im zweiten Modul (G2) eine Antwort auslöst. Die
>> Antwort enthält Temperaturmesswerte, welche vom ersten Modul (G1)
>> empfangen und dann zunächst auf einer Flüssigkristallanzeige (FKA)
>> angezeigt werden sollen.
>
> Hannes schrieb:
>> - B erfasst Daten und wartet auf ein "Kommando". Trifft "Kommando" ein,
>> schickt es "Daten" an A.
>> - A wartet auf "Taste", und schickt dann "Kommando" an B. Zusätzlich
>> wartet es auf "Daten" und zeigt diese ggf. an.
>
> A ist raus!! Und Prosa muß jetzt auch nicht mehr sein. Wir haben
> Blockschaltbild...

Und ich sag Dir, G3 (resp. C) ist raus. Ob du's jetzt kapierst oder 
nicht.

Was Prosa ist, weißt du schon, oder? Oder wahrscheinlich nicht...

Wie gesagt, bei Blockschaltbild bin ich raus, weil ist mir zu "hoch".

(Will sagen: Ein wie auch immer gestaltetes Schaltbild halte ich für die 
schwachsinnigste Idee, um einen Programmablauf darstellen zu wollen.)

von Wolle G. (wolleg)


Lesenswert?

Hannes schrieb:
>Wie mir
>scheint ist die Version mir 3 Geräten nicht mehr gefragt, sondern nur
>noch die mit 2.
> Kann der TO das bitte so bestätigen?
Ja, kann ich bestätigen.
Man könnte auch sagen: Es ist eine Funkfernablesung auf Knopfdruck.

: Bearbeitet durch User
von W.S. (Gast)


Lesenswert?

Wolle G. schrieb:
> Dieser Vorgang läuft mit meinem Programmentwurf leider nur einmal ab
> ("hängt sich auf"). Erst nach dem Zurücksetzen des ersten Gerätes führt
> ein weiterer Tastendruck zum Auslösen des Vorgangs.

Naja, nach einem allerersten Blick in deine Quelle habe ich alle 
weiteren Blicke dort hinein bleiben gelassen. Mein Rat an dich wäre, die 
angezielten Abläufe und Algorithmen strikt von dem 'Fußvolk' sprich 
Lowlevel-Routinen zu trennen, um nicht an jeder Stelle von einer 
Fußangel in die nächste zu treten. So, wie du es versucht hast, besteht 
letztlich die ganze Synchronisation zwischen den verschiedenen Geräten 
aus gegenseitigem Warten und das läuft erfahrungsgemäß darauf hinaus, 
daß irgendwann einmal alle Geräte auf die jeweils anderen Geräte warten 
und keines sich mehr rührt.

So, ich hatte die Quell-Beispiele ja nicht ohne Grund gepostet. Wenn du 
(oder ein anderer MSP-Benutzer) das auf deine Architektur umsetzt, dann 
hast du wenigstens erstmal einen Datenverkehr, der bidirektional läuft, 
also Senden und Empfangen zugleich, ohne daß sich da etwas gegenseitig 
stört. Obendrein kann dieser Treiber sowohl die empfangenen Zeichen als 
auch die zu sendenden Zeichen zwischenspeichern, sodaß die Algorithmen 
"weiter oben" nicht darauf warten müssen oder sich sonstwie um die 
Details der untersten Ebene kümmern müssen. Was bleibt, ist ein kleines 
Kommandoprogramm, aber das ist hardwareunabhängig. Sowas kann man seit 
Jahren aus dem Lernbetty-Projekt nehmen oder ich poste dieses Detail 
hier noch einmal.

Dann hat man jedenfalls erst einmal einen Grundstock an Funktionalität, 
auf dem man aufbauen kann:
- serieller Verkehr, gepuffert und bidirektional
- Kommandoprogramm, wo man mit menschlich lesbaren Kommandozeilen 
arbeiten kann
- Ein- und Ausgabe von Zeichen, Zahlen und Texten

Mit so etwas als Basis kann man dann in aller Ruhe jedes Detail 
austesten und muß sich nicht mit "es geht nicht" oder "es hat sich 
aufgehängt" begnügen.

W.S.

von Rainer V. (a_zip)


Lesenswert?

Ist offensichtlich mal wieder ein hirnloser "-1 Verteiler" hier zu 
sein...
Also läuft die erste Version doch nicht fehlerfrei. Und deshalb muß 
natürlich das erst mal korrigiert werden. Dann wird vielleicht auch die 
Übertragung auf die zweite Version gelingen. Ich warte mal...
Gruß Rainer

von Rudi S. (Gast)


Lesenswert?

W.S. schrieb:
> Mein Rat an dich wäre, die
> angezielten Abläufe und Algorithmen strikt von dem 'Fußvolk' sprich
> Lowlevel-Routinen zu trennen, um nicht an jeder Stelle von einer
> Fußangel in die nächste zu treten.

Sehr guter Vorschlag. Lässt sich auf Top-Down-Entwurf reduzieren.

> So, wie du es versucht hast, besteht
> letztlich die ganze Synchronisation zwischen den verschiedenen Geräten
> aus gegenseitigem Warten und das läuft erfahrungsgemäß darauf hinaus,
> daß irgendwann einmal alle Geräte auf die jeweils anderen Geräte warten
> und keines sich mehr rührt.

Vom TO bestätigt:
>> - B erfasst Daten und wartet auf ein "Kommando". Trifft "Kommando" ein,
>> schickt es "Daten" an A.
>> - A wartet auf "Taste", und schickt dann "Kommando" an B. Zusätzlich
>> wartet es auf "Daten" und zeigt diese ggf. an.

"Warten" ist doof - und schreit nach Multitasking. Keine Panik, da 
reicht Round-Robin als Scheduler: Tasks einfach hintereinander schreiben 
und jeweils mit if (gibts_was_zu tun) { ... } klammern.

von Falk B. (falk)


Lesenswert?

Rudi S. schrieb:
> W.S. schrieb:
>> Mein Rat an dich wäre, die
>> angezielten Abläufe und Algorithmen strikt von dem 'Fußvolk' sprich
>> Lowlevel-Routinen zu trennen, um nicht an jeder Stelle von einer
>> Fußangel in die nächste zu treten.
>
> Sehr guter Vorschlag. Lässt sich auf Top-Down-Entwurf reduzieren.

Nö, das ist hier vollkommenen Overkill, vor allem unter Berücksichtung 
der Fähigekten des OPs. (klingt nicht nur so wie Opi, IST er auch!)

Beitrag "Re: Sende/Empfangsvorgang mittels nur 1St. µC"

> "Warten" ist doof - und schreit nach Multitasking.

Ja, ist hier aber nicht wirklich nötig, weil der Ablauf rein sequentiell 
ist.

Taste drücken
Anfrage senden
Antwort empfangen
Anzeigen

Da läuft nix parallel. Man muss nur die Empfangsroutine etwas robuster 
machen und ein Hängenbleiben vermeiden.

> Keine Panik, da
> reicht Round-Robin als Scheduler: Tasks einfach hintereinander schreiben
> und jeweils mit if (gibts_was_zu tun) { ... } klammern.

Da braucht es keinen Scheduler, da reicht ein einfacher, linearer 
Programmablauf! SHOCKING!

von Rudi S. (Gast)


Lesenswert?

Falk B. schrieb:
>> Keine Panik, da
>> reicht Round-Robin als Scheduler: Tasks einfach hintereinander schreiben
>> und jeweils mit if (gibts_was_zu tun) { ... } klammern.
>
> Da braucht es keinen Scheduler, da reicht ein einfacher, linearer
> Programmablauf! SHOCKING!

Wie DU das nennst ist mir sowas von schnurz-egal.

Aber lesen solltest Du dringend noch lernen. Hatte ich nicht geschrieben 
"Tasks einfach hintereinander schreiben ..."?

von Falk B. (falk)


Lesenswert?

Rudi S. schrieb:
> Wie DU das nennst ist mir sowas von schnurz-egal.
>
> Aber lesen solltest Du dringend noch lernen. Hatte ich nicht geschrieben
> "Tasks einfach hintereinander schreiben ..."?

Es gibt gar keine "Task", die kooperativ oder wie auch immer 
pseudoparallel laufen!

von W.S. (Gast)


Lesenswert?

Mir scheint, daß es letztlich denn doch auf saubere Lowlevel für den 
UART hinausläuft. Sowas OHNE Warten. Ab da scheint es glatt geradeaus zu 
gehen.

W.S.

von Rudi S. (Gast)


Lesenswert?

Falk B. schrieb:
> Ja, ist hier aber nicht wirklich nötig, weil der Ablauf rein sequentiell
> ist.
>
> Taste drücken
> Anfrage senden
> Antwort empfangen
> Anzeigen

Aber was ist, wenn die Anfrage, oder wenn die Antwort verloren geht?

Soll dann wirklicht der nächste Tastendruck ins Leere laufen? Oder - 
verlässt Du dich dann auf den Watchdog? Oder nimmst kurz die Batterie 
aus dem Gerät?

>> - A wartet auf "Taste", und schickt dann "Kommando" an B. Zusätzlich
>> wartet es auf "Daten" und zeigt diese ggf. an.

Das sind 2 unabhängige Aufgaben - auf Neudeutsch "task". Da kannst dich 
meinetwegen auf den Kopf stellen, das ändert aber nichts daran.

Ich erinnere nur an den Eingangspost des TO (Beitrag #6874430):
> Ich suche eine „neue“ Idee, wie 2 Vorgänge verschachtelt werden könnten,
> da meine bisherigen Programmierversuche nicht den richtigen Erfolg
> hatten.

Die Aufteilung in 2 Vorgänge hat "Opa" schon von Anfang an erkannt - und 
nur eine Methode gesucht, diese - wie er sich ausdrückte - zu 
'verschachteln'.

Die Sache ist total unkompliziert, wenn man beide Vorgänge (Aufgaben, 
Tasks, wie auch immer ...) so sieht, wie sie sind - nämlich unabhängig.

von Rainer V. (a_zip)


Lesenswert?

Jetzt mal ganz ehrlich...wir habe hier ein Prosa-Szenario akzeptiert, 
ohne überhaupt zu wissen, was da harwaremäßig abgeht. Ich habe 
verstanden, es gibt 3 Module, die über Uart verbunden sind. Damit ist 
für mich klar, dass es etwas wie RS422 oder so ist. Ist es aber wohl 
nicht... Also sonst... hat jedes Modul TX und RX. Damit das Event von 
Alternative 1 funktioniert, sehe ich folgende Situation. A, B, C haben 
jeder TX und RX. A.TX ist verbunden mit B. und C.RX.
Nun wird A getastet und schickt einen Befehl raus, daran erkennt B, dass 
er gemeint ist, C erkennt, "nicht für mich". Nun kann B seinerseits, 
nachdem er was immer auch gemacht hat, nicht über sein TX an C senden, 
denn das ist schon vergeben! Sein TX muß also auf das offene RX von A 
gehen und A kann nun anhand des "anderen Befehls" den Wert von B an C 
schicken!!!!
Wenn ich das alles wieder einmal völlig mißverstanden habe, dann möge 
man mir verzeiehen oder nicht...ich bin auch kein großer Verzeiher und 
kann damit leben.
Gruß Rainer

von Hannes (Gast)


Lesenswert?

Rainer V. schrieb:
> Wenn ich das alles wieder einmal völlig mißverstanden habe, dann möge
> man mir verzeiehen

Ich verzeihe Dir - aber nur, wenn Du mir mit deinem Blockschaltbild weg 
bleibst.

von Wolle G. (wolleg)


Lesenswert?

Rudi S. schrieb:
> Aber was ist, wenn die Anfrage, oder wenn die Antwort verloren geht?
Dann muss ich die Taste noch einmal betätigen.

> Die Aufteilung in 2 Vorgänge hat "Opa" schon von Anfang an erkannt - und
> nur eine Methode gesucht, diese - wie er sich ausdrückte - zu
> 'verschachteln'.
>
> Die Sache ist total unkompliziert, wenn man beide Vorgänge (Aufgaben,
> Tasks, wie auch immer ...) so sieht, wie sie sind - nämlich unabhängig.

Prima, dass es unkompliziert ist. Allerdings nicht für den Opa.
Vielleicht kann sich einer der Experten mal auf das niedrigere Niveau 
abseilen, und mein Programm so umbauen, dass es als eine Art 
Funkfernauslesegerät läuft.
Das Gerät B, welches die Messwerte an Gerät A senden soll, funktioniert 
schon entsprechend meinen Wünschen.  Für das Gerät A mit dem Taster, 
welches nach Tastendruck einen Code an Gerät B sendet und die von Gerät 
B gesendeten Daten empfangen und anzeigen soll, wird Hilfe gewünscht.
Ich hoffe, dass in meinen bisherigen Beiträgen und  meinem 
Programmschnipsel alle notwendigen Angaben, wie z.B. Adresse, Kanal und 
„Schlüsselwort“  (hier 0x56) bereits gemacht wurden. Falls noch weitere 
Fragen bestehen
--> nachfragen.

von Rainer V. (a_zip)


Lesenswert?

Nicht böse sein...aber ich glaub, ich fall' jetzt erst mal um...
Rainer

von Rudi S. (Gast)


Lesenswert?

Wolle G. schrieb:

>> Aber was ist, wenn die Anfrage, oder wenn die Antwort verloren geht?
> Dann muss ich die Taste noch einmal betätigen.

Das kannst du nicht, da dein Programm sich vielleicht festgefahren hat 
und u.U. für alle Ewigkeit auf eine Nachricht WARTET.


Ich zeige Dir mal ein paar Stellen, wo du einen sehr ungeschickten 
Programmierstil an den Tag legst:

--
Am Ende von main()
1
    _EINT();
2
    for(;;); 
3
  }

So musst Du alle Aktionen in den Interrupt-Routinen ausführen ...
Eigentlich hällt man die die ISR kurz und signalisiert nur Ergebnisse an 
andere Programmteile.

--
In antwort_empfangen()
1
   while(1)
2
   {

Die Funktion terminiert nie, kommt hier nie wieder raus...
1
    while (!(IFG2 & URXIFG1));

Hier wartest du auf irgendwas. Was, wenn die Bedingung nie eintritt?

--
In daten_senden()
1
     pause400();
Hier wird u.U. wertvolle Zeit verplempert.

--
Vielleicht siehst Du das Problem selbst: Warten, Däumchen drehen das 
wird so nicht hinhauen...

Ich hätte 2 (oder auch mehr) Aufgaben-Funktionen formuliert und die 
reih-um (Round Robin) abgetestet. Wenn die Aufgabe meint nichts tun zu 
müssen, returnt sie einfach.

Also GANZ GROB sowas:
1
void main(void)
2
{
3
  ....
4
  while(1) {           // Anmerk.: for(;;) gefällt mir nicht so 
5
    aufgabe_taste();   // Taste abfragen, ev. Befehl and B schicken
6
    aufgabe_daten_empfangen(); // Daten empfangen und ev. anzeigen
7
    aufgabe_daten_anzeigen();  // alternativ
8
  }
9
}
10
11
void aufgabe_taste(void)
12
  if !((P2IFG&BIT0) == BIT0) {      //Taster 2.0
13
    return;      // es gibt nichts zu tun, also schnell zurück
14
  } 
15
  P5OUT &=~BIT6;                 // LED grün EIN als Kontrolle
16
  ...
17
  kommando_senden();
18
}
19
20
void aufgabe_daten_anzeigen() {
21
   if !(neue_daten_da) {
22
     return;     // es gibt nichts zu tun, also schnell zurück
23
   }
24
   daten_auf_LCD_schieben();
25
}

Anmerkung: Diese Bitfummelei ist komplett unleserlich. Hier arbeitet man 
besser z.B. mit #define ... UNBEDINGT 'reparieren'!

Merke: Programme und Bücher haben eins gemeinsam: Sie wollen gelesen 
werden.

von Falk B. (falk)


Lesenswert?

Wolle G. schrieb:
> Falls noch weitere
> Fragen bestehen
> --> nachfragen.

Dann muss sie der OPA aber auch mal BEANTWORTEN!

von Wolle G. (wolleg)


Lesenswert?

Rudi S. schrieb:
> Wenn die Aufgabe meint nichts tun zu
> müssen, returnt sie einfach.

> Also GANZ GROB sowas:
Ich hoffe, dass ich es verstanden habe.
Noch zwei Fragen:
a) Was macht konkret "return"
b) Wie müsste die Funktion aufgabe_daten_empfangen(); konkret aussehen?
Könnte man dafür meine Funktion void antwort_empfangen(void) 
verwenden?(vermutlich nicht)

von Rudi S. (Gast)


Lesenswert?

Wolle G. schrieb:
> Rudi S. schrieb:
>> Wenn die Aufgabe meint nichts tun zu
>> müssen, returnt sie einfach.
>
>> Also GANZ GROB sowas:
> Ich hoffe, dass ich es verstanden habe.
> Noch zwei Fragen:
> a) Was macht konkret "return"
> b) Wie müsste die Funktion aufgabe_daten_empfangen(); konkret aussehen?
> Könnte man dafür meine Funktion void antwort_empfangen(void)
> verwenden?(vermutlich nicht)

zu a)
https://www.edutechlearners.com/download/books/The%20C%20Programming%20Language%20by%20Kernighan%20&%20Ritchie%20PDF.pdf

zu b)
zu Deiner antwort_empfangen() hatte ich doch schon was geschrieben - 
nämlich, dass sie in mehrfacher Hinsicht den Prozessor blockiert.

von Falk B. (falk)


Lesenswert?

OK, ich wünsche allen Teilnehmern dieser Diskussion viel Spaß und vor 
allem Erfolg. Wolle ist wohl nicht nur Ü80 sondern auch allgemein 
cognitiv nicht mehr sonderlich fit. Das artet hier in eine Therapiestude 
aus, für die ich weder qualifiziert noch motiviert bin.

von Rudi S. (Gast)


Lesenswert?

Wolle, du solltest dringend an deinem Programmierstil arbeiten. Ich kann 
Dir (leider) keinen C-Kurs bieten, aber vielleicht in die richtige 
Richtung schupsen.

Habe eben in deinen Code geschaut, und jetzt ist mir schwindelig ...

Nur so als Beispiel:

- void  D1_ausgeben(void)
- void  D2_ausgeben(void)
- void  D3_ausgeben(void)
- void  D4_ausgeben(void)

könnte man locker zusammen fassen zu z.B.
1
void  D_ausgeben(char data, int pos) {
2
  ...
3
  lcd_write_command(LCD_CMD_CURSOR_LA, pos);
4
  ...
5
  sprintf(vers,"%02X", data);
6
  ...
7
}

Aufgerufen wir das dann mit z.B. mit
1
D_ausgeben(D1, 106);
2
D_ausgeben(D2, 109);
3
...

Was heißt das nun? Man kann einen function() Werte mitgeben, und diese 
dann in der Funktion verarbeiten. Umgekehrt kann eine function() auch 
Werte zurückgeben...

Aber steht alles im K&R (in diesem Fall Chapter 4)

von Ralf G. (ralg)


Lesenswert?

Rudi S. schrieb:
> könnte man locker zusammen fassen
Das geht sogar noch weiter. Das gehört sich für alle 
'XX_ausgeben'-Funktionen.

von Rudi S. (Gast)


Lesenswert?

Ralf G. schrieb:
> Rudi S. schrieb:
>> könnte man locker zusammen fassen
> Das geht sogar noch weiter. Das gehört sich für alle
> 'XX_ausgeben'-Funktionen.

Hättest besser mal geschrieben: ACHTUNG - SPOILER!!! <grins>

Ich hatte eigentlich gehofft, Opa wäre da selbst drauf gekommen.

von Wolle G. (wolleg)


Lesenswert?

Rudi S. schrieb:

> zu b)
> zu Deiner antwort_empfangen() hatte ich doch schon was geschrieben -
> nämlich, dass sie in mehrfacher Hinsicht den Prozessor blockiert

Genau.
Und da ich das Problem nicht allein lösen konnte, hatte ich gehofft, 
dass ich hier im Forum Hilfe erhalten könnte,  indem man mir mein nicht 
funktionierendes Programm umschreibt, ergänzt oder ….
So war es mal „früher“, als hier  z.B.noch K.H.  Buchegger oder Rufus 
aktiv waren.
Aber, die Hoffnung stirbt zuletzt.

von Rudi S. (Gast)


Lesenswert?

Wolle G. schrieb:
> Rudi S. schrieb:
>
>> zu b)
>> zu Deiner antwort_empfangen() hatte ich doch schon was geschrieben -
>> nämlich, dass sie in mehrfacher Hinsicht den Prozessor blockiert
>
> Genau.
> Und da ich das Problem nicht allein lösen konnte, hatte ich gehofft,
> dass ich hier im Forum Hilfe erhalten könnte,  indem man mir mein nicht
> funktionierendes Programm umschreibt, ergänzt oder ….
> So war es mal „früher“, als hier  z.B.noch K.H.  Buchegger oder Rufus
> aktiv waren.
> Aber, die Hoffnung stirbt zuletzt.

Ich muss gleich weg, daher nur kurz eine allgemeine Antwort:

>> Wenn der Programmteil meint nichts tun zu
>> müssen, returnt sie einfach.

Sowas wie:
1
  while (!(IFG2 & URXIFG1));
2
  D2 = RXBUF1;
geht dann nicht.

Da müsste dann vielleicht stehen:
1
  if (!(IFG2 & URXIFG1)) {
2
    return;
3
  }
4
  D2 = RXBUF1;

Aber das hat Konsequenzen für den Programmaufbau. Schnell was Umfrickeln 
ist da vermutlich nicht.

von W.S. (Gast)


Lesenswert?

Wolle G. schrieb:
> Und da ich das Problem nicht allein lösen konnte, hatte ich gehofft,
> dass ich hier im Forum Hilfe erhalten könnte,  indem man mir mein nicht
> funktionierendes Programm umschreibt, ergänzt oder ...

Tja das ODER. Normalerweise erwartet man zunächst so etwas wie 
Ratschläge. Und zwar zu dem Zweck, daß man anhand selbiger das eigene 
Problem auch selber lösen kann. Und die sind hier in reichlicher Weise 
gekommen. Zu hoffen, daß jemand anderes einem den eigenen Brei vorkaut, 
damit man bloß noch zu schlucken braucht, ist vielleicht ein bissel 
zuviel. Allenfalls kann es passieren, daß da jemand ein anderes Rezept 
kochen würde und man auch einen Teller davon abkriegt. Kann eventuell 
auch ganz gut schmecken. Kommt aber auf die individuellen Geschmäcker 
an.

Also: sei lieber mental offen für Zeugs, was du noch nicht selber 
durchgekaut hast. Viele Wege führen nach Rom.

W.S.

von Peter D. (peda)


Lesenswert?

Der Trick ist ganz einfach nicht wartend programmieren, sondern 
abweisend. Ist das Ereignis noch nicht eingetroffen, geht die Ausführung 
zurück zur Mainloop, die dann andere Sachen machen kann.

Für die UART nimmt man üblicher Weise 2 FIFOs, die dann im Interrupt 
automatisch gefüllt bzw. geleert werden.
Außerdem entwickelt man erstmal ein Protokoll, mit dem der Empfänger 
sicher das Ende eines Datenpakets erkennen kann. Einfach nur Rohdaten zu 
senden, hat man vielleicht 1980 noch so gemacht.
Ein simples Protokoll sind lesbare Textdaten, die mit 0x0A/0x0D 
abgeschlossen werden. Die kann man dann auch leicht debuggen.

von Stefan F. (Gast)


Lesenswert?

Peter D. schrieb:
> Der Trick ist ganz einfach nicht wartend programmieren, sondern
> abweisend. Ist das Ereignis noch nicht eingetroffen, geht die Ausführung
> zurück zur Mainloop, die dann andere Sachen machen kann.

Schön formuliert, gefällt mir.

von W.S. (Gast)


Angehängte Dateien:

Lesenswert?

So, nachdem nun Peter nochmal dir ans Herz gelegt hat, was ich dir 
ebenfalls schon gesagt hatte, kommt von mir nochmal ein Denkanstoß zur 
Programmierung und zum Aufteilen von Quellen je nach Funktionsgruppen.

Ich habe die Quellen eben grad soweit zusammengekürzt, daß sie dich 
nicht verwirren sollten. Hoffentlich nix Wichtiges vergessen.

Ich habe auch schon mal die zwei Kommandos "REPORT" und "ANTWORT..." 
eingebaut, das letztere aber nur als Rumpf. Was du da in welcher Form 
senden willst, weißt du am besten.

Ein Grundgerüst hast du damit bereits. Du kannst also anfangen.

W.S.

von Rudi S. (Gast)


Lesenswert?

Peter D. schrieb:
> Der Trick ist ganz einfach nicht wartend programmieren, sondern
> abweisend. Ist das Ereignis noch nicht eingetroffen, geht die Ausführung
> zurück zur Mainloop, die dann andere Sachen machen kann.

+++ für die wirklich gelungene Formulierung!

> Für die UART nimmt man üblicher Weise 2 FIFOs, die dann im Interrupt
> automatisch gefüllt bzw. geleert werden.

@Wolle: Ich hoffe da schrillen irgendwelche Glocken. Das Prinzip FIFO 
ist recht ordentlich erklärt in
- https://data-flair.training/blogs/queue-in-c-cpp/ oder auch
- https://www.gpsworld.com/what-exactly-is-gps-nmea-data/
- (Wolle: unbedingt studieren, sonst bist Du abgehängt!)

Wer fühlt sich berufen, guten FIFO-Code beizusteuern? (C-code aus 
data.flair übernehmen?)

> Außerdem entwickelt man erstmal ein Protokoll, mit dem der Empfänger
> sicher das Ende eines Datenpakets erkennen kann. Einfach nur Rohdaten zu
> senden, hat man vielleicht 1980 noch so gemacht.
> Ein simples Protokoll sind lesbare Textdaten, die mit 0x0A/0x0D
> abgeschlossen werden. Die kann man dann auch leicht debuggen.

Mein Vorschlag: Lasst uns einfach bei NMEA spickeln ...

-> https://en.wikipedia.org/wiki/NMEA_0183#Message_structure

- Startzeichen vorne dran: '$'
- Kennung der Datenquelle (1 Zeichen): A bzw. B (Ode an Rainer)
- Trenner ","
- Festpunk-Zahl als Text z.B. "22.8" oder Text z.B. "S" (start)
- Endezeichen <LF> (0x0A)

Wer denkt sich den Rest des Protokolls aus und formuliert es?

von Rainer V. (a_zip)


Lesenswert?

Rudi S. schrieb:
> A bzw. B (Ode an Rainer)

na geht doch :-)
Rainer

von Rudi S. (Gast)


Lesenswert?

@ Wolle:
Könntest Du bitte mal die Version posten, bei der noch alles 
funktioniert hat - also die mit den 3 Geräten?

@ den Rest:
Mich würde brennend interessieren, wieso sich die Chose damals nicht 
aufgehängt haben soll.

Verwegener Plan: Vielleicht kann man vom alten, funktionierenden Code 
was ableiten? Z.B. den Code für Tastenabfrage und Senden des 
Abfragekommandos komplett in eine Interruptroutine packen, die per Timer 
alle Sekunde mal aufgerufen wird.

Totaler Pfusch, ich weiß: Eine Art brutales "Timesliceing" per 
Sledgehammer...

PS:
Opa könnte man beschäftigen mit 'Code aufräumen'. Nur 
void-void-Funktionen und ausschließlich globale Variablen - geht ja gar 
nicht ...

von Wolle G. (wolleg)



Lesenswert?

Rudi S. schrieb:
> Opa könnte man beschäftigen mit 'Code aufräumen'. Nur
> void-void-Funktionen und ausschließlich globale Variablen - geht ja gar
> nicht ...

Na ja. Der  Opa, der nur laienhafte Programmierkenntnisse hat, ist schon 
am "Limit" und  Aufräumen ist zunächst  von zweitrangiger Bedeutung. Er 
weiß auch nicht, wie ein aufgeräumter Zustand aussehen sollte. (Das 
Aufräumen könnte  dann vlt. von einem Programmierexperten in einem 
zweiten Schritt erfolgen ??)

Im Anhang der Code für die Version mit 3 Geräten.

Noch einmal eine kurze Erläuterung.
Der µC von Gerät A schickt über UART nach Tastendruck (P2.0)  an E32 in 
der Funktion  "daten_tx_festlegen();" die  4 Bytes  für Adresse, Kanal 
und  "Schlüsselbyte 0x56" an E32_868, welcher diese Daten drahtlos an 
das Gerät B sendet. E32_868 von Gerät B, mit der Adresse 0x0202 
konfiguriert, empfängt den Datenstrom und wenn der Schlüssel 0x56 
enthalten ist, dann sendet Gerät B an Gerät C (Adresse  (0x0303) den 
Messwert, wo er angezeigt werden kann.

: Bearbeitet durch User
von Rainer V. (a_zip)


Lesenswert?

Wolle G. schrieb:
> welcher diese Daten drahtlos an das
> Gerät B sendet. E32_868 von Gerät B, mit der Adresse 0x0202
> konfiguriert

Drahtlos ist mir jetzt neu! Habe ich da richtig schlimm geschludert??
Rainer

von Falk B. (falk)


Lesenswert?

Wolle G. schrieb:
> Na ja. Der  Opa, der nur laienhafte Programmierkenntnisse hat,

In der Tat. Was in aller Welt treibt dich dazu, SOLCHE Dateinamen zu 
verwenden? Warst du mal Germanistikprofessor?

> ist schon
> am "Limit" und  Aufräumen ist zunächst  von zweitrangiger Bedeutung.

Nicht ganz. Wenn auch andere durchsehen sollen, ist das wichtig.

> Er
> weiß auch nicht, wie ein aufgeräumter Zustand aussehen sollte.

Das ist eines der vielen Probleme.

> (Das
> Aufräumen könnte  dann vlt. von einem Programmierexperten in einem
> zweiten Schritt erfolgen ??)

Eher im Ersten. Hab ich ja schon mal gemacht, wenn gleich da noch was 
fehlte.

von Stefan F. (Gast)


Lesenswert?

Falk B. schrieb:
> Was in aller Welt treibt dich dazu, SOLCHE Dateinamen zu
> verwenden?

Das wird wohl ein ewiges Mysterium bleiben.

> for (i=65000;i>0;i--);  // warten ca.360ms

Viel Glück mit Compiler-Optimierung!

Jede Datei beginnt mit der Pinbelegung eines Mikrocontrollers. Aber sie 
stimmen nicht überein!

> ME2    |= UTXE1;  //  URXE1 +     // Enable USART1 TXD/RXD

Die wenigen Kommentare sollten wenigstens richtig sein, sonst verwirren 
sie bloss.

Das ist auch geil:

> void Wert1_ausgeben(void);
> void wert2_ausgeben(unsigned int Kanal);

Was für Werte werden da ausgegeben? Wo kommen die her?

Noch geiler:

> void temp_01_anzeigen(void);
Was ist mit 02..04 ?
> void temp_05_anzeigen(void);
> void temp_06_anzeigen(void);
> void temp_07_anzeigen(void);
> void temp_08_anzeigen(void);
> void temp_09_anzeigen(void);
> void temp_10_anzeigen(void);
> void temp_11_anzeigen(void);
> void temp_12_anzeigen(void);
> void temp_13_anzeigen(void);
> void temp_14_anzeigen(void);
> void temp_15_anzeigen(void);
> void temp_16_anzeigen(void);
> void temp_17_anzeigen(void);
> void temp_18_anzeigen(void);

Alles ohne Doku.

Dieses Muster zieht sich durch alle Dateien durch. In meiner Firma wäre 
dieser das ein Kündigungsgrund.

Dieser Quellcode ist wirklich schrecklich schlecht. Schmeiss ihn weg und 
fange nochmal neu an, nachdem du einen Plan hast, wie das Programm 
funktionieren soll.

von Rudi S. (Gast)


Lesenswert?

FYI - braucht man ja niocht doppelt machen

Ich verschön're mal die 
C--0194a-iar-TS-E32_868TD30-konfig_0303_und_empfangen__Ka09_b.c

von Falk B. (falk)


Angehängte Dateien:

Lesenswert?

Ok, entgegen meiner Aussage, diese Therapiestunde nicht fortsetzen zu 
wollen, hier dennoch mal ein Versuch. Siehe Anhang. Das ist ein 
komplexxtes Projekt für IAR Workbench. Ich hab auch mal dein 
Kauderwelsch wieder etwas zurecvht gerückt. Man schmeißt keine .h und .c 
Dateien in einen Topf bzw. eine Datei. Und man nutzt auch ganz sicher 
mal nicht solche kryptischen Dateinamen! Mach es EINFACH!

Bei dem Programm sollte mindestens die Taste P2.1 die grüne LED 
umschalten. P2.0 sollte die Anfrage per UART senden und die Antwort 
empfangen. Wenn das klappt, sind am Ende beide LEDs aus und auf dem LCD 
stehen die Daten. Viel Erfolg beim Testen.

von Falk B. (falk)


Lesenswert?

Stefan ⛄ F. schrieb:

> Dieses Muster zieht sich durch alle Dateien durch. In meiner Firma wäre
> dieser das ein Kündigungsgrund.

Arbeiten bei euch Ü80 Leute, die keine Ahnung vom Programmieren haben, 
es aber, warum auch immer, als Hobby betreiben?

> Dieser Quellcode ist wirklich schrecklich schlecht. Schmeiss ihn weg und
> fange nochmal neu an, nachdem du einen Plan hast, wie das Programm
> funktionieren soll.

Wird nicht funktionieren, das lernt der Wolle in diesem Leben nicht 
mehr.

von Stefan F. (Gast)


Lesenswert?

Falk B. schrieb:
> Arbeiten bei euch Ü80 Leute, die keine Ahnung vom Programmieren haben

Ich folge oft dem Vorbild alter Leute, weil ich deren Erfahrung 
wertschätze. Ich kenne zwei Programmierer die fast 80 sind und einen 
tadellosen Programmierstil haben.

Doch die von kritisierten Quelltexte sind nicht nur schlecht sondern 
schlimm. Wolle soll sich diese Quelltexte bitte nicht als Vorbild 
nehmen. Das ist der Punkt auf den es mir bei meinem Beitrag ankam.

von Rudi S. (Gast)


Angehängte Dateien:

Lesenswert?

Ersatz für 
C--0194a-iar-TS-E32_868TD30-konfig_0303_und_empfangen__Ka09_b.c

Ich habe möglicht wenig verändert, außer:

- Funktions-Parameter für sie display eingeführt
- D1, D2, ... in ein Array gepackt (fägt weiterhin bei 1 an ...)
- Funktionen vor main() gesetzt , Vorwärts-Deklarationen entfernt
- Formatierung/Indents berichtigt

@Wolle: kannst du das mal durch deinen Compiler schicken und ggf. auf 
"Gerät C" spielen und Unterschied zu 
"C--0194a-iar-TS-E32_868TD30-konfig_0303_und_empfangen__Ka09_b.c" 
testen?

von Wolle G. (wolleg)


Lesenswert?

Falk B. schrieb:
> Bei dem Programm sollte mindestens die Taste P2.1 die grüne LED
> umschalten. P2.0 sollte die Anfrage per UART senden und die Antwort
> empfangen.
1. Testbericht:
Die Taste P2.1 macht das, was sie soll.
Ich habe mal an RX von E32-868 den Oszi gehängt. Nach Tastendruck P2.0 
ist nur 1 statt 5 Zeichen auf dem Bildschirm zu erkennen.
Welches Zeichen es ist, kann ich nicht sagen.
Dadurch wird natürlich auch keine Antwort ausgelöst.

von Wolle G. (wolleg)


Lesenswert?

Rudi S. schrieb:
> @Wolle: kannst du das mal durch deinen Compiler schicken und ggf. auf
> "Gerät C" spielen und Unterschied zu
> "C--0194a-iar-TS-E32_868TD30-konfig_0303_und_empfangen__Ka09_b.c"
> testen?
Kann ich machen.
Aber was erwartest Du und worauf sollte ich wert legen?

von Rudi S. (Gast)


Lesenswert?

Wolle G. schrieb:

> Rudi S. schrieb:
>> @Wolle: kannst du das mal durch deinen Compiler schicken und ggf. auf
>> "Gerät C" spielen und Unterschied zu
>> "C--0194a-iar-TS-E32_868TD30-konfig_0303_und_empfangen__Ka09_b.c"
>> testen?

> Kann ich machen.
> Aber was erwartest Du und worauf sollte ich wert legen?

Ich würde gerne sicherstellen, dass die (bereinigte) Version von C 
funktioniert - bevor man da was Neues einbaut.

Hab da schon mal was vorbereitet ...

von Falk B. (falk)


Lesenswert?

Wolle G. schrieb:
> Falk B. schrieb:
>> Bei dem Programm sollte mindestens die Taste P2.1 die grüne LED
>> umschalten. P2.0 sollte die Anfrage per UART senden und die Antwort
>> empfangen.
> 1. Testbericht:
> Die Taste P2.1 macht das, was sie soll.

Schon mal ein erster Erfolg ;-)

> Ich habe mal an RX von E32-868 den Oszi gehängt. Nach Tastendruck P2.0
> ist nur 1 statt 5 Zeichen auf dem Bildschirm zu erkennen.

Sicher?

> Welches Zeichen es ist, kann ich nicht sagen.

Warum nicht? Ist der Oszi so alt wie du? ;-)
Wenn es ein Digitaloszi ist, kann man mit der richtigen 
Triggereinstellung das sichtbar macht. Triggermode NORMAL macht es 
möglich, plus richter Kanal + Schwellspannung.

von Falk B. (falk)


Lesenswert?

Wolle G. schrieb:
> Rudi S. schrieb:
>> @Wolle: kannst du das mal durch deinen Compiler schicken und ggf. auf
>> "Gerät C" spielen und Unterschied zu
>> "C--0194a-iar-TS-E32_868TD30-konfig_0303_und_empfangen__Ka09_b.c"
>> testen?
> Kann ich machen.
> Aber was erwartest Du und worauf sollte ich wert legen?

Bist du sicher, daß du hier zwei verschiedene Software gleichzeitig 
testen willst und kannst?

von Wolle G. (wolleg)


Lesenswert?

Falk B. schrieb:
> Ist der Oszi so alt wie du? ;-)
> Wenn es ein Digitaloszi ist,...

Nicht ganz.
Es ist analoger Oszi ohne eine Speicherfunktion.

von Rudi S. (Gast)


Lesenswert?

>> Rudi S. schrieb:
>>> @Wolle: kannst du das [C-200a.c] .... testen?

> Wolle G. schrieb:
>> Kann ich machen.
>> Aber was erwartest Du und worauf sollte ich wert legen?

Falk B. schrieb:
> Bist du sicher, daß du hier zwei verschiedene Software gleichzeitig
> testen willst und kannst?

@Wolle: Falk hat natürlich recht. Meine Idee war shice, also alles 
zurück. Und halt dich mal an ihn: Er ist mit Sicherheit der bessere 
Programmierer und Didakt.

von Falk B. (falk)


Lesenswert?

Wolle G. schrieb:
> Nicht ganz.
> Es ist analoger Oszi ohne eine Speicherfunktion.

Dachte ich mir. Aber ich glaube, du täuschst dich, weil du nur einen 
kurzen, komischen Puls siehst. Ich hab den Quelltext nochmal angeschaut, 
da müssen 5 Bytes rauskommen. Und ich wette, das tun sie auch. Aber mit 
deinem Oszi kann man das nur schwer sehen, erst recht mit Ü80 8-0

Irgendwie alles schwierig. Solche Ferndiagnosen und Fernfehlersuchen 
sind sehr nervig und zeitaufwändig. Das einfachste ist es, du schickst 
mir deine Module per Post und ich bieg das hier gerade. Das ist DEUTLICH 
schneller und nervenschonender, für alle Beteiligten. Allerdings musst 
du auch deinen Programmieradapter für den MSP430 mitschicken, ich hab 
keinen.

Schick mir eine Email, wenn du das so machen willst. Meine Adresse hast 
du ja schon.

von Wolle G. (wolleg)


Angehängte Dateien:

Lesenswert?

Falk B. schrieb:
> Das einfachste ist es, du schickst
> mir deine Module per Post und ich bieg das hier gerade.
Vielen Dank für Dein Angebot.

Ich hatte als Test mal meine mit "alt" gekennzeichneten Funktionen:
void daten_tx_festlegen_alt(void)
void daten_senden_alt(void)
in Dein Programm eingefügt.
Damit sind mit dem Oszi die 5 Bytes nachweisbar und mein Messmodul zeigt 
auch an (gelbe LED in der Datei „ 0193-iar_LP161_E32-868T_konf und 4x 
DS18B20_antworten.c), dass es den Messwert gesendet hat.
Vielleicht kannst DU den Unterschied erkennen und das Programm "main.c" 
entsprechend umbauen.

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Wolle G. schrieb:
> Vielleicht kannst DU den Unterschied erkennen und das Programm "main.c"
> entsprechend umbauen.

Naja, der sichtbare Unterschied ist nur, daß du in deiner Sendefunktion 
nach jedem Byte nochmal __delay_cycles (900); einfügst, das sind bei 
800kHz CPU-Takt (DCO nach Reset) mehr als 1 ms. Das kann man machen, ist 
aber eigentlich nicht nötig. Vermutlich aber schon, weil die Gegenstelle 
genauso so "toll" programmiert ist wie deine restliche Software 8-0
Also wirf deine alte Sendefunktion wieder raus und nimm meine, mit einer 
kleinen Änderung.
1
void daten_senden(const unsigned char *data, int cnt) {  
2
    int i;
3
4
    for (i=0; i<cnt; i++); {
5
        TXBUF1 = data[i];
6
        while (!(IFG2 & UTXIFG1));      // USART1 TX buffer ready?       
7
        __delay_cycles(900);
8
    }
9
}

von Wolle G. (wolleg)


Lesenswert?

Falk B. schrieb:
> Vermutlich aber schon, weil die Gegenstelle
> genauso so "toll" programmiert ist wie deine restliche Software 8-0

Richtig. Die Pause könnte entfallen.
Auch mit dem Einbau der Pause in Dein Programm ist auf dem Oszi nur
 1 Byte zu sehen.
Die Pause war eigentlichen vor allem dazu gedacht, die Anzahl der Bytes 
auf dem Oszi besserer erkennen zu können.
Zum anderen frage ich mich, was hier die "tolle" Software 8-0 mit der 
Gegenstelle zu tun haben könnte. Dort muss in erster Näherung noch 
nichts geändert werden.

Ich sehe zwar in Deiner Funktionen
void daten_senden(const unsigned char *data, int cnt)
gewisse Unterschiede zu meiner Funktion, kann aber die Auswirkungen 
nicht richtig beurteilen.
Vielleicht findest Du noch den Fehler.

: Bearbeitet durch User
von Leo C. (rapid)


Lesenswert?

Falk B. schrieb:
> for (i=0; i<cnt; i++); {

Ist das so gewollt? Also das ";" hinter der schließenden Klammer.

von Falk B. (falk)


Lesenswert?

Leo C. schrieb:
>> for (i=0; i<cnt; i++); {
>
> Ist das so gewollt? Also das ";" hinter der schließenden Klammer.

NEIN! DOCH! OHHHHHH!!

Natürlich NICHT! Wie kommt die denn dort hin? Mist!
Also eher so! Das erklärt auch, warum nur ein Byte gesendet wird.
1
void daten_senden(const unsigned char *data, int cnt) {  
2
3
    int i;
4
5
    for (i=0; i<cnt; i++) {
6
7
        TXBUF1 = data[i];
8
9
        while (!(IFG2 & UTXIFG1));      // USART1 TX buffer ready?       
10
11
        __delay_cycles(900);
12
13
    }
14
}

: Bearbeitet durch User
von W.S. (Gast)


Lesenswert?

Wolle G. schrieb:
> Zum anderen frage ich mich, was hier die "tolle" Software 8-0 mit der
> Gegenstelle zu tun haben könnte. Dort muss in erster Näherung noch
> nichts geändert werden.

Ähem... nun ja, wenn du sowohl blockierend sendest als auch blockierend 
empfängst, dann müssen nicht nur die Informationen überhaupt über den 
Draht gehen, sondern auch nur zu der Zeit, wo die Gegenstelle gerade 
zuhört. Eben das hat die "tolle" Software mit der Gegenstelle zu tun. 
Vorausgesetzt, meine Vermutung stimmt.

W.S.

von Wolle G. (wolleg)


Lesenswert?

Das war Teil 1. Prima!
Das Komma war zu viel. Es werden jetzt die 5 Bytes gesendet und vom 
Messmodul empfangen, was am Aufblitzen der gelben LED zu erkennen ist. 
Da am bereits funktionierenden Messmodul nichts geändert wurde, ist 
davon auszugehen, dass auch geantwortet wird.
Leider ist für die Antwort noch kein Erfolg zu sehen.
Mit meinen laienhaften Kenntnissen würde ich sagen, dass nicht direkt 
auf eine Antwort gewartet wird und damit der Eingang eines Datenstroms 
"verpasst" wird.

W.S. schrieb:
> über den Draht gehen,
> Eben das hat die "tolle" Software mit der Gegenstelle zu tun.
> Vorausgesetzt, meine Vermutung stimmt.
Die Module sind drahtlos verbunden. Zur Funktionsweise der Ansteuerung 
habe ich mich weiter oben ausgelassen (Version mit 3 Modulen)

von Falk B. (falk)


Lesenswert?

Wolle G. schrieb:
> Das war Teil 1. Prima!
> Das Komma war zu viel. Es werden jetzt die 5 Bytes gesendet und vom
> Messmodul empfangen, was am Aufblitzen der gelben LED zu erkennen ist.
> Da am bereits funktionierenden Messmodul nichts geändert wurde, ist
> davon auszugehen, dass auch geantwortet wird.

Es geht voran!

> Leider ist für die Antwort noch kein Erfolg zu sehen.
> Mit meinen laienhaften Kenntnissen würde ich sagen, dass nicht direkt
> auf eine Antwort gewartet wird und damit der Eingang eines Datenstroms
> "verpasst" wird.

Kann ein, die Funktion wartet nur 1000 Bitzeiten, das sind ~100ms. Du 
kannst ja mal mit deinem Nachkriegsoszi messen, wann die Antwort 
eintrifft.
Oder einfach mal die Zahl

#define TIMEOUT                     1000

auf 10000 oder mehr setzen. Maximalwert sind ~65500

von Wolle G. (wolleg)


Lesenswert?

Falk B. schrieb:
> Es geht voran!

So ist es. Vielen Dank für die Hilfe.
Jetzt läuft die Verbindung so, wie gewünscht.
Ein Problem war für mich u.a. der etwas andere Programmierstil durch die 
Zusammenlegung von Einzelschritten.

von Falk B. (falk)


Lesenswert?

Wolle G. schrieb:
> Falk B. schrieb:
>> Es geht voran!
>
> So ist es. Vielen Dank für die Hilfe.
> Jetzt läuft die Verbindung so, wie gewünscht.

Was hast du denn noch verändert? Wie lange muss die Software auf die 
Antwort warten? Hast du das mal gemessen? Merks du, daß ich die Fragen 
schon mal gestellt habe? Siehe Netiquette.

von Wolle G. (wolleg)


Lesenswert?

Falk B. schrieb:
> Was hast du denn noch verändert?   Siehe Netiquette.

Zunächst musste ich mich mit dem  "aufgeräumten" Zustand befassen, bei 
dem viele Funktionen zusammengefasst wurden. Z. B auch diese Zeile:
 for (i=0, j=0; i<TIMEOUT && j<4; i++ )
Die zusätzliche Änderungen der lc7981.h erschwerten mir das Verständnis.
Dadurch waren die Zusammenhänge für mich rel. schwer verständlich. 
Deshalb war der Fehler auch nicht sofort als Fehler zu  erkennen.
Es wurde zunächst immer nur 00000 ausgegeben.
Die Herausnahme der Zeile "daten_ausgeben(daten2);" und die Umstellung 
der Temperaturausgabe als Kommazahl führten zum gewünschten Verhalten 
bzw. Ergebnis.

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Wolle G. schrieb:
> Die zusätzliche Änderungen der lc7981.h erschwerten mir das Verständnis.
> Dadurch waren die Zusammenhänge für mich rel. schwer verständlich.

Hmm, dann bist du einer der scheinbar nicht wenigen Antilogiker ala 
Bome. Ich hab die Veränderungen gemacht, damit das EINFACHER lesebar 
wird. Was ist wohl verständlicher?
1
    lcd_write_command(LCD_CMD_CURSOR_LA,183);   // 26 Zeilenanfang 2.Zeile --> 26 Zeichen pro Zeile
2
    lcd_write_command(LCD_CMD_CURSOR_HA,0);

oder
1
lcd_set_cursor(1, 6);

Aber in deinem Alter und da es nur Hobby ist, darfst du die schrägeste 
"Logik" der Welt haben. Allerdings wird die Kommunikation mit deinere 
Umwelt, zumindest was die Probleme mit deiner Software angeht, damit 
deutlich schwerer. Egal, viel Spaß mit deinem Funkthermometer.

von Wolle G. (wolleg)


Lesenswert?

Falk B. schrieb:
> Aber in deinem Alter und da es nur Hobby ist, darfst du die schrägeste
> "Logik" der Welt haben.
Auch wenn Du  "Logik" und das Alter ständig wiederholst, würde mich mal 
interessieren, was die Ursache für die Fehlanzeige gewesen kann.

Nur mal so:
lcd_set_cursor(1, 6);
Wie man darauf kommt, da kann man zunächst nur "raten".

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Wolle G. schrieb:
> lcd_set_cursor(1, 6);
> Wie man darauf kommt, da kann man zunächst nur "raten".

Wenn man Englisch kann und sowas schon wenigsten EINMAL benutzt hat, ist 
das wie Muttersprache. Kein Witz.

von Falk B. (falk)


Lesenswert?

Wolle G. schrieb:
> Falk B. schrieb:
>> Aber in deinem Alter und da es nur Hobby ist, darfst du die schrägeste
>> "Logik" der Welt haben.
> Auch wenn Du  "Logik" und das Alter ständig wiederholst, würde mich mal
> interessieren, was die Ursache für die Fehlanzeige gewesen kann.

Dazu müßte ich erstmal wissen, wie die Fehlanzeige aussieht. Du hast 
auch das Problem, daß du die elementaren Probleme unserer Kommunikation 
nicht verstehst, siehe Netiquette.

"Daran denken, dass die Leute im Forum nicht neben einem sitzen und 
alles so vor sich sehen wie der Fragesteller"

Ich sehe NICHT, was du siehst! Und erzählen tust du nicht sonderlich 
viel, nichtmal auf direkte Fragen antworten, bestenfalls beim 3. Mal 
nachfragen.

von Wolle G. (wolleg)


Lesenswert?

Falk B. schrieb:
> Wolle G. schrieb:
>> lcd_set_cursor(1, 6);
>> Wie man darauf kommt, da kann man zunächst nur "raten".
> Wenn man Englisch kann und sowas schon wenigsten EINMAL benutzt hat, ist
> das wie Muttersprache. Kein Witz.
Mir reicht schon der Englischwahn in Zeitungen, Fernsehen usw. (z.B. 
boostern für Auffrischungsimpfung)
Andererseits gab es schon mal die Begriffe:
Arbeitsspeicher, Programmspeicher, Zentraleinheit oder Kellerspeicher

Außerdem sind wir hier in einem deutschsprachigen Forum. Da sollte doch 
die Anwendung der deutschen Sprache kein Problem sein.
Aber darum ging es mir in erster Linie gar nicht.
Das Problem war: Was soll der Klammerausdruck in  "lcd_set_cursor(1, 
6);" detailliert bewirken. Das war für mich nicht sofort ableitbar.

B)
>Dazu müßte ich erstmal wissen, wie die Fehlanzeige aussieht.
Ich möchte zwar nicht in den gleichen Stil wie Du verfallen.(z.B.
>Aber in deinem Alter und da es nur Hobby ist, darfst du die schrägeste
> "Logik" der Welt haben.
Würde Dir trotzdem vorschlagen, mal den Text vom 18.11. zu durchdenken:
>>Die zusätzliche Änderungen der lc7981.h erschwerten mir das Verständnis.
>>Dadurch waren die Zusammenhänge für mich rel. schwer verständlich.
>>Deshalb war der Fehler auch nicht sofort als Fehler zu erkennen.
>>Es wurde zunächst immer nur 00000 ausgegeben.
>>Die Herausnahme der Zeile "daten_ausgeben(daten2);" und die Umstellung
>>der Temperaturausgabe als Kommazahl führten zum gewünschten Verhalten
>>bzw. Ergebnis.
Daraus sollte sich ergeben, dass es um die Fehlanzeige des Wertes in der 
Zeile
"daten_ausgeben(daten1);" handelt.

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

Wolle G. schrieb:
> Falk B. schrieb:
>> Wolle G. schrieb:
>>> lcd_set_cursor(1, 6);
>>> Wie man darauf kommt, da kann man zunächst nur "raten".
>> Wenn man Englisch kann und sowas schon wenigsten EINMAL benutzt hat, ist
>> das wie Muttersprache. Kein Witz.
> Mir reicht schon der Englischwahn in Zeitungen, Fernsehen usw. (z.B.
> boostern für Auffrischungsimpfung)

Da bin ich teilweise bei dir!

> Andererseits gab es schon mal die Begriffe:
> Arbeitsspeicher, Programmspeicher, Zentraleinheit oder Kellerspeicher

Ja, gab es. In den 1960er und 1970er bei Siemens. Alles lange her, alles 
lange vorbei. Die Weltsprache der IT ist Englisch. Das ist auch OK. 
Denglisch ist das Problem (hirnlose Mischung aus Deutsch und Englisch).

> Außerdem sind wir hier in einem deutschsprachigen Forum. Da sollte doch
> die Anwendung der deutschen Sprache kein Problem sein.

Richtig, aber die Macht der Gewohnheit hat mich halt englische 
Funktionsnamen wählen lassen. Wenn ich dich näher kennen würde, hätte 
ich deutsche genommen.

> Aber darum ging es mir in erster Linie gar nicht.
> Das Problem war: Was soll der Klammerausdruck in  "lcd_set_cursor(1,
> 6);" detailliert bewirken. Das war für mich nicht sofort ableitbar.

Im Ernst? Warum in Aller Welt QUÄLST du dich mit Programmierung und C, 
wenn du nicht mal die elementarsten Kenntnisse hast? Entweder bist du 
ein Troll oder ein ARG schräger Typ?!? Auch auf die Gefahr hin, nur 
Blindleistung zu produzieren, hier die Erklärung für dich.

In lc7981.h stehen die Funktionsprototypen drin. Das sind die einfachen 
Beschreibungen der Funktionen und ihrer Parameter.
1
void lcd_set_cursor(unsigned int spalte, unsigned int zeile);

Ahhhhhh, hier habe ich selber DENGLISCH produziert! Asche auf mein 
Haupt! spalte und zeile sollten verständlich sein.

> Würde Dir trotzdem vorschlagen, mal den Text vom 18.11. zu durchdenken:

Das war DANACH! Wolle, du hast nicht nur massive Defizite im Bereich der 
Programmierung, auch in der Kommunikation (deutsch Gesprächsführung) im 
Internet. Sagte ich bereits.

> Daraus sollte sich ergeben, dass es um die Fehlanzeige des Wertes in der
> Zeile
> "daten_ausgeben(daten1);" handelt.

Wolle, lass es einfach und genieße deine Elektronik, die anscheinend 
jetzt so funktioniert, wie du es wolltest. Daß wir das geschafft haben, 
grenzt an ein Wunder 8-0

von Rainer V. (a_zip)


Lesenswert?

Falk B. schrieb:
> Wolle, lass es einfach und genieße deine Elektronik, die anscheinend
> jetzt so funktioniert, wie du es wolltest. Daß wir das geschafft haben,
> grenzt an ein Wunder 8-0

Ist ja auch bald Weihnachten...aber im Ernst, Beschäftigung mit 
Elektronik, Controllern, Programmiersprachen funktioniert ohne 
rudimentäre Englischkenntnisse einfach (fast) nicht. Dabei kann es auch 
schon mal egal sein, ob man englisch gelernt hat oder einfach nur 
solange nachschlägt, kombiniert, rätselt, bis man Sinn gefunden hat.

Falk B. schrieb:
> In lc7981.h stehen die Funktionsprototypen drin. Das sind die einfachen
> Beschreibungen der Funktionen und ihrer Parameter.

Kann man denn überhaupt irgendetwas machen, wenn man das schon nicht 
verstanden hat?? Also trotz Gratulation zum Erfolg doch auch ein 
Kopfschütteln...
Gruß Rainer

von Wolle G. (wolleg)


Lesenswert?

Rainer V. schrieb:
> Beschäftigung mit
> Elektronik, Controllern, Programmiersprachen funktioniert ohne
> rudimentäre Englischkenntnisse einfach (fast) nicht.

Doch, doch.  Das sollte schon in deutschsprachigen Foren funktionieren.

Etwas anders sehe ich das bei der Anwendung einer Programmiersprache. Da 
kann und sollte man sich weltweit auf eine Sprache einigen, was ja auch 
geschieht.
z.B.  main, char, for, while,   usw.
Mal was anderes:
Kennt ihr noch die Forenteilnehmer K.H. Buchegger oder Rufus?

von Falk B. (falk)


Lesenswert?

Wolle G. schrieb:
> Kennt ihr noch die Forenteilnehmer K.H. Buchegger oder Rufus?

Ja. Ersterer ist seit ein paar Jahren nicht mehr dabei, die Gründe kenne 
ich nicht. Zweiterer war noch ne Weile hier, hab ihn aber lange nicht 
mehr gelesen.

von Wolle G. (wolleg)


Lesenswert?

Falk B. schrieb:
> Ja. Ersterer ist seit ein paar Jahren nicht mehr dabei, die Gründe kenne
> ich nicht. Zweiterer war noch ne Weile hier, hab ihn aber lange nicht
> mehr gelesen.
Einen ähnlichen Kommunikationsstil, wie der der beiden Forenteilnehmer 
mit ihrer Art der Hilfe, würde ich mir heute wieder wünschen.
Man schilderte sein Problem und erhielt eine meinem Niveau angepasste 
Antwort in Form einer konkreten Änderung oder einer Ergänzung des 
entsprechenden Programmabschnittes. Dazu gab es noch ausführlichen 
Kommentar, sodass man die Änderung auch sofort verstehen konnte.

Jetzt mal ein neuer Versuch, aus dem man ableiten könnte, ob ich mich 
verständlich ausgedrückt habe:
Ich habe versucht, in der Funktion "void antwort_empfangen(void)" den 
Wert von daten1 mit Hilfe von:
void  Dx_ausgeben(char data) {
    lcd_set_cursor(0, 4);
    sprintf(tmp_string, "%02X", data);
    lcd_print_string(tmp_string);
}
mit ausgeben zu lassen. Auch wenn ich 02X in 04X ändere, werden nur
2 Stellen ausgegeben. Beispiel: Dezimalwert =378 --> Hexadezimal 17A ;
ausgegeben wurde 007A
Was könnte der Fehler sein?

von Falk B. (falk)


Lesenswert?

Wolle G. schrieb:
> Jetzt mal ein neuer Versuch, aus dem man ableiten könnte, ob ich mich
> verständlich ausgedrückt habe:
> Ich habe versucht, in der Funktion "void antwort_empfangen(void)" den
> Wert von daten1 mit Hilfe von:
> void  Dx_ausgeben(char data) {
>     lcd_set_cursor(0, 4);
>     sprintf(tmp_string, "%02X", data);
>     lcd_print_string(tmp_string);
> }
> mit ausgeben zu lassen. Auch wenn ich 02X in 04X ändere, werden nur
> 2 Stellen ausgegeben.

Logisch. Dein Funktionsparameter ist ein char, das sind beim MSP430 8 
Bit.
Für 16 Bit gibt es ja in deiner Software

void daten_ausgeben(unsigned int data)

Damit kann man 16 Bit Werte ausgeben, wenn gleich hier in dezimal.

Man kann auch deine Funktion auf 16 Bit umstellen.
1
void  Dx_ausgeben(unsigned int data) {
2
    lcd_set_cursor(0, 4);
3
    sprintf(tmp_string, "%04X", data);
4
    lcd_print_string(tmp_string);
5
}

: Bearbeitet durch User
von Wolle G. (wolleg)


Lesenswert?

Danke. Jetzt funktioniert es.
Für mich komisch. Ich bilde mir ein, dass ich es genau so schon mal 
gemacht hatte.
(Aber das ist jetzt mein Bier.)

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.