Timer Berechnungsfrage

andy999mueller

Neues Mitglied
02. Feb. 2008
6
0
0
Sprachen
Hallo,

ich kapiere es immer noch nicht so ganz mit der Berechnung der Timers:

Und zwar würde ich gerne ein Signal erzeugen, dass 400µs lang ist.
Ich habe einen ATMega128 mit 16Mhz. Wie müsste nun die Berechnung für mein Compare-Wert aussehen, abhängig von meinem Prescaler?

Wäre echt super wenn ihr mir Hilfe bei der Berechnung geben könntet



Gruß Andy
 
Hallo Andy,

unter

http://www.roboternetz.de/phpBB2/dload.php?action=file&file_id=169

findest Du ein praktisches Tool zum Berechnen der Timer beim AVR.

Damit Du aber nachvollziehen kannst was das Programm wirklich rechnet solltests Du auf jeden Fall das Datenblatt zum ATmega128 mit den Beschreibungen für die Timer wenigstens grob verinnerlicht haben. Darum kommst Du in der Regel nicht herum.

Kleiner Tipp als Einstieg zum nachdenken:
- Deine 16MHz CPU macht einen Takt in 62,5 nsec
- Die Timer clock source ist via default die gleiche clock wie die CPU also 16MHz.
- Der Prescaler ist eine Art Vorteiler mit dem Du Dein Taktverhältnis "verkleinern" kannst
- Bei Prescaler = 1 bist Du bei 16Mhz und bei Prescaler = 8 bist Du bei 2 Mhz, bedeutet Dein Timer würde alle 500 nsec einen Tick machen, richtig?
- Beim ATmega128 hast Du Prescaler mit 1, 8, 32, 64, 128, 256 und 1024
- Mit 32 bist Du bei ca. 2 µs und mit 64 bist Du bei ca. 4 µs oder?
- Du kannst natürlich auch einen 16-Bit-Timer quälen, hast ja beim ATmega128 genug und in mit Prescaler 1 laufen lassen. Dann kann er wenisgtens mit einem Timerwert von 59136 so richtig loslegen :D

So, höher als 64 würde ich mit dem Prescaler nicht mehr gehen. Nun ist es erst mal egal ob Du einen 8-bit oder 16-bit Timer verwendest denn sowohl mit 2µ als auch mit 4µ läßt sich der 8-Bit-Timer sauber aufziehen denn sowohl 200 (56) als auch 100 (156) passen schön rein.
Dann noch die passende ISR dazu und schon kanns los gehen :)

Wenn Dir das jetzt zu schnell war dann gehs nochmal langsam durch und schau Dir dazu das Datenblatt an. Ich glaube mit dieser Hilfestellung kommst Du auch alleine weiter. Falls nicht so kannst Du mit obigem Programm Dir direkt auch BASCOM-Code erzeugen lassen.

Grüße,
Markus
 
es geht halt darum, dass ich gerne einen Servo ansteuern würde, ist es dann sinnvoll mit PWM zu arbeiten oder ist das egal?
 
Hallo Andy,

sorry, bei Servos muss ich passen. Mit denen habe ich mich noch überhaupt nicht beschäftigt und daher kann ich Dir nicht viel dazu sagen.

Aktuell arbeite ich aber serh sehr gern mit BASCOM_AVR und dort gibt es eine Routine die Dir schon fix & fertig einen Servo konfiguriert. Das ganze funktioniert über Timer0 und Du musst der Routine nur noch sagen an welchem PIN der Servo hängt, wie viele Servos Du bedienen möchtest und Du must die reload value für die ISR angeben. Ein kleines Beispiel programm ist in der Direkthilfe und im BASCOM-AVR Manual enthalten.

Ich weiß nich tin was Du programmierst aber vielleicht könnte das eine Alternative sein.

Ansonsten lassen wir die Frage hier weiter offen und schauen ob Dir jemand speziell mit Servos weiterhelfen kann.

Kurze Frage; in welcher Sprache programmierst Du Deinen ATmega128 und auf welcher Entwicklungsumgebung arbeitest Du?

Grüße,
Markus
 
Hallo Andy,

bezüglich "Servo ansteuern", siehe dir einmal dieses Programm von Achim Walther an:

Servo mit Tasten steuern

Das Programm ist in Assembler geschrieben, ich weiß nicht, ob dir das weiter hilft, allerdings ist es schön klein und dokumentiert. Auf der Seite von Achim Walther ist auch gut erklärt, wie man sich an das Thema "Servo" Schritt für Schritt herantastet.

Ich hoffe, ich konnte die ein bisschen weiter helfen.

Gruß
Dirk
 
schrittmotorsteuern

Hallo
ich muss 2 schrittmotor steuern in C mit dem AVR Studio 4..meine CPU ist 18 Mhz.Ich weiss nicht,welcher Vorteiler soll ich benutzen.Ich denke, mein Freguenz soll 1 kHz sein ,wie kann ich Timer einstellen.
Kann jemand mir helfen?
 
