Forum: Mikrocontroller und Digitale Elektronik Torzeit mit Attiny2313


von Paul Baumann (Gast)


Lesenswert?

Ich möchte mir einen Frequenzzähler mit einem ATTINY2313 bauen und habe
jetzt das Problem, eine genaue Sekunde als Meßzeit zu erzeugen. Da ich
aber den Timer 0 als Counter brauche, kann ich mit ihm nicht die
Meßzeit erzeugen.
Der Timer 1 ist zu „klein“ dafür. (4 Mhz  Quarz).
Sieht jemand eine andere Möglichkeit, die 1 Sekunde bzw. 100
Mikrosekunden genau zu erzeugen, denn Wait 1 in Bascom ist ungenau.

Gedacht ist es so:
(nur Pseudocode)
-Timer 0 als Counter einstellen
do
-Timer-Interrupt erlauben
-1 Sekunde warten
-Interrupt verbieten
loop

Dann müßte ja im Timerregister die Anzahl der gezählten Impulse pro
Sekunde enthalten sein und die kann ich ja dann ohne Mühe auf LCD
ausgeben.
Ich habe schon den Frequenzzähler von Bernhard „auseinandergenommen“,
komme aber mit Assembler nicht zurecht.


MfG Paul

von johnny.m (Gast)


Lesenswert?

> Der Timer 1 ist zu „klein“ dafür...
Zu klein? Der hat 16 Bit, Timer 0 hat nur 8...

Weißt Du denn, in welchem Bereich die zu messenden Frequenzen liegen?
Wenn der Bereich größer ist, dann musst Du sowieso Zählerüberläufe mit
in die Überlegungen einbeziehen.

von Rolf Magnus (Gast)


Lesenswert?

Der Prescaler des Timers kann bis auf 1024 eingestellt werden. Bei 4 Mhz
und maximalem Prescaler kann der Zähler maximal ca 16,77 Sekunden lang
laufen, bis er überläuft. Wenn du den Prescaler auf 256 einstellst und
den Timer im CTC-Modus bis 15625 zählen läßt, bekommst du einen
Interrupt, der genau einmal pro Sekunde ausgelöst wird.

von johnny.m (Gast)


Lesenswert?

Das war auch meine Idee. Aber da er ja keine Angaben über den
Frequenzbereich macht, ist es ein bisschen schwierig, was konkretes zu
sagen.

Mit Timer 1 im CTC-Modus wie von Rolf beschrieben und Timer 0 als
Periodenzähler sollte es im Prinzip gehen. Bei höheren Frequenzen als
255 Hz müssen dann die Überläufe von Timer 0 mitgezählt werden, was
über den entsprechenden Interrupt aber auch kein Thema sein sollte.

von Peter D. (peda)


Lesenswert?

Die MCs haben es sehr gerne, wenn sie auch mal etwas rechnen dürfen.

Es spielt also überhaupt keine Rolle, ob die Torzeit nun 1s oder 789ms
lang ist, man kann immer den Zählwert in Hz umrechnen.


Selbst in float rechnet der AVR immer noch 1000-mal schneller, als bei
Dir ein Lidschlag dauert.


Peter

von Rolf Magnus (Gast)


Lesenswert?

> Selbst in float rechnet der AVR immer noch 1000-mal schneller, als
> bei Dir ein Lidschlag dauert.

Sofern für die float-Bibliotheken noch genug Platz im Speicher ist,
denn sonst rechnet er nähmlich gar nicht. Der Tiny2313 ist ja nicht
gerade üppig mit Flash bestückt.

von Peter D. (peda)


Lesenswert?

@Rolf

Stimmt.

Float ist zumindest beim WINAVR sehr groß, da sollte es schon ein
ATMega48 sein.


Peter

von Paul Baumann (Gast)


Lesenswert?

Ich habe Timer 0 und 1 aus Versehen im Text vertauscht.
Außerdem wollte ich es so machen, daß ich bis 5Khz direkt zählen kann
und dann über einen Portpin einen 10:1 Teiler (7490) einschalte, der
dann wiederum bei f > 5Khz dem Prozessor wieder nur max. 5 Khz
aufbürdet.
Wenn ich Euch richtig verstanden habe, schlagt ihr vor, Timer 1 als
Counter zu nehmen und Timer 0 als Geber für die Torzeit.
Bloß- wie muß ich dann die beiden Timerinterrupts verknoten, damit
nicht einer den anderen beeinflußt?
Soviel ich weiß, gibt ein Interrupt im Interrupt "Mecker vom
Meister"!

