Hallo, ich habe eine Frage und zwar ich will mein Timer1 bei Atmega16 nullen und bei einem bestimmten Zustand abfragen . Dieser Wert wird gespeichert und im Lauf des Programmes dekrementiert und das ist meine Frage mit welchem Frequenz wird mein Wert dekrementiert. bei Timer1 benutze ich noch den 8 Vorteiler. und hab ein extern 4MHz Quarz.
Hä? Wenn du spezifische Fragen zu einem Code hast, dann zeig den Code und versuch nicht ihn zu beschreiben. Auf die Art * hast du weniger Arbeit * müssen wir nicht raten
Der Timer inkrementiert (außer zeitweise in bestimmten PWM-Modes). Das sollte in den seltensten Fällen ein Problem sein, in Rechnungen damit dreht sich halt das Vorzeichen. Was mich wundert: > und das ist meine Frage mit > welchem Frequenz wird mein Wert dekrementiert. Danach schreibst Du: > bei Timer1 benutze ich noch den 8 Vorteiler. > und hab ein extern 4MHz Quarz. und Du kannst das nicht selbst ausrechnen?
hier mein Code : #include <avr/io.h> #include <stdint.h> #ifndef F_CPU #define F_CPU 4000000UL #endif uint16_t Timer; int main(void) { TCCR1B |= (0<<CS10)|(1<<CS11)|(0<<CS12); // 8-Prescaler while(1) { while ((PIND & (1 << PD1))) {} TCNT1 = 0; while ((PIND & (1 << PD2))) {} Timer = TCNT1; while ((PIND & (1 << PD3))) {} /*Korrekturswert dekrementieren*/ for (;Timer!=0; Timer--) {} } }
Und jetzt das ganze nochmal, diesmal aber etwas struktuerierter und sauberer formatiert, damit auch schnell sieht, was der Code eigentlich macht
1 | #include <avr/io.h> |
2 | #include <stdint.h> |
3 | #ifndef F_CPU
|
4 | #define F_CPU 4000000UL
|
5 | #endif
|
6 | |
7 | uint16_t Timer; |
8 | int main(void) |
9 | {
|
10 | TCCR1B |= (0<<CS10)|(1<<CS11)|(0<<CS12); // 8-Prescaler |
11 | |
12 | while(1) |
13 | {
|
14 | while ((PIND & (1 << PD1))) |
15 | {}
|
16 | |
17 | TCNT1 = 0; |
18 | while ((PIND & (1 << PD2))) |
19 | {}
|
20 | |
21 | Timer = TCNT1; |
22 | while ((PIND & (1 << PD3))) |
23 | {}
|
24 | |
25 | /*Korrekturswert dekrementieren*/
|
26 | for (;Timer!=0; Timer--) |
27 | {}
|
28 | }
|
29 | }
|
Analyse: Der Code macht nichts erkennbar Sinnvolles. Dir gehst warscheinlich um diesen Teil hier
1 | /*Korrekturswert dekrementieren*/
|
2 | for (;Timer!=0; Timer--) |
3 | {}
|
Nun. Je nach Compilereinstellung verbraucht der im Extremfall praktisch 0 Zeit. Dies deshalb, weil ihn der Compiler durch
1 | Timer = 0; |
ersetzt. Macht nämlich im Endeffekt genau dasselbe, nur gehts schneller. Und dienstbeflissen wie Compiler nun mal sind, versuchen sie immer die schnellste Lösung zu finden :-) Fangen wir mal so an: Was soll es denn eigentlich werden?
Stimmt er macht nix ist ein teil von einem Programm ich werde erstmal ein Flußdiagramm zeichnen und mein code hier rein machen. Danke
1- Das Programm soll auf Startsignal von dem Taktgeber gewartet. 2- Es wird dann auf den nächsten Nulldurchgang der Prüfspannung(Komparator) von negativer zu positiver Halbwelle gewartet. 3- Das Stromdetektorsignal kennzeichnet den Einschaltzeitpunkt.Mit der Signalflanke des Stromdetektorsignals wird der Zählerstand von Timer 1 auf "0" gesetzt. Das programm ist Phasensynchronsteuerung für universellen Einstaz an Prüfständen mit pneumatischen Aktoren. Ich hoffe ihr könnt mir helfen, weil ich schon seit paar Wochen keinen Weg mehr finde. Danke im Voraus :)
nur wenn ich wüsste :) soory ich hab das Bild ja nur als PNG hochgeladen was ja von mir verlangt wurde ...
Jar schrieb: > Ich hoffe ihr könnt mir helfen, weil ich schon seit paar Wochen keinen > Weg mehr finde. Wochen? Such dir jemanden, der programmieren kann Ist deine beste Option.
Ah, 1,2,3 sind PNGs? Dann Speicher ich die mal als 1.png 2.png und 3.png
1 | // Timer1 nullen
|
2 | TCNT1 = 0; |
3 | |
4 | // steigende Flanke von dem Komparator warten
|
5 | while (!(PIND & (1 << PD1))) |
6 | {}
|
7 | while ((PIND & (1 << PD1))) |
8 | {}
|
9 | |
10 | // Timer abfragen und in Timerswert speichen
|
11 | Timer_wert = TCNT1; |
Da sind IMHO Probleme drin. Einen Überlauf von TCNT1 bekommst du nicht mit. Deine Messmimik funktioniert nur bis zu einer bestimmten Frequenz. Als Abhilfe für dieses Problem könnte man einen Overflow-Interrupt einrichten und die Zahl der Overflows mitzählen. Die Messung misst nicht immer eine volle Periode. Angenommen bei TCNT1 = 0 ist die 2. Halbperiode aktiv (PIND & (1 << PD1)), dann bekommst du in Timer_wert nur die Restlaufzeit der 2. Halbperiode :( Als Abhilfe für das 2. Problem könnte man unmittelbar vor TCNT1 = 0 eine Warteschleife einfügen, die auf einen definierten Beginn einer Periode wartet. Als grundsätzliche Verbesserung könnte man die Input Capture Unit des AVR nutzen, die definierte Zeitstempel liefert, wenn der Komparator auslöst.
Jar schrieb: > nur wenn ich wüsste :) > soory ich hab das Bild ja nur als PNG hochgeladen was ja von mir > verlangt wurde ... Nur nebensächlich: Hast du auf deinem PC die Dateiendungen PNG ausgeblendet oder überhaupt nicht verwendet? Im Moment kann ich mir nämlich nicht erklären, wie die beim Upload innerhalb der Forensoftware verloren gehen konnten (Bug?).
hier nochmal die Bilder ich hoffe diesmal klappts. Karl heinz Buchegger : ja stimmt ich brauche ein Programmierer und deshalb bin ich hier damit ihr mir hilft und hoffe könnt mir helfen.
Jar schrieb: > Karl heinz Buchegger : ja stimmt ich brauche ein Programmierer und > deshalb bin ich hier damit ihr mir hilft und hoffe könnt mir helfen. Kein Problem. Willst du meinen Stundensatz wissen? (So war das gemeint. Im Ernst! Wenn du von Automotoren keine Ahnung hast, bringst du ihn ja auch in eine Werkstatt, wo sich Mechaniker, die sich damit auskennen um deinen Motor kümmern. Das hat er in seiner Ausbildung gelernt. Nur beim Programmieren glaubt jeder, er könne das in 2 Nachmittagen in Eigenregie hinkriegen) Wochen! Dein Problem, das man noch einmal in einer strengeren und ausführlicheren Aufgabenbeschriebung zusammenfassen müsste, sieht für mich erst mal nach einem Softwaremonoflop aus, bei welchem sich die Verzögerungszeit aus irgendwelchen Zusatzbedingung ergibt. Ohne die Hardware bauen zu müssen und wenn es mit den Signalen keine Schwierigkeiten gibt, ist so was für einen geübten Programmierer eine Sache auf 1 Tag, maximal 2 (wobei die meiste Zeit da drauf geht, dir die Datails der Aufgabenstellung aus der Nase zu ziehen) Nicht Wochen.
----> Einen Überlauf von TCNT1 bekommst du nicht mit. Deine Messmimik funktioniert nur bis zu einer bestimmten Frequenz. ->Es soll keinen Überlauf geben: 1- Timer1 ist 16 bit 2- ich nulle mein Timer1 und er zählt bis nächste steigende Flanke von dem Komparator kommt . Der Komparator ist 50H und ich benutze 4MHz takt das heisst 4 MHz durch 50 Hz ergibt 80000 Hz und noch durch 8 Prescaler ergibt 10000 Hz. ich hoffe ich hab auch richtig gedacht.
Karl heinz Buchegger schrieb: > Wochen! > Dein Problem, das man noch einmal in einer strengeren und > ausführlicheren Aufgabenbeschriebung zusammenfassen müsste, sieht für > mich erst mal nach einem Softwaremonoflop aus, bei welchem sich die > Verzögerungszeit aus irgendwelchen Zusatzbedingung ergibt. > Ohne die Hardware bauen zu müssen und wenn es mit den Signalen keine > Schwierigkeiten gibt, ist so was für einen geübten Programmierer eine > Sache auf 1 Tag, maximal 2 (wobei die meiste Zeit da drauf geht, dir die > Datails der Aufgabenstellung aus der Nase zu ziehen) Stimmt Karl ich hab Problem die Aufgabenbeschreibung richtig auszudücken und es liegt dran, dass ich erst seit 3 jahren in Deutschland bin. Zwar ist kein Grund dass du mir dann weiter hilfst Danke trotzdem.
Deine Flankenerkennungen sind alle falsch rum Die for Schleife mit dem Korrekturwert ist immer noch eine 0-Operation. Was ist dieser Korrekturwert überhaupt? Was macht er? Was stellt er dar? Ist das eine Zeit, oder Äpfel oder Birnen oder ... ? Nachdem die Sache mit dem Flussdiagram noch nicht wirklich gegriffen hat, geh doch noch einen Schritt zurück: Beschreibe in Worten welcher Ablauf gelten muss. Vergiss den technischen Brimborium und benutze deine eigenen Worte. Nummeriere die einzelnen Schritte durch, damit du dich auf sie beziehen kannst Also 1) auf fallende Flanke vom Taktgeber warten 2) auf steigende Flanke vom Komperator warten 3) ... 4) ...
Karl heinz Buchegger schrieb: > Deine Flankenerkennungen sind alle falsch rum >>>>>>>>>> wieso sind sie falsch rum??? > Die for Schleife mit dem Korrekturwert ist immer noch eine 0-Operation. >>>>>>>>>> ich würde gern wissen warum?? mein Korrekturwert ist am Anfang 0 aber bei der nächste Schleife ändert sich . > > Was ist dieser Korrekturwert überhaupt? > Was macht er? > Was stellt er dar? > Ist das eine Zeit, oder Äpfel oder Birnen oder ... ? > > Korrekturwert ist die Zeitdifferenz zwischen mein Istzeit und Sollzeit Es geht um Schalter, die mit einem bestimmten Phasenwinkel betätigt sein sollten.250V AC 50Hz, dies wird durch ein externe Schaltung digitalisiert(Komparator)und als Eingang für dem Microkontroller benutzt. wenn der Schalter betätigt ist, es gibt eine externe Schaltung mit Stromdetektor, der mir eine steigende Flanke liefert, wenn strom durch den Schalter fließt. 0) Sollwinkel lesen und zeitlich umrechnen 1) auf fallende Flanke vom Taktgeber warten 2) auf steigende Flanke vom Komperator warten 3) korrektur dekrementieren bis 0 wird 4) Ventil einschalten 5) auf steigende Flanke vom Stromwandler warten 6) Timer1 nullen 7) auf steigende Flanke vom Komparator warten 8) Timer1 abfragen 9) Korrekturwert berechnen Korrekturwert = sollzeit - istzeit 10) wenn Korrekturwert >=0 und Korrekturwert <=10000 ist dann bleibt korrektur wert gleich und in Korrektur gespeichert 11) wenn Korrekturwert <0 und Korrekturwert <= -10000 ist dann wird neue korrekturwert berechnet und in Korrektur gespeichert 12) auf steigende Flanke vom Taktgeber warten 13) Ventil ausschalten Ein Beispiel damit es klarer wird : Korrekturswert >0 { soll_winkel = 120° Ist_Winkel = 30° Korrekturswert = soll_winkel - Ist_winkel = 120°-30° = 90° > 0 nächste schritt er dekrementiert 90° und die 90°+30° ist 120°, deshalb sollte bei 120° treffen. } Korrekturswert <0 { soll_winkel = 30° Ist_Winkel = 120° Korrekturswert = soll_winkel - Ist_winkel = 30°-120° = -90° < 0 neue Korrektur Berechnung Korrektur = 360°+(-90°) = 270° nächste schritt er dekrementiert 270° und die 120°+270° ist 390°,was eigentlich 30° entspricht, deshalb sollte bei 30° treffen. }
Jar schrieb: > Karl heinz Buchegger schrieb: >> Deine Flankenerkennungen sind alle falsch rum >>>>>>>>>>> wieso sind sie falsch rum??? Weil zb das hier
1 | // steigende Flanke von dem Komparator warten
|
2 | while (!(PIND & (1 << PD1))) |
3 | {}
|
4 | while ((PIND & (1 << PD1))) |
5 | {}
|
nicht auf eine steigende Flanke wartet. Gehs in Gedanken durch. Angenommen PD1 sei 0 Das ist genau die Bedingung, damit die erste Schleife wiederholt und wiederholt und wiederholt. Die erte Schleife läuft also so lange, wie PD1 auf 0 ist. Die 2-te Schleife ist genau die Umkehrung. Sie wird so lange wiederholt, wie der Pin PD1 auf 1 ist. Verlassen wird sie erst wenn PD1 wieder auf 0 geht. Und jetzt mal in einem Zeitstrahl 1 +------------------+ PD1 | | | | 0 ------------------+ +------------- -------------------------------------------------------------> 111111111111111111122222222222222222222 Die 1 und die 2 markieren, welche Schleife gerade läuft, wenn das Signal den beschriebenen Zustand hat. Am Ende kommt man irgendwann aus der 2.ten Schleife raus. Tja, nur leider: Dazu muss das Signal an PD1 von 1 auf 0 wechseln. Und das ist nun mal eine fallende Flanke und keine steigende. Da du aber sowohl in deinen Beschreibungen als auch im Kommentar an dieser Stelle immer von einer steigenden Flanke sprichst, denke ich, dass in diesem Fall tatsächlich Beschreibung und Kommentar richtig sind und der Programmtext falsch. Dasselbe in grün, nur anders rum, für alle anderen Flankenerkennungen.
> 0) Sollwinkel lesen und zeitlich umrechnen > 1) auf fallende Flanke vom Taktgeber warten > 2) auf steigende Flanke vom Komperator warten > 3) korrektur dekrementieren bis 0 wird > 4) Ventil einschalten > 5) auf steigende Flanke vom Stromwandler warten > 6) Timer1 nullen > 7) auf steigende Flanke vom Komparator warten > 8) Timer1 abfragen > 9) Korrekturwert berechnen Korrekturwert = sollzeit - istzeit > 10) wenn Korrekturwert >=0 und Korrekturwert <=10000 ist dann bleibt > korrektur wert gleich und in Korrektur gespeichert > 11) wenn Korrekturwert <0 und Korrekturwert <= -10000 ist dann wird neue > korrekturwert berechnet und in Korrektur gespeichert > 12) auf steigende Flanke vom Taktgeber warten > 13) Ventil ausschalten Du hast wieder nur das hingeschrieben, wie deiner Meinung nach das Programm arbeiten soll. Das ist aber etwas anderes als Beschreiben was es in der Lösung zu tun gibt, wie die Aufgabenstellung überhaupt ist. zb dieser Punkt hier > 3) korrektur dekrementieren bis 0 wird Der ist unsinnig. Mach den korrektur Wert 0 und du hast das gleiche Ergebnis. Was du höchst wahrscheinlich willst: Eine bestimmte Zeitdauer x abwarten, wobei das x sich aus dem Inhalt der Variablen korrektur in Millisekunden (Mykrosekunden?, Nanosekunden?, Sekunden? Stunden? Tagen?) ergibt. Das ist aber etwas komplett anderes! Deines spricht von einer Operation, von der man nur sagen kann, dass sie am Ende in korrektur einen Wert von 0 hinterlässt. Meine Beschreibung legt aber das Augenmerk auf etwas ganz anderes! Da steht im Vordergrund, dass eine kleine Wartezeit eingelegt werden soll und es wird beschrieben, wie lange diese Pause sein soll. Wie hingegen diese Pause realisiert wird, schreibe ich in der Beschreibung der Aufgabenstellung nicht hin. Das interessiert an dieser Stelle (noch) überhaupt nicht. Ich konzentriere mich darauf, das das Programm eine Pause einlegen soll und ich konzentriere mich darauf, was es zu dieser Pause zu sagen gibt.
stimmt .... aber ich arbeite mit invertierten Logik mit Transistoren und vorwiderstände am Eingang des Microkontrollers. sorry ich hätte das sagen können.
Jar schrieb: > stimmt .... > > aber ich arbeite mit invertierten Logik mit Transistoren und > vorwiderstände > am Eingang des Microkontrollers. > > sorry ich hätte das sagen können. Ich würde sogar soweit gehen, zu sagen: Mal einmal ein Signaldiagramm und zwar so, wie die Signale an den µC Pins anliegen. Aus dem Diagram soll hervorgehen: welche Signale hast du welches sind die kritischen Zeitpunkte welche Zeiten musst du messen wie soll das davon abhängige Ausgangssignal aussehen. Deine Beschreibungen und der Programmtext sind so konfus, dass das anscheinend bisher noch niemand davon ableiten konnte. Das ist letzten Endes ja die Aufgabenstellung: Ein Signal zu generieren, in Abhängigkeit von anderen Signalen. Ev. muss man auch 2 oder mehr Diagramme malen, weil es verschiedene Fälle gibt. Aber diese Diagramme, und nur diese Diagramme, sind es letztlich, die die Aufgabenstellung präzise beschreiben. Wohlgemerkt: Aufgabenstellung! Das hat noch nichts damit zu tun, wie man diese Aufgabenstellung lösen kann. Ansonsten sehe ich swarz, das dir hier irgendjemand weiter helfen kann. Und nur damit hier kein Misverständnis auftaucht. Dein Programm, so wie es jetzt ist, kannst du höchst wahrscheinlich in die Tonne klopfen.
Und wieder einmal qualifiziert sich K.H. für den Baldrian-Award. ;-)
ich werde versuchen so gut wie möglich die aufgabe zu beschreiben : Eingangsignale für Mikcrokontroller : ---- Der Soll-Winkel wird durch 3 Hex Schalter ermittlet.Der einstellbare Winkelbereich beträgt zwischen 0° ...360°.Die Werteingabe wird durch Codierschalter gegeben. ---- taktgeber : SPS signal liefert Einschaltzeitdauer und ausschaltzeitdauer. meistens 2s Einschalt 2s Ausschalt. ---- Komparator : Aus dem Sinusverlauf der Prüfspannung (50Hz;20ms)wird ein Rechtecksignal von gleichen Frequenz genereriert. Dies wird als Referenzgröße für den Einschaltzeitpunkt. ---- Einschalzeitpunkt : Der Zeitpunkt des Einschaltens bestimmt den Ist-Phasenwinkel, welcher als Regelgröße mit Soll-Phasenwinkel verglichen wird. Dafür gibt ein Stromwandler. Für Bitmap_4 : 1) Es wird auf das Startsignal von dem Taktgeber gewartet. 2) Nulldurchgang :Es wird auf den nächsten Nulldurchgang der prüfspannung von negativer zu positiver Halbwelle gewartet. Mit der Signalflanke des Nulldurchgangs wird das Startsignal an das Magnetventil gegeben(3) 4) Stromdetektorsignal : Das Stromdetektorsignal kennzeichnet den Einschaltzeitpunkt. Mit der Signalflanke des Stromdetektorsignals wird der Zählerstand von Timer1 auf "0" gestezt. Der Timer wird im 500KHz Takt erhöht. Dadruch kann die Zeit bis zum nächsten Nulldurchgang auf 0,002ms genau gemessen werden. 5) Nulldurchgang : Mit dem nächsten nulldurchgang von negativer zu positiver Halbwelle wird der Zählerstand von Timer1 abgefragt. zu diesem Wert wird im nächsten Schritt ein Wert hinzuaddiert, der Sollwinkel entspricht (6) Der so ermittelte Wert dient im nächsten Zyklus als Korrekturzeitwert. Er wird in einem Register abgelegt. Für Bitmap_5 : ab nächste Schleife wird das Prorgramm so laufen : 1) Es wird auf das Startsignal von dem Taktgeber gewartet. 2) Nulldurchgang :Es wird auf den nächsten Nulldurchgang der prüfspannung von negativer zu positiver Halbwelle gewartet. Mit dem Nulldurchgang wird der im vorherigen Zyklus ermittelte Korrekturwert dekrementiert. bei jedem Durchlauf der Zählschleife wird um ein Inkremend verringert. Ist der Wert "0" erreich, wird das Startsignal an das Magnetventil gegeben (4)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.