Schleife funktioniert nicht mehr richtig

Postby mr. teflon » Thu Feb 17, 2011 12:00 am

Hallo,

ich lasse mir abwechselnd die Lufttemp. (KTY10-6) und die Bremsentemp. (2x MAX6675) anzeigen. Dafür hatte ich vor langer Zeit eine etwas komplizierte If Schleife gebastelt die auch funktioniert. Hat allerdings beim weiteren Programmausbau den Nachteil, dass das Hauptprogramm durch die 2x 500ms Verzögerung gegen LCD flimmern unnötig ausgebremst wird.

Jetzt kam ich durch die jüngste Timer-X Spielerei auf die Idee zwar ständig die Temperaturen einzulesen aber nur aller paar Counts auch wirklich anzeigen zulassen. Was die 500ms ersetzen soll und damit das Hauptprogramm mit voller Geschwindigkeit laufen zu lassen. Dafür habe ich nur noch eine If Schleife eingebaut. Seltsamerweise funktioniert das nicht richtig. Die Lufttemp. wird zwar ständig eingelesen aber die MAX6675 nicht. Obwohl das nicht sein kann, weil die 3 Einlesefunktionen hintereinander stehen. Außerdem arbeitet das Programm irgendwie zu langsam. Die Counts müßten mit vollen µC Speed gezählt werden. Das heißt die 20 Counts Anzeigerefresh müßte flimmern und die 500 Counts zur Umschaltung müßte quasi ständig erfolgen. Auch müßte die Alarm LED mit 1 Count quasi ständig an sein und nicht blinken. Stattdessen dauert das alles auch Sekunden ...

Ich versuche schon seit Tagen Stück für Stück vorwärts und rückwärts das Problem zu finden. Bin alles hundertmal durchgegangen. Weis mir aber keinen Rat mehr. Könnte bitte jemand drüber schauen. Vielleicht sehe ich den Wald vor lauter Bäumen nicht mehr.

Zumindestens müssen doch beide MAX6675 eingelesen werden und die Alarm LED blinken sobald ich die Sensoren in die Finger nehmen. Mit der alten Version funktioniert das.

Tschau
Mr. Teflon
Attachments
BikeTemp-funktioniert.c
(40.33 KiB) Downloaded 26 times
BikeTemp-funktioniert-nicht.c
(40.35 KiB) Downloaded 25 times
mr. teflon
 
Posts: 146
Joined: Fri Jan 03, 2014 1:48 pm

Postby sepp2gl » Thu Feb 17, 2011 12:00 am

Ich habe natürlich nicht die Zeit, mich in das Programm einzulesen und zu verstehen, was es tun soll, und warum es nicht tut.

Auffällig ist, dass Du sehr, sehr viele warteschleifen hast. Das ist nicht besonders effektiv.
Durch die starr sequenzielle Abarbeitung hast Du natürlich Effekte, die Du nicht hättest, wenn Du Interrupts nutzen würdest, denn durch Interrupts lassen sich die einzelnen Funktionen gut entzerren.
Aus Deiner Bemerkung "Interruptspielerei" entnehme ich, dass Du das Prinzip der Interrupts noch nicht wirklich verstanden hast.
Mein Vorschlag:
Programmiere den TimerX-Interrupt so, dass er Dir die Routine aufruft, die alle 500ms, alle 5ms oder wann auch immer ausführen soll.
A/D Wandler lassen sich auch besser über Interrupts als durch Wartezyklen betreiben. Gleiches gilt für die serielle Schnittstelle.

Gruß, sepp2gl
sepp2gl
 
Posts: 30
Joined: Fri Jan 03, 2014 1:50 pm

Postby mr. teflon » Thu Feb 17, 2011 12:00 am

Hallo,

die Interruptfunktion habe ich tatsächlich noch nicht verstanden. Und ich meinte auch nicht Interrupt Spielerei sondern Timer-X Spielerei. Habe das soeben oben im Text korrigiert.

