Archiv verlassen und diese Seite im Standarddesign anzeigen : Timer0 des ATmega32 tickt zu langsam
Hallo!
Ich habe ein Problem mit dem Timer0 des ATmega32. Der ATmega läuft mit 16MHz und ich möchte den Timer0 mit einer Frequenz von 100kHz laufen lassen. Ich habe den Timer0 folgendermaßen initialisiert:
TCNT0 = 0x00; //Timer 0 mit Null initialisieren
OCR0 = 160; //Vergleichsregister initialisieren
TIMSK = (1<<OCIE0); //Output Compare interrupt enable
sei(); //Enable Global Interrupt
//Timer Start
TCCR0 = ((1<<WGM01) | (1<<CS00) | (0<<WGM00) );
Die ISR sieht folgendermaßen aus:
SIGNAL(TIMER0_COMP_vect)
{
....
}
Leider läuft der Timer0 mit einer Frequenz von ca. 45kHz und ich kann nicht nachvollziehen woran es liegen mag. Vielleicht kann mir einer da weiterhelfen.
Vielen Dank im Voraus!
Mfg Djon
Ohne den Code gross angesehen zu haben.
Fusebits richtig gestellt? 8fachteiler draussen?
Hallo,
den 8fach-Teiler hat der nicht. Der Tip mit den Fusebits ist gut. Wenn die richtig sind, poste bitte ein kleines compilierfähiges Programm, das den Fehler zeigt. Wenn die ISR zu viele Anweisungen hat oder ein anderer Interrupt währe das eine Erklärung. Wie misst du die Frequenz? Wird ein Ausgang getoggelt? Würde auch fast passen.
Gruß
Jens
Hallo!
Meine Einstellung der Fuse-Bits habe ich hier beschrieben: https://www.roboternetz.de/phpBB2/viewtopic.php?p=395320#395320 Diese scheint ok zu sein. Die ISR hat schon paar Zeilen Code, da wird nämlich die Umrechnung der 100kHz-Frequenz in eine Zeitstruktur mit Stunde, Minute, Sekunde umgerechnet. Aber soll es wirklich daran liegen? Die Frequenz wird mit Hilfe der LED's, die die Sekunden binärkodiert darstellen, gemessen.
Mfg Djon
Hallo,
ja die Fusebits sind wohl okay.
Wenn die richtig sind, poste bitte ein kleines compilierfähiges Programm, das den Fehler zeigt.
Wenn das Programm etwas größer ist, zip es halt. Aber ohne den Code ist es nur ein Raten. Im AvrStudio kann man Programme simulieren und erkennt dort auch ohne großes Rechnen die Laufzeiten. Du könntest auch einen anderen Timer laufen lassen und am Anfang der ISR und am Ende eine Art Timestamp nehmen und dann vergleichen.
Gruß
Jens
Hallo!
Hier sind die besagten Quellcode-Dateien.
Mfg Djon
Besserwessi
10.09.2008, 22:19
Bei dem Codefehlt das zurücksetzen der 10 µs Ticks. Da wird also erst man nicht ducht 100, sondern durch 256 geteilt. Mit dem Faktor 2,56 kommt das dann auch mit der Frequenz hin. Wozu wird eigentlich der Interrupt so schnell gewählt, wenn doch erst mal nur bei jedem 100 ten mal was getan wird ? Da könnte man doch gleich mit einem Interrupt alle 1 ms anfangen. Die µs kann dann auch der Timer direkt in Hardware zählen, für den Fall das man die irgrndwo noch braucht. Entweder mit preskaler : 16 oder gleich bis 16000 Zählen.
Hallo,
die ISR ist def. nicht zu lang. Ich denke Besserwessi hat den Fehler schon gefunden.
static volatile uint16_t _Ticker1ms;
.
.
.
uint8_t getTicker1ms( void )
{
return _Ticker1ms;
}
Sind die unterschiedlichen Typen gewollt?
Wenn du ansonsten innerhalb der ISR bei einem 8Bit Controller eine 16 Bit Variable (_Ticker1ms) änderst, solltest du bei Zugriffen außerhalb der ISR den Interrupt abschalten, sprich die Stelle atomar machen. Es könnte sonst passieren, dass die Variable während des Lesezugriffes von der ISR geändert wird, ist uncool.
Falls du den 16 Bit Wert zurückgeben möchtest.
uint16_t getTicker1ms( void )
{
uint16_t Rückgabewert;
cli();
Rückgabewert = _Ticker1ms;
sei();
return Rückgabewert;
}
Wenn du eh nur 8 Bit zurück gibst ist es egal.
Gruß
Jens
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.