Forum: Mikrocontroller und Digitale Elektronik CTC Betrieb (OCA) am ATMega32


von Lenz (Gast)


Lesenswert?

Hallo,

ich versuche verzweifelt den OC0 Pin eines ATMega32 zu toggeln zu 
bringen. Hilfe aus Datenblatt, GCC-Tutorial und Forum sind ausgeschöpft, 
er will einfach nicht.

F_CPU = 14,7456 MHz

Meine Initialisierung:
1
DDRB = (1<<PB3); // OC0 als Ausgang
2
TCCR0 = 4;  //Timer0 auf FCPU/64 einstellen
3
TCCR0 |= (1 << WGM00); // CTC Modus (Timer 0 wird bei erreichen von OCR0 zurück gesetzt
4
TCCR0 |= (1 << COM00); //Toggle OC0
5
OCR0 = 108; //OC0 wird bei erreichen von OCR0 getoggelt
6
TIMSK |= (1<<OCIE0);    //Timer0 wird aktiviert

ISR:
1
ISR(TIMER0_COMP_vect){
2
  TCNT0 = 0;
3
  PORTB ^= (1 << PB3);
4
}
so geht es zwar, aber das ist natürlich nicht der Sinn der Sache. Er 
sollte ja TCNT0 automatisch auf 0 setzen und OC0 automatisch toggeln, 
was aber beides nicht geschieht. Auf diese Weise habe ich ein ungenaues 
Ergebnis und mehr CPU-Last.

Aber was stimmt an der Initialisierung nicht?

von Anon Y. (avion23)


Lesenswert?

sei(); ?

von Johannes M. (johnny-m)


Lesenswert?

1
> TCCR0 |= (1 << WGM00); // CTC Modus (Timer 0 wird bei erreichen von OCR0 zurück gesetzt
Also nach meinem Datenblatt muss für CTC WGM01 gesetzt sein und nicht 
WGM00...

So viel zum Thema "Datenblatt ausgeschöpft"...

von Johannes M. (johnny-m)


Lesenswert?

Anon Ymous wrote:
> sei(); ?
Wenn es mit Interrupt klappt, wird er wohl auch irgendwo ein sei() 
haben...

von MWS (Gast)


Lesenswert?

Welchen Mega32 hast denn Du ? ;-)

Mein Datenblatt dafür sieht anders aus, z.B. der Prescaler 64 entspricht 
B011, d.h. 3 und nicht 4.

Außerdem wird OC0 bei gesetztem COM00 per Hardware getoggelt, was soll 
denn das toggeln desselben Pins in der ISR ? Das ist Unsinn.

Per Hardware zu toggeln braucht's überhaupt keine Interrupts.

Für CTC muss der WGM01 gesetzt werden und nicht der WGM00.

von Karl H. (kbuchegg)


Lesenswert?

Lenz wrote:

> Meine Initialisierung:
> [c]
> DDRB = (1<<PB3); // OC0 als Ausgang
> TCCR0 = 4;  //Timer0 auf FCPU/64 einstellen
> TCCR0 |= (1 << WGM00); // CTC Modus (Timer 0 wird bei erreichen von OCR0
> zurück gesetzt

laut Datenblatt ist aber WGM01 für den CTC zuständig

von Justus S. (jussa)


Lesenswert?

MWS wrote:

> Außerdem wird OC0 bei gesetztem COM00 per Hardware getoggelt, was soll
> denn das toggeln desselben Pins in der ISR ? Das ist Unsinn.

er sagt ja, wenn er das so in der ISR macht, dann geht es...

von Johannes M. (johnny-m)


Lesenswert?

MWS wrote:
> Außerdem wird OC0 bei gesetztem COM00 per Hardware getoggelt, was soll
> denn das toggeln desselben Pins in der ISR ? Das ist Unsinn.
>
> Per Hardware zu toggeln braucht's überhaupt keine Interrupts.
Hallo? Vielleicht das OP mal lesen? Da steht, dass es mit Interrupt 
klappt, aber eben nicht ohne. Den Handler hat er nur aufgesetzt, weil es 
ohne Interrupt offensichtlich nicht klappte (was aufgrund des falschen 
WGM-Bits auch nicht weiter verwunderlich ist).

