mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Genaue Sekunde mit 4,194304Mhz Quarz: kleine Probleme..


Autor: Draco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So nun hat es mich auch in diese doofe Situation verschlagen :/

Ich möchte eine Sekunde ziemlich genau messen damit ich Ah ausrechnen 
kann. Ich habe einen 4,194304 Mhz Quarz im Einsatz mit einem Teiler von 
256 komme ich genau auf 16384 Zyklen.

Jedoch weiß ich nun nicht welchen Timer bzw. Interrupt ich wo und vor 
allem wie ansprechen muß das ich diese genaue Sekunde erhalten. :/

In meinem Programm habe ich bereits einen Timer2 Overflow, für meinen 
Drehimpulsgeber laufen, welcher jedoch bei jedem Drehimpuls eine Pause 
von 50ms einlegen muß (läßt sich leider bei der Bitabfrage des doofen 
Impulsgebers nicht anders ändern :/) Kann ich denn dann einen zweitern 
Timer nebenbei laufen lassen?! Oder sollte ich mir da tunlichst was 
anderes einfallen lassen?!

Achja... µC ist ein Atmega32 und schreiben tue ich in MicroC - geht aber 
auch das normale AVR GCC...

Vielen Dank für eure Hilfe!

Autor: Stefan B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In erster Näherung kannst du IMHO den Timer2 Overflow mitbenutzen (20 * 
exakt 50ms = exakt 1s). Genauer könnte man was dazu sagen, wenn man 
wüsste, aus welchen Messungen und wie du die Kapazität (Ah) berechenen 
willst.

Autor: Ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo was ist mit Timer 0?
Ich würde nicht alle 256 Takte in die ISR hüpfen. Da diese ja selbst 
wenn du nur einen 8Bit Zähler hoch zählen willst etliche Takte benötigt 
und du so eine hohe Auslastung hast. (Gut bei einem Zähler geht's noch 
gerade so ;)

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Draco (Gast)

>So nun hat es mich auch in diese doofe Situation verschlagen :/

Ach du Aaaaaaarmer.

>Ich möchte eine Sekunde ziemlich genau messen damit ich Ah ausrechnen
>kann. Ich habe einen 4,194304 Mhz Quarz im Einsatz mit einem Teiler von
>256 komme ich genau auf 16384 Zyklen.

Und wo ist das Problem?

Siehe AVR - Die genaue Sekunde / RTC

>In meinem Programm habe ich bereits einen Timer2 Overflow, für meinen
>Drehimpulsgeber laufen, welcher jedoch bei jedem Drehimpuls eine Pause
>von 50ms einlegen muß (läßt sich leider bei der Bitabfrage des doofen
>Impulsgebers nicht anders ändern :/)

Unsinn. Im Interrupt wird NIE gewartet, schon gar nicht 50ms!!!
Siehe Interrupt.
Kann man alles anders programmieren, man muss nur wissen wie. Siehe auch 
Multitasking.

> Kann ich denn dann einen zweitern
>Timer nebenbei laufen lassen?! Oder sollte ich mir da tunlichst was
>anderes einfallen lassen?!

Ja, vergiss die Murksprogrammierung und lerne wie man es richtig macht.

MFG
Falk

