Forum: Mikrocontroller und Digitale Elektronik Clear Timer on Compare Match (CTC) Atmega32


von johnny (Gast)


Lesenswert?

Hi!
Ich möchte mit einem
Clear Timer on Compare Match (CTC) eine zyklisch eine ISR ausführen, die 
z.B. eine LED toggelt.

Ich möchte aber den Comparewert gerne über Tasten ändern und damit die 
Blinkfrequenz. So habe ich es versucht, passiert aber irgendwie nix, 
wenn ich den Knopf drücke
1
  TCCR1A = (1<<WGM01);    // CTC Modus
2
  TCCR1B |= (1<<CS01);    // Prescaler 8
3
4
  OCR1AH = (unsigned char) (variable >> 8);
5
  OCR1AL = (unsigned char) variable; 
6
7
 
8
  // Compare Interrupt erlauben
9
  TIMSK |= (1<<OCIE1A);
10
  // Global Interrupts aktivieren
11
  sei();
12
13
while(1)
14
{
15
  OCR1AH = (unsigned char) (variable >> 8);
16
  OCR1AL = (unsigned char) variable; 
17
if ((PINA & (1<<PINA0)) == 0x00)
18
{
19
  variable = 1000;
20
}
21
if ((PINA & (1<<PINA0)) == 0x00)
22
{
23
  variable = 100;
24
}
25
}

oben hab ich es einmal zum initialiersieren drinne und denn dachte ich 
wenn ich in der Schleife bin, kontrolliert er halt immer den aktuellen 
Wert
Funzt aber irgendwie nicht.

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

Wo ist die ISR?

von johnny (Gast)


Lesenswert?

so würd ich denken, oben in der Schleife fehlt noch die LED wieder 
auszumachen. Hab ich nich mit hin geschrieben.
1
ISR (TIMER1_COMPA_vect)
2
{
3
  PORTB = 0x01;
4
}

von johnny (Gast)


Lesenswert?

und ein delay von ein paar ms is noch in der Schleife :)

Ich stelle mir dass so vor: ISR --> LED ein paar ms ein, dann zurück in 
die while Schleife --> LED aus --> bis 1000 zählen, in die ISR --> LED 
ein;

und die 1000 möchte ich halt auch auf 100 stellen können mit einer Taste

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

So kann das auch nicht funktionieren: die beiden If-Bedingungen sind 
identisch.

Wenn Du immer nur Bruchstücke Deines Codes "freigibst", dann kann Dir 
keiner vernünftig helfen.

von johnny (Gast)


Lesenswert?

Hab den Quelltext grade nicht zur Hand und das aus dem Gedächtnis noch 
einmal hingeschrieben.

Aber die Änderung des Compareregisters ist soweit doch in Ordnung oder?

von Nn N. (jaytharevo)


Lesenswert?

Ganz schlau werd ich aus deinem Programm nicht.

In der ISR schaltest du zb. die LED die ganze Zeit ein. Was, wenn sie 
schon ein ist? Außerdem denk ich, dass du den Falschen Namen der ISR 
verwendest.
Möchtest du denn nicht beim erreichen des Wertes die ISR ausführen und 
dann wieder bei 0 beginnen zu zählen? Eventuell schau dir noch ein mal 
den Part des Datenblatts an, kann nicht schaden ;).
Wenn ja müsstest du den Overflow Interrupt aktivieren.

Also so:

ISR (TIMER1_OVF_vect)
{
  PORTB ^= (1<<PB0);
}

Weiter gehts. Welcher Datentyp ist die Variable "variable" denn, dass du 
sie vorher casten musst in einen char?
Bedenke: Char ist nur 8 Bit lang, kann also maximal 256 sein. 1000 ist 
definitiv zu groß!

So, jetzt optimiere mal und stelle danach den gesamten Sourcecode hier 
rein. Ich glaub wir sind noch nicht fertig :D ;).

MfG

von Karl H. (kbuchegg)


Lesenswert?

johnny schrieb:
> und ein delay von ein paar ms is noch in der Schleife :)
>
> Ich stelle mir dass so vor: ISR --> LED ein paar ms ein,

schon falsch.
Mach aus den Millisekunden ein paar Mykrosekunden (Millionstel Sekunden)

> dann zurück in
> die while Schleife --> LED aus

Nope.
Das LED aus muss ebenfalls in der ISR passieren.

 --> bis 1000 zählen, in die ISR --> LED
> ein;
>
> und die 1000 möchte ich halt auch auf 100 stellen können mit einer Taste

Und du denkst, dass du so schnell eine Taste drücken und wieder 
loslassen kannst, dass du kontrollieren kannst, welche der beiden if
1
  if ((PINA & (1<<PINA0)) == 0x00)
2
  {
3
    variable = 1000;
4
  }
5
  if ((PINA & (1<<PINA0)) == 0x00)
6
  {
7
    variable = 100;
8
  }

denn jetzt das letzte Wort hat.
Zu deiner Info: Dein µC arbeitet diese beiden Anweisungen (und den Rest 
deiner Schleife) viele hundertausendmal in der Sekunde durch. Wenn du da 
gezielt die Taste so loslässt, dass entweder das erste if oder das 2.te 
if den Vorzug bekommt, dann ist das ein Wunder!

von Freak (Gast)


Lesenswert?

Danke für eure Mühen!
Das casten hängt einfach damit zusammen, dass ich direkt in die Register 
geschrieben hab. Das macht jetzt der Compiler für mich.

zur Info:
Das hat weiter keine Bewandnis die LED zu toggeln, ich will einfach auf 
dem OSZI die Zeit sehen, in der die ISR auftreten.

Bei der Taste hab ich mich verschrieben. Das natürlich nicht der gleiche 
Pin.

Ich habe gelesen, dass der CompareTimer genau ist, als der OVerflow, 
darum nehme ich den.

Allerdings bleit die Zeit bis die ISR auftritt bei mir konstant, egal 
welcher Wert grade anliegt, daher bin ich verwirrt. Ich hab das Gefühl 
das holt der µC sich einmal und guckt denn gar nich wie es steht !?

von Karl H. (kbuchegg)


Lesenswert?

Freak schrieb:

> Bei der Taste hab ich mich verschrieben. Das natürlich nicht der gleiche
> Pin.

Genau deswegen kann man sich im Forum viele Freunde machen, indem man 
nicht seinen wirklichen Code postet sondern nur etwas was so ähnlich ist 
:-)



PS: Das war jetzt ein Hinweis!

von Freak (Gast)


Lesenswert?

habs selber gefunden, hatte gar nicht als CTC initialisiert :)
danke trotzdem :)

von Nn N. (jaytharevo)


Lesenswert?

Rofl, Trollalarm....

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.