PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : präzises timing für 8mhz



robby-fant
22.08.2006, 21:31
Hallo, ich möchte ein präzises Timing für eine Steuerung haben in Bascom.

Und zwar: 12us, 6666us, 3333us und 833 us.

Wie kann ich so etwas in Bascom realisieren?

Hanni
22.08.2006, 23:04
Ich glaube es eher nicht.
Zeitkritische Dinge sind immer mit Takte abzählen verbunden und soetwas geht nunmal am besten in Assembler.

-tomas-
24.08.2006, 10:55
Ich sehe da in Bascom keine großen Probleme, da man nicht unbedingt Takte zählen muss.

Die 6666us, 3333us und 833 us lassen sich einfach mit dem Clear Timer on Compare Match (CTC) Mode realisieren.
Ersteinmal solltest Du Dich von den 8Mhz trennen. Man nehme einen 14.7456MHz-Quarz (Standardfrequenz für RS232) und
setze den 16-Bit Timer in den CTC-Mode mit dem prescaler factor =64.

Ensprechend dem Wert im Register OCR1A wird jetzt regelmäßig ein Interrupt ausgelöst:
OCRR1A= 191 -> 833,333 us
OCRR1A= 767 -> 3333,333 us
OCRR1A= 1535 -> 6666,6 us
Man kann das auch mit dem Port OC1A verknüpfen (toggle).

Die 12µs lassen sich mit dem 14.7456MHz-Quarz nicht exakt relisieren...

robby-fant
24.08.2006, 11:22
der Interrupt soll nur einmal ausgegeben werden.

wie starte ich den Interrupt, damit er einmal z.b. 833us startet und dann wieder ruht, bis zum nächsten starten.

-tomas-
24.08.2006, 12:35
Sag mal, was in/nach den 833µs passieren soll und wie genau Du die 833µs einhalten musst.
Das ist entscheidend für den Ansatz, 833µs in Atmega-Hardware oder Software zu realisieren. In Hardware lässt sich Taktgenau einfacher umsetzen... Z.B. einen Port für _exakt_ 833µs auf High zu setzen.

Welchen Atmega verwendest Du?

Hanni
24.08.2006, 19:03
Ich sehe da in Bascom keine großen Probleme, da man nicht unbedingt Takte zählen muss.

Die 6666us, 3333us und 833 us lassen sich einfach mit dem Clear Timer on Compare Match (CTC) Mode realisieren.
Ersteinmal solltest Du Dich von den 8Mhz trennen. Man nehme einen 14.7456MHz-Quarz (Standardfrequenz für RS232) und
setze den 16-Bit Timer in den CTC-Mode mit dem prescaler factor =64.

Ensprechend dem Wert im Register OCR1A wird jetzt regelmäßig ein Interrupt ausgelöst:
OCRR1A= 191 -> 833,333 us
OCRR1A= 767 -> 3333,333 us
OCRR1A= 1535 -> 3333,333 us
Man kann das auch mit dem Port OC1A verknüpfen (toggle).

Die 12µs lassen sich mit dem 14.7456MHz-Quarz nicht exakt relisieren...

DAher ist der Grundansatz mit den 14,7456MHz nicht das nonplusultra.

Praktisch kann er nämlich sehr wohl bei seinen 8 MHz bleiben.

In Takten (oder Zählschritten):
12µs = 96
833µs = 3332
3333µs = 26664
6666µs = 53328

Das sind alles Werte, die man mit dem Timer 1 ohne Prescaler erreichen kann.

Im übrigen, würde ich mir bei so einer Aufgabenstellung mal Gedanken über den kleinsten gemeinsamen Nenner dieser Zeiten machen.

Grüße,
da Hanni.

-tomas-
24.08.2006, 20:18
@Hanni
Du hast Recht, bei 8Mhz gibt es noch keinen Überlauf im Timer 1 :-)
-also geht CTC bei 8Mhz ohne prescaler

Mal sehen was robby-fant schalten will...

robby-fant
25.08.2006, 12:29
833us lang ein Ir-Signal von 36khz erzeugen
6666us lang ein Ir-Signal von 36khz erzeugen

3333us wartezeit
12us wartezeit

-tomas-
25.08.2006, 12:35
Na dann lass es uns gleich richtig machen - dazu ein paar Fragen:

1. Was ist der Auslöser oder ist es eine Endlosschleife?
2. Ist das die richtige Reihenfolge bzw. was sollen diese 12µs Wartezeit (=96Takte@8MHz) bedeuten bei einem 36Khz-Signal (=27µs Periode)?
3. Welchen Atmega verwendest Du?


Do
833us lang ein Ir-Signal von 36khz erzeugen
6666us lang ein Ir-Signal von 36khz erzeugen
3333us wartezeit
12us wartezeit
Loop

robby-fant
25.08.2006, 12:42
Ir_code_6666us

For I = 0 To 7
If Wert.7 = 0 Then
Wait 833us
Ir_code_833us
Else
Wait 3333us
Ir_code_833us
End If
Rotate Wert , Left , 1

Next

-tomas-
25.08.2006, 14:24
OK, Du kannst folgendes machen (am Beispiel Mega32):

Du benutzt den Timer1 zur Zeitmessung. Entweder im CTC-Mode (s.o.) mit Startwert 0 und Vergleich mit MAX oder im Overflow-Mode mit dem Startwert (2^16-MAX).

Du brauchst dafür keine ISR zu schreiben, da Du im CTC-Mode das Output Compare Flag (OCF1x) bzw. im Overflow-Mode das Timer/Counter Overflow Flag (TOV1) direkt abfragen kannst.

PseudoCode:

Initialisiere Timer1-Mode
Lade Timer-Register TCNT1x mit Startwert bzw. 0 (CTC)
nur CTC: Lade OCR1Ax mit Startwert
Lösche Compare bzw. Overflow-Flag
Starte Timer1
Do
36Khz-Signal ausgeben
Loop Until Compare/Overflow-Flag gesetzt
Stoppe Timer1
bzw. wenn Du das 36kHz-Signal mit Hardware oder einer ISR erzeugst:

'Vorspann s.o.
Starte Timer1
Starte TimerX-Output 36Khz-Signal ausgeben
Do
Loop Until Compare/Overflow-Flag gesetzt
Stoppe TimerX-Output 36Khz-Signal ausgeben
Stoppe Timer1
Dieses Initialisieren mit DO-LOOP machst Du dann jedesmal wenn Du eine genaue Zeitmessung brauchst.

Nur wofür sind die 12µs Wartezeit (=96Takte@8MHz)?

---------------------------------
Nachtrag zu Deiner anderen Frage:

Hallo, ich möchte am OC1A (PD5) 36000 Herz erzeugen für eine Ir-Diode.
Wie muss der Timer1 conf. werden und wie wird er auf Toggeln geschaltet und wieder gestoppt?
Nimm dafür ebenfalls den CTC-Mode (eines zweiten Timers). Dazu aus dem Mega32-Manual:

Clear Timer on Compare Match (CTC) Mode
For generating a waveform output in CTC mode, the OCx output can be set to toggle its logical level on each compare match by setting the Compare Output mode bits to toggle mode. The OCx value will not be visible on the port pin unless the data direction for the pin is set to output.

robby-fant
26.08.2006, 08:33
Die brauchte ich vorher in der For-Schleife um die 36khz zu erzeugen.