Du meinst zu viele Schleifen bringen einen eigentlich logischen Ablauf durcheinander? Was dann macht was es will und nicht soll?
Der Ablauf der nicht funktioniert wie er soll ist doch eigentlich eine Abarbeitung ohne künstliche Wartezeiten in Form von "wait_ms" oder ähnliches.
Wo ich Dir recht geben muß ist die Komplexität meiner Schleifen. Anders wußte ich mir damals nicht zu helfen.

Du meinst also ich soll erstmal einen Interrupt programmieren mit dem ich dann meine Funktionen aufrufe. Hmm. Stell ich mir im Augenblick schwierig vor. Der müßte ja allgemein gültig sein damit ich verschiedene Zeiten damit nutzen kann. Von ms angefangen damit die LCD Anzeige nicht flimmert bis mehrere Sekunden damit man eine Weile die jeweiligen Werte auch ablesen kann.

Im Moment stelle ich mir das so vor. Man müßte ständig den Interrupt abfragen und dann wohin springen. Damit komme ich sofort wieder zur If Schleife, damit kann man das auch machen. Ich komme in Gedanken einfach nicht von der If Schleife los.

Könntest Du mir zum Interrupt bitte etwas erklären zum Verständnis?

Tschau
Mr. Teflon
mr. teflon
 
Posts: 146
Joined: Fri Jan 03, 2014 1:48 pm

Postby sepp2gl » Fri Feb 18, 2011 12:00 am

Mr. Teflon,
der Weg des Lernenden ist meist steinig, bringt aber immer Erfolg.
Du bist mit Engagement und Zähigkeit dabei, und das ist gut.

In Embedded Systemen ist die Rechenzeit meist sehr knapp, sie daher mit Wartezyklen zu vergeuden, immer der flasche Weg.

Ein Programm, das effizient mit Interrupts arbeitet, ist meist folgendermaßen aufgebaut:
1. Hauptprogramm
- Initialisierungen
- Endlos-Warteschleife mit Aufgaben, die "irgendwann" ausgeführte werden sollen

2. Timer-Interrupt alle 1ms,
am besten mit TimerC, in dem alle Aufgaben laufen, die ein festes Zeitraster
(5ms, 10ms, 100ms, 500ms) haben sollen.

3. Peripherie Interrupts (ADC, RS232, etc.)
um den Ablauf der IO-Operationen zu steuern, ohne dass auf Ereignisse
gewartet weren muss.

Generell wird nicht auf Interrupts gewartet; Interrupts unterbrechen einen Programmablauf, erledigen ihre Aufgabe und kehren dann automatisch an die Stelle zurück, die sie unterbrochen haben.

Interrupt-Routinen werden mit "#pragma interrupt" deklariert und Ihre Adresse muss in den Interrupt-Vektor in der Datei "sect30.inc" eingetragen werden.
Damit der Interrupt ausgelöst werden kann, muss er vorher eine Priorität erhalten, und Interrupts müssen "enabled" werden.
Mehrere Interrupts können sich auch gegenseitig unterbrechen, daher ist es wichtig, die Prioritäten der einzelnen Interrupts festzulegen.

Ich habe als Beispiele zwei Dateien angehängt, die das Vorgehen illustrieren.
Ich verwende eigene Namensdefinitionen für die R8C-Adressen, die ich nicht weitergebe. Ich glaube aber, dass der Code halbwegs lesbar ist.

Gruß, sepp2gl
Attachments
ICE-Sim.c
(6.09 KiB) Downloaded 29 times

[The extension inc has been deactivated and can no longer be displayed.]

sepp2gl
 
Posts: 30
Joined: Fri Jan 03, 2014 1:50 pm

Postby mr. teflon » Fri Feb 18, 2011 12:00 am

Hallo,

