Forum: Mikrocontroller und Digitale Elektronik Mega32 Problem mit IRQ


von MArtin (Gast)


Lesenswert?

Hi,

ich bin solangsam etwas ratlos. Im Forum, Google und das Datasheet haben 
mir irgendwie nicht mehr weitergeholfen .... who wanna be my glory 
rescuer?


Also:  Ort des Geschehens:  Mega32 @ 8 MHZ (intern osc)

Ich habe 3 PWM-Kanäle (OC2,OC1A,OC1B).
Ich habe 1 Interrupt auf Timer0 (1/100s) bei 8MHz

Problem:

Ohne den Timer0 -> geht das PWM
Mit dem Timer0 -> nix PWM, dafür geht Timer0

================================
== Hier der Code für den PWM: ==
================================

    TCCR1B |= (1<<CS12); //Prescaler 256
    TCCR2  |= (1<<CS22) | (1<<CS21) | (0<<CS20); //Prescaler 256


  // 2. Den Timer in den Fast PWM Mode, 8 Bit schalten
  TCCR1A |= (1<<WGM10);
  TCCR1B |= (1<<WGM12);
  TCCR2  |= (1<<WGM21) | (1<<WGM20);


// 3. Compare Output mode einstellen: Pin geht auf high bei Compare 
match, auf low bei Überlauf.  Ergibt nichtinvertierte PWM.
TCCR1A |= (1<<COM1A1) | (1<<COM1B1) ;
TCCR2  |= (1<<COM21) | (1<<COM20) ;

// PWM-Werte  (testweise)
OCR1A =  127;
OCR1B = 127;
OCR2  = 127;

// Die Pins als Ausgänge konfigurieren.
DDRD |= (1<<PD4) | (1<< PD5) | (1<< PD7);


===================================
== Hier der Code für den Timer0: ==
===================================



TCCR0 = ( 1<<CS02 ) | ( 0<<CS02 ) | ( 1<<CS00 );
TCNT0  = 65535 - ( ( 8000000 / 1024 ) / 100) ;// Vorladen
TIMSK |= (1<<TOIE0); // Interrupts aktivieren und damit Timer starten
sei();




ISR( TIMER0_OVF_vect )
{
    cli();
                TCNT2 = 65535 - ( ( 8000000 / 1024 ) / 100) ;

                // ...... hier kommt was ....

                sei();
}




Wo liegt denn mein Denkfehler? Ich kann doch Timer0 unabhängig von Timer 
1&Timer2 verwenden.... warum beeinflussen die sich denn?

Heul....

von Haudrauf ! (Gast)


Lesenswert?

In der ISR verwendet man sicher kein cli & sei. Lass die beiden mal weg.
In der ISR laedt man eine konstante, keine Rechnung. Weshalb wird TCNT2 
in der isr des timer0 geladen ?

von MArtin (Gast)


Lesenswert?

Hi,

das weglassen von cli,sei im ISR hat keine veränderung gebracht.
Ebenso das weglassen der aufladung.

P.s. die "rechnung" würde der Compiler mit -Os eh wegoptimieren... hoffe 
ich

von Oliver J. (skriptkiddy)


Lesenswert?

MArtin schrieb:
> TCNT0  = 65535 - ( ( 8000000 / 1024 ) / 100) ;// Vorladen
Dafür hat man den CTC-Modus erfunden.
Und seit wann hat Timer0 16 Bit?

von Oliver J. (skriptkiddy)


Lesenswert?

MArtin schrieb:
> Ebenso das weglassen der aufladung.

Du solltest wenn du schon das Register laden willst, TCNT0 nehmen und 
nicht TCNT2.

von MArtin (Gast)


Lesenswert?

> Und seit wann hat Timer0 16 Bit?

Uppsss... Das ist ein sehr guter Punkt!

von MArtin (Gast)


Lesenswert?

