Forum: Mikrocontroller und Digitale Elektronik Ereigniszähler mit Atmega88: wie Zählereingänge beschalten (speziell Counter2)?


von Christian (Gast)


Lesenswert?

Hallo,
ich bin blutiger Anfänger was den Einsatz von Mikrocontrollern angeht 
und versuche mich gerade an meinem zweiten kleinen Projekt damit.
Ich möchte von zwei unabhängigen Sensoren (Pulszähler für radioaktiven 
Zerfall) die Pulse zählen. Die Pulse haben 5V-Pegel und können ca 350ns 
bis 20µs Pulsbreite aufweisen. Zum Zählen möchte ich die internen 
Counter des Atmega88 einsetzen. Ich habe jedoch Probleme beim 
Verständnis, wie diese Zähler von außen beschaltet werden müssen:

Für die Zähler TC0 und TC1 finde ich im Datenblatt die Eingänge T0 und 
T1. Ist meine Annahme richtig, dass es sich dabei um flankengesteuerte 
Takteingänge handelt, über die meine Ereignisse registriert werden 
können?

Für TC 2 (asynchroner 8 Bit Zähler) findet sich ein entsprechender 
Eingang aber nicht!
Da ich den 16 Bit TC1 für das präzise Programmtiming verwenden möchte, 
hatte ich ursprünglich vor, TC0 und TC2 als Zählereingänge zu verwenden. 
Wie muss ich dann mein Sensorsignal als Takt für den TC2 beschalten?

Nach lesen des "AVR-GCC-Tutorial/Die Timer und Zähler des AVR" hier im 
Forum sind mir folgende vage Ideen gekommen:
1. Kann es sein, dass die Pins XTAL1/TOSC1 bzw. XTAL2/TOSC2 eine Rolle 
spielen und dafür verwendet werden? Wenn ja: wie?
2. Wenn ich wie im Tutorial vorgeschlagen den TC2 in Kombination mit 
einem 32,768KHz-Quarz zur Programmsteuerung verwende (ich brauche einen 
1s-Programmablauftakt), wäre TC1 wieder als Ereigniszähler verfügbar.

Ratschläge, Ideen oder am Liebsten leicht verständliche Erklärungen zu 
meinem Problem wären mir eine große Hilfe.
Habt alle vielen Dank + Gruß
Christian

von S. Landolt (Gast)


Lesenswert?

> ... flankengesteuerte Takteingänge ...
So ist es, wobei die Flanke gewählt werden kann.

> .. 1s-Programmablauftakt ...
Ein Quarz im MHz-Bereich und Timer2 im Synchronbetrieb entsprechend 
programmieren.

Das mit dem 32 KiHz-Quarz (asynchron) macht man meist nur, wenn der uC 
für einen Großteil der Zeit schlafen soll, also um Strom zu sparen.

von Peter D. (peda)


Lesenswert?

Christian schrieb:
> Für TC 2 (asynchroner 8 Bit Zähler) findet sich ein entsprechender
> Eingang aber nicht!

In der Tabelle "Clock Select Bit Description" findet man auch keinen 
Eintrag für externe Taktung.
Sprich, es geht nicht.

Christian schrieb:
> Da ich den 16 Bit TC1 für das präzise Programmtiming verwenden möchte

Man kann auch 8Bit-Timer erweitern:

Beitrag "AVR Timer mit 32 Bit"

von Christian (Gast)


Lesenswert?

Peter D. schrieb:
> Christian schrieb:
>> Für TC 2 (asynchroner 8 Bit Zähler) findet sich ein entsprechender
>> Eingang aber nicht!
>
> In der Tabelle "Clock Select Bit Description" findet man auch keinen
> Eintrag für externe Taktung.
> Sprich, es geht nicht.