Danke erstmal für die Hilfe. Ich guck mir das mal an und werde mich rantasten. Sieht auf den ersten Blick kompliziert aus. Wenn ich das dann einmal verstanden habe sollte mit den Interrupts werde ich mein eigentliches Programm weiterbearbeiten. Ohne Verständnis der Interrupts geht es demzufolge dort nicht sinnvoll weiter. Soviel habe ich verstanden.

Tschau
Mr. Teflon
mr. teflon
 
Posts: 146
Joined: Fri Jan 03, 2014 1:48 pm

Postby sepp2gl » Fri Feb 18, 2011 12:00 am

Ohne Verständnis geht grundsätzlich nichts.
Aber Interrupts sind das täglich Brot bei embedded control.
Beispiel: Wer von uns stellt sich schon vor die Haustür und wartet, bis jemand kommt? Dafür haben wir die Klingel (=Interrupt). Wenn es kingelt, unterbrechen wir, was wir gerade tun und lassen sden Ankömmling herein. Danach machen wir weiter.

Du solltest ähnlich meines Beispiels nocheinmal komplett neu anfangen und erstmal mit dem TimerC experimentieren.
Mein Programm verwendet beim TimerC den Overflow-Interrupt (den kennst Du ja schon) und die Compare-Funktion.
Du brauchtst wahrscheinlich nur die Overflow-Funktion.
Du kannst den TimerC über die "Prescaler" so steuern, dass er Dir jede Millisekunde einen Overflow-Interrupt gibt.
In der zugehörigen Routine kannst Du dann einfach einen Zähler laufen lassen und bei 10, 50, 100, 500 jeweils die entsprechenden Funktionen nach Bedarf ausführen.
Wenn Du das mal verstanden hast, ist es recht einfach auch die anderen Interruptsquellen entsprechend zu bedienen.
Voraussetzung ist, dass Du das Renesas R8C-Manual zum nachlesen hast.

Bist Du in der Aubildung? Oder warum interessiert Dich die Controller-Programmierung?

Gruß, sepp2gl
sepp2gl
 
Posts: 30
Joined: Fri Jan 03, 2014 1:50 pm

Postby mr. teflon » Fri Feb 18, 2011 12:00 am

Hallo,

den Timer-C Overflow kenne ich noch nicht. Habe bisher nur mit Timer-X rumgespielt und damit eine LED blinken lassen bzw. die verschiedenen Frequenzen der Ports mittels Oszi ausgemessen.

Okay, was ein Interrupt ist habe ich verstanden.
Nur wenn man dann wieder einen zusätzlichen Zähler mit If Schleife benötigt, um größere Zeiten zu erreichen, ist plötzlich der Sinn eines extra Interrupts bei mir weg. Denn die If Schleife ist dann eh wieder vorhanden.

Außerdem, nach derzeitiger Überlegung, würde doch immer nur die 1. Funktion aufgerufen.

Bsp.
5 Sekunden lang soll die Lufttemp. angezeigt werden, danach für 10 Sekunden die Bremsentemp.
Wenn ich das mit einem Interrupt mache, würde doch nie die Bremsentemp. angezeigt, weil der erste Zähler schon wieder seine 5sec. Bedingung erfüllt sieht.

Irgendwie kommen meine Gedanken noch nicht mit. Ich müßte dann noch was einbauen damit die 1. Funktion übersprungen wird.

Das R8C13 Hardware Manual hatte ich schon runtergeladen. Deutsch wäre mir lieber, aber geht schon so.

Mein Interesse ist rein privater Natur. Meine Ausbildung liegt schon 16 Jahre zurück. In der Ausbildung haben wir eine AEG SPS programmiert nur ganz kurz eine S5 und im Unterricht damals noch einen Z80 in Assembler durchgenommen. Das ging mir aber zu schnell mit dem Z80. So richtig verstanden hatte ich das nie obwohl ich dafür schon Interesse hatte. Die AEG SPS Programmierung fand ich im Vergleich einfacher. Sie S5 schon komplizierter. Das µC Interesse wurde erst wieder richtig geweckt als ich vom R8C13 lesen durfte und hatte die Hefte und das Buch nachbestellt. Mittlerweile ist auch schon der erste R8C13 verstorben.