:-)

MfG Paul

von Paul Baumann (Gast)


Lesenswert?

@Rolf
Ach so, das weiß ich, wie ich eine Sekunde erzeugen kann. (Hab ich in
meiner Uhr genau so gemacht, wie Du beschreibst).

Aber das Problem ist doch jetzt, daß der Timer durch die
Sekundentakterzeugung belegt wäre. Ich brauche ihn aber als Counter,
damit er die Impulse am Eingang zählt.
Was ich brauche ist jetzt irgend etwas Anderes, was mir statt des
Timers die Torzeit erzeugt.
Wenn der Prozessor 2 16-Bit Timer hätte, dann könnte ich einen nehmen,
der zählt und einen, der die Zählzeit des ersten festlegt.

MfG Paul

von Karl heinz B. (kbucheg)


Lesenswert?

Du kannst auch mit einem 8 Bit Timer eine beliebig
lange Torzeit erzeugen. Selbst wenn du eine Stunde
als Torzeit haben möchtest, ist das möglich.

Prinzip: Du weist (oder hast dir ausgerechnet), dass
von einem Timer-Overflow zum nächsten sagen wir mal 120 ms
vergehen. Du möchtest eine Torzeit von, zum Beispiel, 4.2 Sekunden.
D.h. du zählst in der Overflow-Routine mit (Variable hochzählen),
wie oft der Interrupt bereits aufgetreten ist. Wenn vom Beginn
der Torzeit an gerechnet, der Overflow Interrupt das 35-te mal
auftritt, sind 4,2 Sekunden vergangen (4200 / 120 = 35)

von Paul Baumann (Gast)


Angehängte Dateien:

Lesenswert?

@Karl-Heinz
Das ist die Idee, die ich suchte. Ich werde mal mein Programm auf den
"kleinen" Timer umbauen und mir so die Torzeit erzeugen.
Mir fehlt jetzt nur der Zusammenhang, wie ich den "großen" Timer
durch den kleinen starte und stoppe.Ich melde mich danach wieder.

Ich habe mal mein Programm angehangen. Ich habe es für den Atmega8515
umgeschrieben, weil der gerade auf dem Testbord am LCD hängt.Im Moment
versuche ich darin nur, die Torzeit mittels leerer Schleife empirisch
zu erzielen.

Noch eine andere Sache: Welcher Pin ist beim 8515 der Countereingang?
Jedes Datenblatt sagt etwas Anderes?!

MfG Paul

von AVRNIX (Gast)


Lesenswert?

abo

von Bjoern B. (tishima)


Lesenswert?

Hallo!

So erzeuge ich  ne Torzeit in C fuer ne Frequenzmessung

void capture(unsigned int compare)
{
  TCNT1H=0;      // clear timer
  TCNT1L=0;
  OCR1H=(compare >> 8);
  OCR1L=compare;

TIFR |= (1<<OCF1A);  // clear overflov/compare flags

TCCR1B=0x03;            // write Prescaler

  loop_until_bit_is_set(TIFR, OCF1A);
  TIFR |= (1<<OCF1A);      // clear overflov/compare flags
  TCCR1B=0;    // stop timer
}

Das Programm AVRCalc (Google) hilft einem, den Prescaler zu bestimmen
und den compare Wert.

mfg,
Bjoerm

von Steffen S. (strangeperson)


Lesenswert?

$regfile = "2313def.dat"
$crystal = 10000000

Config Timer1 = Counter , Edge = Falling , Prescale = 1

Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 ,
Db7 = Portb.7 , E = Portb.2 , Rs = Portb.0

Config Lcd = 16 * 1
Initlcd

Cursor Off

Dim Timercounter As Word
Dim Overflcounter As Word
Dim Totalcounter As Long
Dim T1 As Integer
Dim T2 As Integer
Dim M As Integer
Dim Zeit As Long

On Counter1 Uphigh

Timercounter = 0
Totalcounter = 0
Zeit = 0

Enable Interrupts
Enable Counter1

Cls
Lcd " Frequen"
Lowerline
Lcd "zz" ; Chr(225) ; "hler "
Waitms 500

Do
  Waitms 47.6
  If Zeit = 21 Then
  Cls
  Timercounter = Counter1
  Totalcounter = Overflcounter
  Shift Totalcounter , Left , 16
  Totalcounter = Totalcounter + Timercounter
  Lcd Totalcounter
  Lowerline
  Lcd " Hz"
  Timercounter = 0
  Totalcounter = 0
  Zeit = 0
  Counter1 = 0
  Overflcounter = 0
  End If
  Zeit = Zeit + 1
