Forum: Compiler & IDEs Timer1 abfragen und dekrementieren


von jar (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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

von Hc Z. (mizch)


Lesenswert?

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?

von jar (Gast)


Lesenswert?

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--)
{}
}
}

von Karl H. (kbuchegg)


Lesenswert?

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
}

von Karl H. (kbuchegg)


Lesenswert?

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?

von jar (Gast)


Lesenswert?

Stimmt er macht nix
ist ein teil von einem Programm
ich werde erstmal ein Flußdiagramm zeichnen und mein code hier rein 
machen.
Danke

von Jar (Gast)


Angehängte Dateien:

Lesenswert?

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 :)

von Stefan B. (stefan) Benutzerseite


Angehängte Dateien:

Lesenswert?

Jar, was soll ich machen?

von Jar (Gast)


Lesenswert?

nur wenn ich wüsste :)
soory ich hab das Bild ja nur als PNG hochgeladen was ja von mir 
verlangt wurde ...

von Karl H. (kbuchegg)


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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?).

von Jar (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Jar (Gast)


Lesenswert?

----> 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.

von Jar (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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) ...

von Jar (Gast)


Lesenswert?

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.
}

von Karl H. (kbuchegg)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

> 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.

von Jar (Gast)


Lesenswert?

stimmt ....

aber ich arbeite mit invertierten Logik mit Transistoren und 
vorwiderstände
am Eingang des Microkontrollers.

sorry ich hätte das sagen können.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Grrrr (Gast)


Lesenswert?

Und wieder einmal qualifiziert sich K.H. für den Baldrian-Award. ;-)

von Jar (Gast)


Angehängte Dateien:

Lesenswert?

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
Noch kein Account? Hier anmelden.