von MWS (Gast)


Lesenswert?

> er sagt ja, wenn er das so in der ISR macht, dann geht es...

Dann hat er sozusagen Glück, daß er es falsch macht, denn wenn beides 
gehen würde, also toggeln per HW und per ISR, wer würde dann das letzte 
Toggeln haben ? :D

Es kann sein, daß er irgendein ein Signal bekommt mit der ISR, aber 
deswegen ist das immer noch kein CTC was er hat, denn laut Datemblatt 
hat er mit gesetztem WGM00 die phasenkorrekte PWM eingeschaltet.

> Hallo? Vielleicht das OP mal lesen?

Sehe nicht, wo ich falsch liege. Es geht aus der OP nicht hervor, daß 
der Code abwecheselnd verwendet wird, es geht daraus hervor, daß er 
möglichst alles verwendet, um irgendeine Ausgabe zu erhalten.

Was passiert also wenn er HW phase correct PWM einschaltet und 
zusätzlich per ISR toggelt ?

Möglicherweise entsteht dann genau das "ungenaue Ergebnis"
Denn ungenau wär' trotzdem nix, das tät bei CTC und nur mit ISR auch 
sehr exakt funktionieren, nur wär' die Prozessorlast viel höher.

von Karl H. (kbuchegg)


Lesenswert?

MWS wrote:

>> Hallo? Vielleicht das OP mal lesen?
>
> Sehe nicht, wo ich falsch liege.

Deine Phantasie hat nicht gereicht, um zu erraten wie der OP vorgegangen 
ist.

> Es geht aus der OP nicht hervor, daß
> der Code abwecheselnd verwendet wird, es geht daraus hervor, daß er
> möglichst alles verwendet, um irgendeine Ausgabe zu erhalten.

Ganz genau.

Er wollte den Timer autonom im CTC arbeiten lassen.
Das hat aber nicht funktioniert. Er hat aber seinen Fehler in der 
Initialisierung nicht gesehen.

Um zu testen, ob der Pin bzw. Timer überhaupt funktioniert, hat er sich 
eine ISR angehängt und dort mal probehalber toggeln lassen. Das hat 
funktioniert.

Jetzt wollte er wissen, warum der Timer für sich alleine das nicht 
hingekriegt hat.

Sinnvollerweise hätte er seinen Testcode rausschmeissen sollen, bevor er 
hier postet. Vergiss die ISR. Die hat er nur rein gemacht um zu sehen ob 
der Timer überhaupt läuft bzw. ob der Ausgabepin in Ordnung ist.

von Lenz (Gast)


Lesenswert?

und schon klappts :)

danke.

Blöder Fehler, ich weiss, aber ich tendiere leider dazu meine eigenen 
Fehler auch nach 10-maligem Kontrollieren noch nicht zu finden.

von MWS (Gast)


Lesenswert?

Karl Heinz,

Fantasie hab' ich schon, nur warum soll ich die dazu einsetzen, Dinge zu 
vermuten, die möglicherweise nur in meiner Vorstellung so sind ?

Wenn er solchen Code postet, dann gehe ich davon aus, daß er den so 
meint. Das sollte ein Grundkonsens sein.

Hätte er jetzt eine reine ISR Version anbieten wollen, so hätte:
1
TCCR0 |= (1 << COM00); //Toggle OC0

rausgenommen werden müssen. Mit Setzen des OCIE0 belegt der OP hingegen, 
daß diese Init und die ISR zusammen gehört, und m.E. hat er das auch 
genau so miteinander betrieben. Und irgendwie mag's ja auch ein bisserl 
funktioniert haben.

Warum reicht nun meine Fantasie nicht ? :D

Aber immerhin haut's hin und gut ist's.

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.