Loop

Uphigh:
  Incr Overflcounter
Return


Das Ding steht bei mir auf dem Schreibtisch und läuft ganz gut. Hier
wird ein Hardwarezähler verwendet und wenn der Zähler voll ist dann
wird ein Overflowcounter ausgelöst und zählt die Überläufe.
Über die Zeit "Waitms 47.6" kannst du Quarzungenauigkeiten
ausbessern.

hf

Achja, 16 * 1 Display entspricht 2 mal 8 Zeichen aber in einer Zeile...
;-) Kann ich auch nix für....

von Paul Baumann (Gast)


Lesenswert?

Danke erst mal an alle "Mitwirkenden".

Wenn man erst mal einen "Schubs" in die richtige Richtung bekommen
hat...

Jetzt habe ich es so gemacht, wie Karl-Heinz und Steffen vorschlugen.
Ich habe die Sache komplizierter angesehen, als sie war. Jetzt werde
ich bloß noch eine Auswertung der Zählfrequenz einbauen, um davon
abhängig einen Vorteiler einzuschalten bzw. zu "überbrücken".

MfG Paul

von Paul Baumann (Gast)


Lesenswert?

@Steffen So

Wozu dienen die Variablen T1, T2 und M? Offenbar sind sie nicht
benutzt. Welcher Pin ist der Zählereingang? (Müßte eigentlich PD6 sein,
ist aber nicht definiert) Dafür müßte es oben wahrscheinlich CAPTURE
EDGE heißen. Bis zu welcher Frequenz zählt die Schaltung? Ich nehme an,
bis zur halben Taktfrequenz. (5 Mhz)

MfG Paul

von Steffen S. (strangeperson)


Lesenswert?

T1, T2 und M waren mal für irgendwelche Teiler vorgesehen, sind aber
nicht benutzt.

Zum Eingang: Du musst im Datenblatt mal gucken, auf welchem Pin Timer 1
liegt. Soweit ich weiß muss der dann auch nicht definiert werden.

Die Frequenz habe ich nie voll ausprobiert, mein Frequenzgenerator
liefert nur Frequenzen im kHz Bereich... Aber denke mal mit 5 MHz kommt
das ganz gut hin, vll sogar mehr, da hier ja der Hardwarezähler
verwendet wird.

von Läubi (Gast)


Lesenswert?

Der Hardwarezähler muß aber auch das ganze sampeln :)

Zitat DB:
Each half period of the external clock applied must be longer than one
system clock
cycle to ensure correct sampling. The external clock must be guaranteed
to have less
than half the system clock frequency (fExtClk < fclk_I/O/2) given a
50/50% duty cycle. Since
the edge detector uses sampling, the maximum frequency of an external
clock it can
detect is half the sampling frequency (Nyquist sampling theorem).
However, due to variation
of the system clock frequency and duty cycle caused by Oscillator
source (crystal,
resonator, and capacitors) tolerances, it is recommended that maximum
frequency of an
external clock source is less than fclk_I/O/2.5.
[zitat ende]

Also im besten Falle CPUCLK/2 und am besten CPU/2.5 oder geringer um
sicher messen zu können :)

von Paul Baumann (Gast)


Lesenswert?

@Steffen
Das wäre dann PD5. ....wolln mal sehen.





@Läubi
Mit den wenigen Englischkenntnissen, die ein alter Mann so hat,
lese ich da heraus, daß die Eingangsfrequenz auch noch 50/50 Puls/Pause
sein muß?! Da müsste ich ja noch ein extra Flipflop
davor setzen, was mir dann allerdings die doppelte Zählfrequenz
beschert. Sehe ich das richtig?

Könnte man auch irgendwie den Analogeingang des Prozessors so
"verbiegen", daß man den als Zählereingang benutzt? Dann könnte
ich auch "Sinüsse" und "Dreiecke" messen, ohne das Signal
vorzubehandeln.

MfG Paul

von Läubi (Gast)


Lesenswert?

Ne muß nicht, aber wenn 50/50 da ist, dann kann der AVR es schaffen die
Halbe Frequenz mitzuzählen.

Im Prinzip läufts so ab, bei jedem CLK "prüft" der AVR nach ob sich
was an T0 (respektive T1) verändert hat, und zählt dann hoch.
Alles auserhalb dieser Zeit wird ignoriert.
Deshalb wenn das Signal zu schnell ist "übersieht" der AVR
Taktflankenwechsel.

Analogeingagn wird aber noch langsamer sein ;)

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.