Hallo,

es kommt darauf an, welche Vorteiler der AVR unterstützt. Mit 18MHz erreichst du weder mit einem 8Bit-Timer noch mit einem 16Bit-Timer exakt eine Event-Time von 1ms, das wird aber in deinem Fall nicht so schlimm sein.

Siehe dir am besten einmal das kleine Tool AVR-Timer-Calculator an, das kannst du hier downloaden. Als Frequenz gibst du 18000000Hz an und als Interrupt-Time 1000us an. Das Programm errechnet dann den Reloadwert, bzw den Comparewert des Timers, je nachdem welchen Interrupt du nutzen möchtest.

Grüße,
Dirk
 
Danke für Ihre Hilfe..
Ich habe neu angefangen zu programmieren..und gibt es immer Problem..ich habe Avr Timer Calculator schon gesehen aber kann ich nicht so gut verstanden..zB: Prescaler=256 Reload=184 Timer=1000 us was bedeutet genau?Timer zahlt bis 184 dann 0 oder? wenn Prescaler=1024 reload=238 und Timer=1000 wahlt ,ist das besser ?(Timer 8 Bit)

(Bitte entschuldigen Sie ich habe Deutsch Probleme:confused:)
 
Hallo,

wenn du in bestimmten periodischen Zeitintervallen Programmteile ausführen möchtest, eignet sich zum Beispiel ein Overflow-Interrupt oder ein Compare-Interrupt eines Timers.

Overflow-Interrupt
Bei dem Overflow-Interrupt läuft der Timer ab einem bestimmten Wert los. Erreicht er das Ende (0xFF bei 8bit, 0xFFFF bei 16bit Timer), wird der Overfllow-Interrupt ausgelöst. In der Interruptroutine muss man den Timer wieder selbst auf den Anfangswert (Reloadwert) stellen (das muss möglichst zu Begin der Interruptroutine erfolgen).

Compare-Interrupt
Bei dem Compare-Interrupt läuft der Timer ab 0x00 los. Erreicht er den Wert, der zuvor in einem Compare-Register festgelegt wurde, wird der Compare-Interrupt ausgelöst, der Timer wird automatisch wieder auf 0x00 zurückgesetzt (CTC-Mode = Clear Timer on Compare Event).

Die Periodendauer des Interrupts läßt sich nun bei gegebener Oszillatorfrequenz (fosc) einerseits durch den Prescaler und andererseits durch den Reloadwert oder den Comparewert beeinflussen.

Die Taktzeit für den Timer ergibt sich folgendermaßen: tclk = Prescaler/fosc.

Beispiel:
8bit Timer, fosc = 16MHz, Interrupt-Periodendauer = 1ms

Overflow-Interrupt:
Prescaler = 128, Reloadwert = 131
1ms = (256-Reloadwert) x Prescaler / fosc
1ms = (256-131) x 128 / 16MHz

Compare-Interurpt:
Prescaler = 128, Comparewert = 124
1ms = Comparewert x Prescaler / fosc
1ms = (124+1) x 128 / 16MHz

Um den Overflow-Interrupt des Timers zu nutzen, musst du
  • Timer auf Reloadwert setzen
  • Overflow-Interrupt des Timers freigeben, eventuell zuvor Interrupt-Request-Flag löschen
  • Prescaler festlegen (jetzt läuft der Timer)
  • nicht vergessen global die Interrupts freizugeben
  • In der Interrupt-Routine selbst den Timer wieder mit Reloadwert beschreiben (bei 16Bit hier auf die Schreib-Reihenfolge von low und high achten)
Um den Compare-Interrupt des Timers zu nutzen, musst du
  • Compareregister mit Comparewert beschreiben
  • Timer auf 0x00 setzen
  • Compare-Interrupt freigeben, eventuell zuvor Interrupt-Request-Flag löschen
  • Prescaler festlegen (Timer läuft nun)
  • globale Interrupts freigeben.
Beispiel in C:
Compare, fosc = 16MHz, Periodendauer = 1ms

Code:
void InitTimer0CompareAInt(void)
{

   TIFR0 |= (1<<OCF0A);                // Interrupt Request loeschen
   TIMSK0 |= (1<<OCIE0A);              // Enable Output Compare A Interrupt

   OCR0A = 249;                        // CompareTime ist 1ms
   TCNT0 = 0;
   TCCR0A   |= 1 << WGM01;             // CTC Mode 2
   TCCR0B   |= (1<<CS01) | (1<<CS00);  // 64 prescaler, Timer0 Start

}

ISR(TIMER0_COMPA_vect)
{
   // Compare-Interrupt:
   // hier etwas tun, möglichst nur zeitkritische
   // Sachen erledigen
   
}
Ich hoffe, ich konnte dir hier etwas weiterhelfen.

Grüße,
Dirk
 
