Schleife funktioniert nicht mehr richtig

Postby mr. teflon » Sat Feb 19, 2011 12:00 am

Hallo Sepp,

so ähnlich dachte ich mir das schon, dass ganze hat nur einen Haken. Ich bekomme so 5sec. lang oder 10sec. immer jeweils ein und selbe Temp. angezeigt. Ich möchte aber während den 5sec. bzw. während den 10sec. schon immer ständig die aktuelle Temp. sehen. Das heißt innerhalb der beiden "Anzeigepausen" müssen ständig die Temp. eingelesen werden. Aller 1sec. würde mir ausreichen. Wenn ich aller 1sec. nur einlese und anzeige würde damit auch das Flimmer bzw. Anzeigezappeln wegfallen. Was ich z.Z. mit 500ms künstlicher Verzögerung als angenehm ampfinde.

Damit bräuchte man dann doch bestimmt noch einen 2. Timer. Oder?
Oder geht das mit ein und demselben Timer nur mit zusätzlicher Zählervariablen? Meinst Du das so?

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
aller 1sec. neue Temp. messen/anzeigen/abspeichern
wenn sekundenzähler <=15, dann Bremsentemp ausgeben
aller 1sec. neue Temp. messen/anzeigen/abspeichern
wenn sekundenzähler ==15, dann sekundenzähler auf null zurücksetzen
Ende

Falls das messen/anzeigen/abspeichern zu lange dauern sollte gingen auch aller 2sec. Nur mache ich mir schon wieder Sorgen wegen der DCF77 Uhr. Die vielen Bits von Datum/Zeit vergleichen kostet auch viel Rechenzeit und dabei darf nicht mal eben so unterbrochen werden, sonst fehlt doch das nächste Bit vom Funksignal, denn das Funksignal wartet nicht bis ein längerer Interrupt fertig ist. Habe ich das wenigstens richtig verstanden?

Sonst muß ich das ohne DCF77 Uhr machen. Das wäre das Non plus Ultra für die Abspeicherung mit konkreter zeitlicher Zuordnung statt sturr in Sekundenschritten.

Nochmal wegen dem Ablauf oben. Das alles muß in einen Interrupt rein? Also das bisherige "Hauptprogramm" in einen Interrupt auslagern?
mr. teflon
 
Posts: 146
Joined: Fri Jan 03, 2014 1:48 pm

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