Oliver J. schrieb:
> MArtin schrieb:
>> Ebenso das weglassen der aufladung.
>
> Du solltest wenn du schon das Register laden willst, TCNT0 nehmen und
> nicht TCNT2.

War noch 'übrig' vom rumspielen... cut&paste error ...

von MArtin (Gast)


Lesenswert?

Wie würde dann das für 8 bit im Timer 0 mit CTC aussehen ?

von Oliver J. (skriptkiddy)


Lesenswert?

MArtin schrieb:
> Wie würde dann das für 8 bit im Timer 0 mit CTC aussehen ?

Schau mal hier:
http://www.rn-wissen.de/index.php/Timer/Counter_%28Avr%29

Dort gibt es ein Beispiel für Timer2. Sollte sich auf Timer0 übertragen 
lassen.

von MArtin (Gast)


Lesenswert?

Hmmm..

jetzt habe ich:

TCCR0= (0<WGM01) | (0<<WGM00) |  ( 0<<CS02 ) | ( 1<<CS02 ) | ( 1<<CS00 
);
TCNT0 = 244;
TIMSK |= (1<<TOIE0);
sei();

sowie:


ISR( TIMER0_OVF_vect )
{
  TCNT0 = 244;
  .... irgendwas kurzes tun ...
}


.... funktioniert für timer0, aber das PWM ist wieder kaputt :(

P.s. Die freq. ist jetzt höher f. timer0, aber egal...

von Oliver J. (skriptkiddy)


Lesenswert?

Zeig bitte den ganzen code.

edit: und bitte als c-datei anhängen.

von MArtin (Gast)


Lesenswert?

Oliver J. schrieb:
> Zeig bitte den ganzen code.

Hui.... das wird schwierig..... Das ganze ist ein RGB LED Stripes 
Controller, der 3 RGB Farben ansteuert und via Ethernet per WEB-Server 
erreichbar ist.

Das alles funktionert ganz gut, d.h. ich kann die LEDS korrekt 
ansteuern, der WEB-Server tut und antwortet artig, ich kann die Werte 
für die 3 Kanäle richtig einstellen - nur werden diese eben nicht mehr 
richtig ausgegeben.

arrrrrrrrggggggggggssssssss.............

ICH BIN SOOOOOO EIN IDIOT ....... GRRRRRR...... es tut jetzt....

Grund:

Die werte von dem HTTP-Request (Wertebereich 0..1000) rechnete ich 
runter mit:

    OCR1A =  ((float)wert_r / 3,93);
  OCR1B = ((float)wert_g / 3,93);
        OCR2  = ((float)wert_b / 3,93);

nun mit

   OCR1A =  wert_r;
  OCR1B = wert_g;
        OCR2  = wert_b;

tut das ganze .... sofern ich die werte nicht >255 sezte...

von MArtin (Gast)


Lesenswert?

Interessant... mit

    OCR1A =  ((float)wert_r / 3.93);
  OCR1B = ((float)wert_g / 3.93);
    OCR2  = ((float)wert_b / 3.93);

(man beachte den "." anstelle "," geht es nun ....

wo ist denn hier der unterschied ?

von MArtin (Gast)


Lesenswert?

Vielen Dank Oliver!

von Oliver J. (skriptkiddy)


Lesenswert?

MArtin schrieb:
> wo ist denn hier der unterschied ?

lies am besten mal ein c-buch, bevor du weiter machst.

von MArtin (Gast)


Lesenswert?

:)

ich habe nur schon lange kein C mehr gemacht bzw. einfach zuviel java 
....

P.s. Den "Komma-Operator" war mir neu... aber hätte da der
Compiler nicht einen Fehler melden müssen ... die "93" ist da doch 
völlig unsinnig .... obwohl ... vielleicht hat er aus

OCR1A =  ((float)wert_r / 3,93);

dann der compiler:


OCR1A =  ((float)wert_r / 3);
OCR1A =   (93);

gemacht...

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.