Danke für Ihre Unterstützung und Erklärung..
Ich werde erstmal Vorteiler,Vergleichswert und Frequenz bestimmen und Programm zu schreiben versuchen, dann melde ich wieder..
bis dann
 
Hallo
Mein Schrittmotorwinkel 1,8 und ich brauche 35000 Schritte.frequenz=200 hz
und Motorgeschwindigkeit ist immer konstant..wie kann ich Register einstellen?ich benutze 16 Bit Timer1.
 
Hallo,

man müsste wissen, welcher Mikrocontroller und welcher Timer genutzt werden soll. Oszillatorfrequenz fosc ist 18MHz?

Dirk
 
Atmega88 in C mit AVR Studio4 programmiern .16 Bit Timer1 benutzen und Frequanz 18.432 Mhz..ich möchte erstmal wissen, wie kann ich Timer einstellen Rechteck Signal zu erzeugen?
 
Hallo,

ich nehme an du möchtest alle 5ms (1/200Hz) in einem Interrupt die Ansteuerung des Motors ändern. Hier mal ein Beispiel wo das CompareA-Ereignis des Timer1 den CompareA-Interrupt auslöst, die OutputCompare-Pins haben die normale Portfunktion und werden durch das CompareA-Ereignis nicht beeinflusst.

In der Interrupt-Serviceroutine wird zum Testen PortB.7 getoggelt (hier müsste man am Pin 5ms low - 5ms high messen (100Hz)).

(Den Programmcode habe ich nicht getestet)

Code:
void InitTimer1CompareAInt(void)
{

   DDRB |= ( 1 << DDB7 );    //  PortB.7 Ausgang, Nur zum Testen

   TIFR1 |= (1<<OCF1A);                // Interrupt Request loeschen (sicherheitshalber)
   TIMSK1 |= (1<<OCIE1A);              // Enable Output Compare A Interrupt

   OCR1A = 11520;                      // CompareTime ist 5ms (11520 x 8/18,432MHz)
   TCNT1 = 0;
   
   TCCR1B   |= (1<<WGM12) | (1<<CS11); // Prescaler 8, CTC Mode 4, Timer1 Start

}

ISR(TIMER1_COMPA_vect)
{
   // Eventtime = 5ms
   PORTB ^= ( 1 << PB7 );   // PortB.7 toggle
   
}
Grüße,
Dirk
 

Anhänge

  • motor.png
    motor.png
    19,1 KB · Aufrufe: 16
wenn wir als Prescaler=16 Comparewert=5760 bestimmen, was passiert anders von dieser Programm?
 
Hallo,

ein Prescaler 16 ist im Timer1 Modul nicht vorhanden. Man könnte natürlich einen anderen Prescaler nehmen und dazu den passenden Comparewert. An der Periodendauer des Interrupts würde sich nichts ändern.

Mögliche Prescaler wären beim ATmaga88 Timer1 Modul 64, 256 und 1024. (siehe Datasheet Seite 134)

Dirk
 
Entschuldigung ich habe die Prescaler nicht geachtet ich habe Timer-Calculator geguckt..aber es ist egal,was aendert,wenn ich 64 oder 128 Prescaler benutze?
und in dem Beispielprogramm Frequenz 200Hz also der Takt 2,5ms high und 2,5ms low oder 5 ms low und 5 ms high?
 
Hallo,

mit folgenden Einstellungen erreicht man eine Interruptfrequenz von 200Hz (Periodendauer ist dann 5ms)

Prescaler 8, OCR1A = 11520
oder
Prescaler 64, OCR1A = 1440
oder
Prescaler 256, OCR1A = 360
oder
Prescaler 1024, OCR1A = 90

Der CompareInterrupt erfolgt immer alle 5ms.
Im Beispiel wird in der Interruptroutine (CompareInterruptA) der logische Zustand des Portpins geändert. Man erhält somit 5ms low und 5ms high (100Hz), dies ist nur zum Testen, falls man die Möglichkeit hat, mit einem Oszilloskop zu prüfen.

Gruß,
Dirk
 
Hallo
ich habe etwas geschrieben,aber funktioniert nicht richtig.:(

Code
#include <avr\io.h>
#include <inttypes.h>
#include <avr\interrupt.h>
#include <util/delay.h>

volatile int8_t i=0; //schrittanzahl

void InitPorts()
{
DDRB |= (1<<PB1) | (1<<PB2);
}
void InitTimer1(void)
{
DDRB |=(1<<PB7);
TIFR1 |= (1<<OCF1A);
TIMSK1 |=(1<<OCIE1A);
OCR1A = 1440;
TCNT1 =0;
TCCR1B |=(1<<WGM12) | (1<<CS11) | (1<<CS10);
}

ISR (TIMER1_COMPA_vect)
{
motor1();
}

void motor1()
{
for(i=0;i<100;i++){
PORTB^= (1<<PB1);
}
}
int main()
{
sei();
InitPorts();
InitTimer1();
do{}

while(1);

}

ich glaube , for Schleife ist falsch:(
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)