Nein, da hast Du einen Gedankenfehler.
Alle Temperaturen (egal welche angezeigt werden sollen, werden im Sekundentakt eingelesen, wenn wieder eine Sekunde voll ist. Ist ganz einfach.
Ein 2. Timer wäre Overkill.

Im Grunde kannst Du den Großteil Deiner Schleife im main() in den Interrupt verschieben und die Wartezyklen entfernen.

Das Speichern und Messen geht so schnell, dass der Controller in der Sekunde noch Zeit hat, den "Herrn der Ringe" zu lesen .

Das Funksignal holst Du Dir ebenfall über Interrupts. Du musst ihn dann entsprechend höher priorisieren, wenn er nicht unterbrochen werden darf.

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

Postby mr. teflon » Sun Feb 20, 2011 12:00 am

sepp2glNein, da hast Du einen Gedankenfehler.
Alle Temperaturen (egal welche angezeigt werden sollen, werden im Sekundentakt eingelesen, wenn wieder eine Sekunde voll ist. Ist ganz einfach. Ein 2. Timer wäre Overkill.


okay


Im Grunde kannst Du den Großteil Deiner Schleife im main() in den Interrupt verschieben und die Wartezyklen entfernen.


Meinst Du die richtige Main Schleife oder in der Interruptfunktion die main?


Das Speichern und Messen geht so schnell, dass der Controller in der Sekunde noch Zeit hat, den "Herrn der Ringe" zu lesen .


okay


Das Funksignal holst Du Dir ebenfall über Interrupts. Du musst ihn dann entsprechend höher priorisieren, wenn er nicht unterbrochen werden darf.


aha

und warum soll ich nochmal den Timer C verwenden nicht den X oder Z?

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

Postby sepp2gl » Mon Feb 21, 2011 12:00 am

Ich meine das, was Du jetzt in Deiner main()-Funktion stehen hast.
Die main()-Funktion muss natürlich bestehen bleiben. Es reicht aber wenn sie im wesentlichen die Initialisierung und eine Endlosschleife enthält (die auch leer sein darf).

TimerC weil der für Zeitsteuerungs-Augaben gedacht ist (16bit). Die anderen Timer sind nur 8bit und daher nur für einfache Signalaufgaben brauchbar. Außerdem bin ich ir nicht sicher, oob sie überhaupt eine Overflow-Erkennung haben. Hier hilft Dir ein Blick ins Hardware-Handbuch.

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

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

Hallo,

okay, Danke erstmal bis hier her. Ich werde jetzt mal anfangen alles gedanklich zu sortieren und loszulegen. Irgendwann melde ich mich wieder.
mr. teflon
 
Posts: 146
Joined: Fri Jan 03, 2014 1:48 pm

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

Hallo,

muß eine Zwischenfrage stellen, bevor ich mich und den µC tot flash.

Für den Timer C muß ich in der Vectortabelle der sect30.inc nur vector 27 setzen? Oder auch die compare0 und compare1?

Desweiteren lese ich im Hardware Manual Seite 70 (pdf 81) das der Timer C keine Funktion "Timer Mode" hat. Hattest Du das überlesen? Oder ist das irrelevant wenn ich den Overflow nutzen soll?

Wenn ja, muß ich nur folgende Register richtig setzen? Die Reihenfolge stimmt? Ob Input compare oder Output compare sollte egal sein, wie das Manual verstehe. Ich taste mich ran ...

prcrcm0cm1ocdprcrtcc0tcc1tcouttcc00 = 1;   // Bit0 = 1, Counter Start


Mit Timer X habe ich derzeit weiter probiert um verschiedene Aufrufe mit verschiedenen "Zeiten" aufzurufen. Im Grunde muß man nichts weiter machen als zusätzliche Zählvariablen einzubauen und entsprechend der gewünschten Funktion zuvergleichen und wieder zu nullen. Das klappt mit Timer X wunderbar.

Jetzt muß ich nur noch Timer C zum laufen bekommen.

void Timer_X_int(void){   counter++;   zaehler1++;   if (counter > 80)   {      p1_0 ^= 1;      counter = 0;     }    if (zaehler1 > 20)   {     p1_6 ^= 1;     zaehler1 = 0;   }}
mr. teflon
 
Posts: 146
Joined: Fri Jan 03, 2014 1:48 pm

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

Wenn Du das mit dem TimerX auch hinbekommst - umso besser.

Für den TimerC kannst Du alles mit Capture und Compare vergessen. Das brauchst Du für Deine Anwendung nicht.
Daher ist der Vector 27 der Einzige, den Du setzen musst.
Du musst zuletzt noch die Interrupt-Priorität setzen und den Interrupt "enablen".

Der TimerC ist immer im Timer-Mode; er hat keinen anderen da er immer interne Taktquellen nutzt.
Für den Betrieb brauchst Du eigentlich nur tcc0, tcc1

So ahnlich, wie Deine TimerX Routine kann auch die TimerC Routine aussehen
sepp2gl
 
Posts: 30
Joined: Fri Jan 03, 2014 1:50 pm

Postby mr. teflon » Sat Feb 26, 2011 12:00 am

Hallo,

ich habe den Timer C jetzt zum laufen bekommen. Letztlich lag ich schon ganz richtig, die Interrupt Priorität fehlte noch. Doch wie lautet der Befehl? Im Manual habe ich dazu nichts gefunden. Habe dann vom Timer X abgeguckt und habe auf tcic getippt. Wo steht sowas?
Danach funktionierte auch der Timer C Interrupt. Das der Timer C zählt hatte ich schon vorher gesehen mittels COM Ausgabe von Register tc. Aber er löste nicht aus. Was mich anderseits wundert, denn es gibt doch sowas wie eine Default Interrupt Priorität?

So, jetzt habe ich lange Zeit mit dem Timer C rumgespielt und mir eine Tabelle erstellt um die Port Frequenzen und die Interruptzeit auszurechnen und per Messung zu bestätigen. Dabei gibt es aber Probleme. Alles was schneller taktet wie 312kHz macht Probleme. Egal ob mit Multimeter oder Oszi gemessen. Wobei ich auf dem Oszi (30MHz HAMEG HM303-3) zusätzlich Geistertakte sehe. Das gleiche Signal optisch etwas schwächer dargestellt zeitlich verschoben. Das Oszi kann aber nicht kaputt sein, denn den Sinus vom 20MHz Quarz kann ich mittels 10:1 Teiler astrein ablesen.

Das gesamte Projekt habe ich angehangen. Man braucht nur die Quelle f vom Timer C zu ändern hat dann die Effekte wie in der Tabelle.

Ich habe auch schon einen 2. µC geflasht, mit dem gleichen Ergebnis. Ich weis nicht warum die Ports oberhalb von 312kHz machen was sie wollen. Selbst wenn ich das tc Register verschiebe und dann an einen bestimmten Port ausgebe kommt oberhalb von 312kHz Mist raus. Der Timer bzw. das Register tc scheint aber richtig zu arbeiten, sonst würden die höherwertigen Bits nicht takten wie sie sollen. Bin ratlos. Könnte das jemand bei sich testen?

Wegen der Compare Funktion. Auf der Suche nach Informationen im Internet, weil mich das Hardware Manual nicht zufrieden stellt, las ich über den AVR µC , dass man die Comare Funktion nutzt um einen Zählerstand vorzuladen um letztlich hochgenaue Timings zu erhalten. Mir reichen die Grundtimings mittels f1, f8 und f32, hörte sich jedoch gut an.

Tschau
Mr. Teflon
Attachments
Timer-C-Takte.png
Timer-C-Experimente.rar
(67.16 KiB) Downloaded 37 times
mr. teflon
 
Posts: 146
Joined: Fri Jan 03, 2014 1:48 pm

Postby sepp2gl » Sun Feb 27, 2011 12:00 am

Hallo Mr. Teflon,

wie gesagt: für Deine Anwendung brauchst Du keinen Compare.
Dein Programm sieht auf den ersten Blick OK aus.

Verwendest Du den HEW-Debugger für Deine Tests?

Aus Deiner Tabelle werde ich nicht schlau.
Was willst Du damit testen?
Aauf den unteren Bits ändert sich der Zählerstand schneller als Du ihn in der Software verabeiten kannst. Das ist doch ganz normal.
Du kannst Dich darauf verlassen, dass der Zähler richtig zählt.
sepp2gl
 
Posts: 30
Joined: Fri Jan 03, 2014 1:50 pm

Postby mr. teflon » Sun Feb 27, 2011 12:00 am

Hallo,

den KD30 Debugger verwende ich nur ganz selten. Ich komme damit nicht zurecht. Ich weis nicht wie ich live in die Register schauen kann. Und millionenmal auf STEP klicken macht keinen Spass.

Die Tabelle habe ich für mich erstellt, damit ich weis wie das Timer C Register arbeitet und wie schnell die Bits verschoben/"getaktet" werden. Erst theoretisch und dann praktisch nachweisen. Lerneffekt. Außerdem weis ich jetzt aller wieviel ms der Interrupt ausgelöst wird je nach Teiler f Einstellung.

Warum ich aber den Takt der Bits nicht messen kann die schneller wie 312kHz takten verstehe ich immer noch nicht. Wenn die Software nicht nachkommen würde, dann sollte man denken das man kein Bit vom Register tc ordentlich ausgeben und messen können. Dann sollte alles durcheinander geraten.
Im Gegenteil, wenn der Interrupt ausgelöst wird, sollten eher niedrigere Frequenzen "gestört" werden. Der Overflow Interrupt "taktet" ja nur mit 153Hz, 19Hz oder 5Hz, je nach Teiler f Einstellung.

Das sind meine Gedankengänge dazu.

Was anderes - wichtigeres.
Ich stehe wieder vor dem Problem, dass die Hauptschleife meine beiden MX6675 nicht einliest. Den AD Wandler aber schon. Die Befehle stehen hintereinander. Die MX6675 werden nur nach einem Reset einmalig ordentlich eingelesen.
Wenn ich in die Hauptschleife P1_0 ^= 1; einbaue, dann blinkt diese LED. Warum blinkt die LED sichtbar sehr langsam? Die sollte aber übelst schnell takten, sprich mit vollen CPU Takt, sodass man sie nicht blinken sehen dürfte. Irgendwie frisst der Timer C Interrupt sehr viel Rechenleistung.
Da bleibt zum lesen "Herr der Ringe" keine Zeit übrig.
Ich vermute dadurch kommt die MAX6675 Einlesefunktion durcheinander und kann den Chip per SPI nicht fehlerfrei auslesen. Die Taktleitung muß ja stimmen. Wenn vielleicht im dümmsten Moment des einlesens der Interrupt zuschlägt.
Also ist das mit dem Timer auch nicht so einfach.
Bei meinen ersten Gehversuchen mit dem Timer C und nur LEDs in den Schleifen fiel das Problem natürlich nicht auf.

Man liest ja man soll die Interrupt Funktion so klein wie möglich halten. Nur wie soll das gehen? Ich müßte ja alles hineinstopfen. Mit dem Ergebnis das für die Hauptschleife keine Rechenzeit mehr übrig bleibt. Damit kann ich die DCF77 Uhr vergessen.

Ideen?

Tschau
Mr. Teflon
Attachments
BikeTemp-v3.rar
(145.27 KiB) Downloaded 45 times
mr. teflon
 
Posts: 146
Joined: Fri Jan 03, 2014 1:48 pm

PreviousNext

Return to Das R8C-Projekt

Who is online

Users browsing this forum: No registered users and 1 guest