Hallo,
ich verwende einen ATmega3290p bei 8 MHz. Durch nachfolgende
Init-Funktion, stelle ich den Timer0 so ein, dass ich einen CTC-Timer
habe. Den Systemtakt teile ich dafür durch 8.
Lasse ich den Timer nun auf Werte zwischen 0xFF und 0x0A zählen, toggelt
mein Ausgang beim Eintritt des Interrupts. Ist der Wert jedoch kleiner
als 0x0A, ist die Zeit bis zum Toggeln genauso kurz, wie wenn ich 0x0A
in das Compare-Register schreibe jedoch den Systemtakt ungeteilt lasse.
Ich hoffe ihr könnt mir sagen was ich falsch mache.
1
voidinit_timer(void)
2
{
3
// Bit 6, 3 - WGM01:0: Waveform Generation Mode
4
TCCR0A|=(1<<WGM01);// Clear Timer on Compare Match (CTC); Top=OCR0A;
5
TCCR0A&=~(1<<WGM00);// Clear Timer on Compare Match (CTC); Top=OCR0A;
6
7
// Bit 5:4 - COM0A1:0: Compare Match Output Mode
8
TCCR0A&=~(1<<COM0A1);// Toggle OC0A on compare match
9
TCCR0A|=(1<<COM0A0);// Toggle OC0A on compare match
Ich vermute gerade, mein Problem könnte vielleicht daran liegen, dass
ich das mit dem Teiler des Systemtaktes falsch verstanden habe.
Ich bin davon ausgegangen, dass ich mit dem clk/8-Takt die Werte von
0xFF (lange Zeit) bis 0x01 (kurze Zeit) einstellen kann. Und wenn ich
den Teiler einfach auf eins setze, meine Timer-Zeit linear kürzer wird.
Kann es sein, dass ich hier falsch liege? Wenn ja, dann wäre es
vielleicht auch logisch, dass der uC nicht das tut was ich möchte, da er
in der Zeit nicht mehr schafft die Interrupts zu bearbeiten.
Hat sich erledigt. Habe mir mal die Zeiten ausgerechnet und gegenüber
gestellt. Bei Werten kleiner 0x0A schafft es der uC nicht mehr die
Interrupts zu bearbeiten.
> Habe mir mal die Zeiten ausgerechnet und gegenüber gestellt.
Warum erst hinterher? Wenn man mit Timern arbeitet, rechnet man sich
bereits im Vorfeld die nutzbaren Vorteiler und Arbeitsbereiche aus.
> ISR(TIMER0_COMP_vect)> { // Ausgang wird getoggelt> }
Deine ISR enthält keinen Code. Wenn die ISR keine Arbeit erledigen muss,
dann wird sie auch nicht gebraucht und kann entfallen. Das Toggeln des
OC-Pins erfolgt ja durch Hardware (eingeschaltet per COM- und WGM-Bits)
im Hintergund, also ohne ohne zyklisches Abarbeiten von Code durch den
Prozessor.
Und mal so nebenbei:
> ...Bei Werten kleiner 0x0A schafft es der uC nicht ...
Warum betrachtest Du Zahlen, die Zählerstände darstellen (und in 1 Byte
passen), nicht einfach dezimal? Ist doch viel übersichtlicher. Oder
denkst Du hexadezimal?
Also ich sehe es so:
Zahlen, Zählerstände, Schleifenzähler, betrachtet man am besten dezimal.
Speicher-Adressen betrachtet man meist Hexadezimal.
ASCII-Werte schreibet man (wenn möglich) als lesbares Zeichen.
Bitmuster gibt man möglichst mit Bitnamen an, zumindest aber binär oder
hex.
Nur so als Anregung.
...
Hannes Lux wrote:
>> Habe mir mal die Zeiten ausgerechnet und gegenüber gestellt.> Warum erst hinterher? Wenn man mit Timern arbeitet, rechnet man sich> bereits im Vorfeld die nutzbaren Vorteiler und Arbeitsbereiche aus.
Er hat seinen Fehler selbst gefunden, er hat daraus gelernt und er hat
Feedback gegeben, wo er seine Frage gestellt hat - wo siehst du jetzt
einen Grund, nachtreten zu muessen?
> einen Grund, nachtreten zu muessen?
Sorry, das sehe ich nicht als Nachtreten, sondern als gut gemeinten
Hinweis für die Zukunft. Außerdem enthält mein Text auch noch andere
Hinweise, die vermutlich hilfreich sein könnten.
...
Sehe ich auch so.
Keine Ahnung was Hans Wurst als Fehler gefunden hat, aber die Ursache
ist es nicht, denn wie Hannes Lux schrieb: Das Pin toggeln geschieht in
Hardware. Selbst wenn sich der µC komplett aufhängt toggelt der Pin noch
weiter.
Davon abgesehen passen die Einstellungen aber. Es muss also an etwas
anderes liegen.
0x0A und Prescaler 8 ergibt einen Teilerfaktor von 88. Das sollte der µC
locker schaffen (ganz grob müsste ein leerer Interrupt etwa 10-20 Takte
brauchen)
Eine eigene Frage?
Dieser Thread ist über 17 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.