Autor: avr (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die 4,194304 MHz sind 2^22 Hz, daher kommt auch der Wert.

Bei den Zählern gibt es daher die Möglichkeiten mit Overflow:

8 Bit-Zähler (2^8) mit Vorteiler 1024 (2^10) und eigener
Zähler bis 16 (2^4), d.h. ein Zeitfenster von 62,5 ms.

16 Bit-Zähler (2^16) mit Vorteiler 64 (2^6) ergibt direkt
1 Sekunde.

Wenn du statt deinen 50 ms mit den 62,5 ms leben kannst
wäre das der beste Weg.

AVR

Autor: Draco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na die 50ms kommen nur dann zustande wenn der Impulsgeber eine Drehung 
vollführt.:

void Timer2Overflow_ISR() org IVT_ADDR_TIMER2_OVF
{
     if (Button(&PINC, 2, 1, 1) && Button(&PINC, 4, 1, 0) && richtung == 0) {
                       richtung = 2;
                       delay_ms(50);

     } else if (Button(&PINC, 4, 1, 1) && Button(&PINC, 2, 1, 0) && richtung == 0) {
                       richtung = 1;
                       delay_ms(50);

     }
}


....
  SREG_I_bit = 1;
  TOIE2_bit  = 1;
  TCCR2      = 6;
....

Ich messe die aktuelle Spannung einer (Solarzelle + Batterie - 
Verbraucher) via ADC alle 10sec und möchte mir die Ergebnisse einfach 
aufaddieren. Mir reicht es ja wenn ich erst nach 2-3h das Ergebniss 
sehe, das funktioniert ja auch soweit ganz gut :D Jedoch komme ich mit 
dem Timer nicht so ganz auf die Sekunde, weil mir fehlt entweder immer 
was oder ich bin nach 2-3 Minuten schon 2sec im vorraus.

Autor: Zwölf Mal Acht (hacky)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Einen Delay im Timer Interrupt ? Aaaaaaaaaaaaaaaaaaahhhhhhhhhhhhhhhhh.

Autor: Herbert K. (avr-herbi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich meine, zu einer halbwegs genauen Zeit wirst Du erst kommen, wenn Du 
andersherum von Deiner Anforderung den Quarz berechnest.
Also was ich meine:
Bei 8 Bit Timer:
z.B. per Software z.B. (50 x Interrupt und per Software zählen)
x Hardware Teiler des Timers x Vorteiler => Quarz
Da der 16 Bit Timer von Dir schon verwendet wird, schlage ich Dir den 
Timer 2 dafür vor, da kannst Du mit Überlauf Interrupt arbeiten. Den hat 
Timer0 nicht. (Hab mich damit leider vor einigen Tagen selbst 
auseinandersetzten müssen und mich viel Zeit gekostet).
Wenn Du von einem Quarz ausgehst wie bisher, wirst Du vermutlich immer 
auf Teilerfaktoren kommen, die nicht ganzzahlig sind und dann wirds 
vermutlich ungenau.
Viele Grüße Herbert

Autor: Draco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja und?! Momentan wurde der Timer auch ausschließlich für die 
Drehgeberabfrage genutzt. Es funktioniert wunderbar, das Programm war 
nicht zeitkritisch - also warum nicht?! Ist nicht schön, ich weiß. Aber 
das Ergebniss ist das Ziel - nicht der Weg.

Das ich es nun umschreiben muß ist mir klar. Aber solche Postings 
bringen einen echt nicht weiter. Ich hab mir hierher gewandt weil ich 
ein Problem habe und ein Meister noch nie vom Himmel gefallen ist - auch 
ihr habt mal angefangen und Fehler begangen. Jemanden deswegen "dumm" zu 
machen sehe ich als falschen Ansatz in einem Forum wie diesem.


Vielen Dank erstmal für die Hinweise, auch an Falk für die nützlichen 
Links. Werde mich da mal reinlesen.

Autor: Draco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mensch.. so schnelle Antworten hier :D

Herbert K. schrieb:
> Hallo,
>
> ich meine, zu einer halbwegs genauen Zeit wirst Du erst kommen, wenn Du
> andersherum von Deiner Anforderung den Quarz berechnest.
> Also was ich meine:
> Bei 8 Bit Timer:
> z.B. per Software z.B. (50 x Interrupt und per Software zählen)
> x Hardware Teiler des Timers x Vorteiler => Quarz
> Da der 16 Bit Timer von Dir schon verwendet wird, schlage ich Dir den
> Timer 2 dafür vor, da kannst Du mit Überlauf Interrupt arbeiten. Den hat
> Timer0 nicht. (Hab mich damit leider vor einigen Tagen selbst
> auseinandersetzten müssen und mich viel Zeit gekostet).
> Wenn Du von einem Quarz ausgehst wie bisher, wirst Du vermutlich immer
> auf Teilerfaktoren kommen, die nicht ganzzahlig sind und dann wirds
> vermutlich ungenau.
> Viele Grüße Herbert

So wie ich mich gerade belesen habe im Datenblatt, ist der Timer2 einer 
der 8Bit Timer, also steht mir ja der 16Bit Timer (TCCR1) noch zur 
Verfügung. Dort passt mein Teiler ja wieder.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Timer 2 dafür vor, da kannst Du mit Überlauf Interrupt arbeiten. Den hat
>Timer0 nicht. (Hab mich damit leider vor einigen Tagen selbst
>auseinandersetzten müssen und mich viel Zeit gekostet).

Alle Timer des ATMega32 haben einen Overflow-Interrupt.

MfG Spess

Autor: Herbert K. (avr-herbi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
bitte um Entschuldigung - war noch ein wenig früh. ATmega32 hatte ich 
übersehen. Ich war vom ATmega8 ausgegangen.

Aber ein Delay gehört eigentlich nicht in die ISR sondern das macht mann 
außerhalb der ISR - oder?

Nach dem ich anfangs ähnliche Probleme hatte, habe ich mein Prg. 
geändert, so das in der ISR nur Zustände abgefragt / festgehalten werden 
und evt. Counter +1.

Die Regelung / Steuerung mache ich dann außerhalb der ISR im normalen 
Programm, in dem die vorherigen Zustände einfach in einer Schleife 
abgefragt werden und da stört dann auch ein Delay nicht unbedingt. Seit 
dem läuft meine Uhr auch genauer.

Viele Grüße Herbert

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>bitte um Entschuldigung - war noch ein wenig früh. ATmega32 hatte ich
>übersehen. Ich war vom ATmega8 ausgegangen.

Auch alle Timer des ATMega8 haben einen Overflow-Interrupt.

MfG Spess

Autor: Herbert K. (avr-herbi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Spess hat mich wieder mal auf einen Fehler hingewiesen:
Ich meinte "Timer/Counter xx Compare Match" als ISR.
Danke Spess.
Viele Grüße Herbert

Autor: Ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber wenn du in deinem einem Interrupt 50ms wartest. Verpasst du aber 
vielleicht den einen oder anderen Interrupt, da während eines Interrupt 
alle anderen gesperrt sind.

Wen ein anderer Interrupt z.B alle 10ms kommt verpasst du ca. 4 mal den 
anderen. So kommst du nie auf eine genaue Sekunde.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist egal, ob der Weg das Ziel ist oder nicht, denn Warteschleifen in 
Interrupts sind No-Gos. Sowas macht man nicht. Und wie du siehst hast du 
deswegen auch Probleme.
Entprellung löst man anders als über Warteschleifen.

Autor: Draco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gut gut, um nun mal ein wenig ruhe in den thread zu bringen hab ich die 
Tastenabfrage angepasst.:
 void Timer2Overflow_ISR() org IVT_ADDR_TIMER2_OVF
{
     if (Button(&PINC, 2, 0, 1) && Button(&PINC, 4, 0, 0) && richtung == 0 && zaehler >=29) {
                              richtung = 2;
                              zaehler = 0;

     } else if (Button(&PINC, 4, 0, 1) && Button(&PINC, 2, 0, 0) && richtung == 0 && zaehler >=29) {
                              richtung = 1;
                              zaehler = 0;
     }
     
     zaehler++;
}

Hab nun den 16Bit Timer mit 64iger Teilung genommen für meine sekunde, 
die Uhr läuft nun seit ca. 8h ohne eine sekunde abweichung, will sie 
dann morgen mal einen ganzen Tag neben einer Stopuhr laufen lassen.

Danke für eure Hilfe!

Autor: Herbert K. (avr-herbi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
schön das wir Dir helfen konnten.

Ich freue mich auch, das Du für andere die Änderung / Lösung 
hinterlassen hast.

Viel Erfolg bei den weiteren Arbeiten am Projekt.
Viele Grüße Herbert

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.