TC2 kann also tatsächlich keine externen Ereignisse zählen? Das ist ja 
blöd. :(

S. Landolt schrieb:
>> .. 1s-Programmablauftakt ...
> Ein Quarz im MHz-Bereich und Timer2 im Synchronbetrieb entsprechend
> programmieren.
>
> Das mit dem 32 KiHz-Quarz (asynchron) macht man meist nur, wenn der uC
> für einen Großteil der Zeit schlafen soll, also um Strom zu sparen.

Ich brauche halt einen Interrupt im Sekundentakt (bei meinen ebenfalls 
noch sehr spärlichen Programmierkenntnissen). Zwischendurch soll das 
Programm tatsächlich nicht viel machen. Nur die Zähler müssen laufen. 
Weshalb dann einen MHZ-Quarz verwenden, wenn doch der Timer nur 8Bit 
hat?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Mit einem einfachen Getrieb im TOV2 Interrupt kannst du auch aus dem 
Timer 0 oder 2 eine präzise Uhr machen.
Hier mal ein Stückchen Code, bei dem der Timer 0 alle 1/50 Sekunde die 
ISR auslöst:
1
// clock gearbox is called every 1/50 of a second
2
// Note that it is really the CTC interrupt but the 8515 uses the COMP vector
3
// 6 byte clock : fifties:seconds:minutes:hours:days
4
// this clock will wrap around after 65535 days ~= 179 years 
5
// a simple clock gearbox
6
volatile uint8_t fifties = 0;
7
volatile uint8_t seconds = 0;
8
volatile uint8_t minutes = 0;
9
volatile uint8_t hours = 0;
10
volatile uint16_t days = 0;
11
12
ISR(TIMER0_COMP_vect) {
13
     fifties++;
14
     if (fifties > 49) {
15
  fifties = 0;
16
  seconds++;
17
  if (seconds > 59) {
18
    seconds = 0; 
19
    minutes++;
20
    if (minutes > 59) {
21
      minutes = 0;
22
      hours++;
23
      if (hours > 23) {
24
        hours = 0; 
25
        days++;
26
        }
27
      }
28
    }
29
  }
30
}

: Bearbeitet durch User
von Christian (Gast)


Lesenswert?

Christian schrieb:
> Ich brauche halt einen Interrupt im Sekundentakt (bei meinen ebenfalls
> noch sehr spärlichen Programmierkenntnissen). Zwischendurch soll das
> Programm tatsächlich nicht viel machen. Nur die Zähler müssen laufen.
> Weshalb dann einen MHZ-Quarz verwenden, wenn doch der Timer nur 8Bit
> hat?

Oder soll ich den 8Bit TC2, der von einem MHz-Quarz betaktet wird dann 
programmatisch erweitern, so wie Peter D. es vorschlägt?

Peter D. schrieb:
> Beitrag "AVR Timer mit 32 Bit"

Nur welchen Vorteil habe ich davon gegenüber der 32,768KHz-Quarz 
Variante, wo ich doch nur meinen sekündlichen Interrupt benötige?

von Christian (Gast)


Lesenswert?

Matthias S. schrieb:
> Hier mal ein Stückchen Code, bei dem der Timer 0 alle 1/50 Sekunde die
> ISR auslöst:

Ok, also wenn ich recht verstehe: Mittels Software aus dem 8Bit TC2 und 
einem schnellen Takt (MHZ-Quarz) einen Sekundentakt ableiten, wie in 
deinem Uhrenbeispiel.
Somit erhalte ich für meinen Programmablauf die nötige Genauigkeit. TC0 
und TC1 bleiben somit als Zähler für meine externen Ereignisse 
verfügbar, da TC2 das ja nicht kann.

Vielen Dank für alle bisherigen Antworten!

von c-hater (Gast)


Lesenswert?

Christian schrieb:

> Für die Zähler TC0 und TC1 finde ich im Datenblatt die Eingänge T0 und
> T1. Ist meine Annahme richtig, dass es sich dabei um flankengesteuerte
> Takteingänge handelt, über die meine Ereignisse registriert werden
> können?

Leider nicht ganz. Das gilt (als Näherung) nur, so lange die Impulse am 
Zählereingang hinreichend breit sind. Genaueres sagt, wie immer, das 
Datenblatt.

Die Sache ist nämlich, dass es nicht wirklich flankengetriggerte 
Eingänge sind, sondern tatsächlich das Signal daran nur gesampelt wird. 
Die zählwirksamen "Flanken" entstehen erst im Inneren des AVR.

> Für TC 2 (asynchroner 8 Bit Zähler) findet sich ein entsprechender
> Eingang aber nicht!

Tja, so ist das oft. Man muss die Hardware nehmen, wie sie der 
Hersteller designed hat...

> Da ich den 16 Bit TC1 für das präzise Programmtiming verwenden möchte,
> hatte ich ursprünglich vor, TC0 und TC2 als Zählereingänge zu verwenden.

Vollkommen irrationale Idee deinerseits, da ja TC2 de facto nicht 
existiert und schon der kleinste Blick auf die zweite Seite des DB 
diesen Sachverhalt gnadenlos enthüllt.
Ja, in meinen Träumen fahre ich auch meinen Lamborghini, das Problem ist 
halt: er existiert in der bösen Realität nicht. Also kann ich ihn nicht 
fahren. So einfach ist das. Abgleich Wunschtraum<->Realität. Das sollte 
man als Erwachsener aber wirklich beherrschen...

> Wie muss ich dann mein Sensorsignal als Takt für den TC2 beschalten?

Wenn du endlich akzeptiert hast, dass TC2 einfach nicht existiert, dann 
erübrigt sich diese Frage...

von S. Landolt (Gast)


Lesenswert?

Wenn es denn doch der 32 KiHz-Quarz sein soll, so findet sich hier 
Näheres zum asynchronen Betrieb des Timer2:
https://www.mikrocontroller.net/articles/Sleep_Mode
im Kapitel 'Quarzgenaue Zeitbasis'; da dort im Normalmodus mit TOIE2 
gearbeitet wird, erreicht man so nicht direkt 1 s, Letzteres wäre 
möglich im CTC-Modus mit OCIE2A.

von S. Landolt (Gast)


Angehängte Dateien:

Lesenswert?

Ein Minimalgrundgerüst mit 1 s.

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.