Tschau
Mr. Teflon
mr. teflon
 
Posts: 146
Joined: Fri Jan 03, 2014 1:48 pm

Postby sepp2gl » Fri Feb 18, 2011 12:00 am

Hallo Mr. Teflon,
ich bin noch nicht dahintergestiegen, was genau Dein Controller machen soll.
Kannst Du mir eine grobe Funktionsbeschreibung machen?

Ich verstehe insbesondere nicht, warum Du 5s die eine Information anzeigen willst und danach 10s die andere. Was für ein Display ist das?

Gruß, sepp2gl
sepp2gl
 
Posts: 30
Joined: Fri Jan 03, 2014 1:50 pm

Postby mr. teflon » Fri Feb 18, 2011 12:00 am

Hallo Sepp,

ich messe 2 Temperaturen von 2 Bremsen. Mit zwei MAX6675. Dazu noch die Umgebungslufttemperatur mittels KTY10-6. Den KTY10-6 könnte man auch noch durch einen dritten MAX6675 ersetzen. Muß aber nicht sein. Dazu habe ich ein 2x16 LCD Display des Typs EA DOGM 162. Das wird per SPI angesprochen. Ich habe auch noch ein 3 zeiliges da, dass EA DOGM 163. Aber beim 2 zeiligen ist die Schrift größer und es muß auch mit dem 2 zeiligen lösbar sein.

einmal erscheint:
Lufttemperatur
21,6°C

und dann:
P3.2 153,3°C
P3.3 140,8°C

diese beiden Informationen sollen unterschiedlich lang angezeigt werden, weil mir die Bremsentemperaturen wichtiger sind, sollen diese länger angezeigt werden. Die 5 / 10sec. ist nur erstmal so eine Vorgabe von mir. Kann später auch 3 / 15sec werden.
Zusätzlich wird die Bremsentemp. mit einem Grenzwert verglichen bei der dann eine Alarm LED blinkt. Später soll noch die DCF77 Uhr mit rein und das abspeichern der Bremsentemperaturwerte auf eine SD-Karte. Wegen letzteren beiden, was Zukunftmusik ist, muß ich meine komplizierten Warteschleifen umbauen, sonst funktioniert die DCF77 Uhr mit Sicherheit niemals. Das Bsp. der DCF77 aus dem Forum bzw. aus dem Mikrocontroller Sonderheft 1 Seite 66 funktioniert ja einzeln wunderbar. Einen 1sec Interrupt würde ich aber bestimmt sowieso benötigen, wenn ich ich jede Sekunde die Messwerte abspeichern möchte.

Ist das Vorhaben jetzt verständlicher?

Tschau
Mr. Teflon
mr. teflon
 
Posts: 146
Joined: Fri Jan 03, 2014 1:48 pm

Postby sepp2gl » Sat Feb 19, 2011 12:00 am

Kann man sagen.
Jetzt weiß ich worum es geht.

Also hier das Vorgehen:
- TimerC mit dem Vorteilern auf die langsamste Taktrate bringen
- TimerC Overflow Interrupt-Routine
Overflows zählen, bis 1s erreicht sind.
Temperaturen messen
Overflowzähler zurücksetzen
Sekundenzähler incrementieren
wenn sekundenzähler < 5, dann lufttemp ausgeben
wenn sekundenzähler <=15, dann Bremsentemp ausgeben
wenn sekundenzähler ==15, dann sekundenzähler auf null zurücksetzen
Ende

Der Punkt ist, dass für den Prozessor dabei jede Menge Zeit für andere Aufgaben bleiben.

Gruß, sepp2gl
sepp2gl
 
Posts: 30
Joined: Fri Jan 03, 2014 1:50 pm

Next

Return to Das R8C-Projekt

Who is online

Users browsing this forum: No registered users and 1 guest