Hallo zusammen! Ich moechte eine LED mittels SW-PWM (habe nicht genug Timer fuer nur HW-PWMs dimmen. Mittels Tastern kann man den Vergleichswert vergroessern oder verkleinern, was bedeutet, dass die LED heller oder dunkler wird. Das ganze funktioniert auch recht schoen, nur ist das Problem, dass die LED auch vollkommen ausgeschaltet werden soll. Wenn der Vergleichswert Null wird setze ich SREG auf Null, (damit die globalen Interrupts nicht aktiviert sind) und gleichzeitig den Pin auch auf Null. Bei Erhoehen des Vergleichswertes mit Tastendruck aktivierte ich die Interrupts wieder und die LED leuchtet schwach. Allerdings kommt jedesmal erst ein kurzer heller Flash, als ob kurzzeitig das Tastverhaeltinis bei 255 liegt. Kann mir das vielleicht irgendjemand erklaeren? Bitte! Zur Info: ich verwende einen ATMega128 mit einem externen 8MHz Oszillor, Timer3 ist ein 16-Bit-Timer Das Programm ist wie folgt: /* SW-PWM mit Timer3: Ausgang C.4 */ #include<mega128.h> #include<stdio.h> #include<delay.h> //---------------------------------------------------------------------- ------------------------------------ interrupt [30] void t3_overflow(void) //bei Überlauf von T3 Ausgang C.4 = high { PORTC.4=1; } //---------------------------------------------------------------------- ------------------------------------ interrupt [27] void t3_compareA(void) //wenn Vergleichswert erreicht, Ausgang, C.4 = low { PORTC.4=0; } /*** HAUPTPROGRAMM ******************************************************************/ void main(void) { unsigned char a=10; // Vergleichswerte zu Beginn DDRC=0x10; //C.4 als Ausgang definiert, Rest ist Eingang PORTF=0xFF; //PORTF als Eingang, Pull-up aktiviert TCCR3B=0x01; //Timer3 clk/1 ETIMSK=0x14; //Overflow und VergleichswertA T3 SREG=0x80; //globaler Interrupt enable while(1) { if ((PINF.5==0)&&(a<255)) // Vergleichswert +/- { a++; delay_ms(50); } if ((PINF.4==0)&&(a>=1)) { a--; delay_ms(50); } OCR3AH=a; // Übergabe Vergleichswert an Vergleichsregister OCR3AL=a; else { PORTC.4=0; SREG=0x00; if(PINF.5==0) { a++; delay_ms(50); SREG=0x80; } } } } Vielen herzlichen Dank! LARA
> SREG=0x80;
Pfui, am SREG fummelt man nicht rum, jedenfalls nicht so! Mach es bitte
mit Inline-Assembler. Ich geh mal davon aus, dass das CodeVision ist
(solltest Du demnächst vielleicht direkt dazuschreiben, es gibt nämlich
ne ganze Reihe Compiler, die alle Unterschiede haben und nur bedingt bis
gar nicht portierbar sind), dann geht die Interrupt-Freigabe mit
#asm("sei")
und das globale Sperren mit
#asm("cli")
Ja, es ist CodeVision, sorry fuers nichts dazuschreiben. Aber woher hast Du das denn gewußt????? Warum darf ich nicht am SREG rumfummeln??? Kann daher der "Blitz" kommen? Ich werd's gleich mal mit "sei" und "cli" versuchen. Danke schoen LARA
Ich hab's probiert, das "blitzt" immer noch!!! Heul LARA
Hi, Ich denke Du musst beim Überlauf prüfen ob der Pin eingeschaltet werden muss. interrupt [30] void t3_overflow(void) //bei Überlauf von T3 Ausgang C.4 = high { if ( <einschaltbedingung> ) PORTC.4=1; } Gruß, Feadi
Guten Morgen Faedi! Vielen Dank fuer Deinen Tipp! ich habe es folgendermaßen versucht. nterrupt [30] void t3_overflow(void) //bei Überlauf von T3 Ausgang C.4 = low { if((OCR3AL!=1)&&(OCR3AH!=1)) { PORTC.4=1; } } Das gute ist, dass es nicht mehr blitzt. Das bloede, dass die LED nun erst wieder beim Vergleichswert 2 angeht (wir ja auch so in der Einschaltbedingung gefordert) Aber ich weiss nicht so recht, wie ich die Bedingung sonst gestalten soll, wenn ichs mit if((OCR3AL!=0)&&(OCR3AH!=0)) klappts ja auch nicht, da der Interrupt ja gar nicht ausgelöst werden kann... Vielleicht hat ja jemand noch ne Idee??? Vielen Dank im voraus! LARA P.S.: Warum ist es denn nun eigentlich besser den Inline-Assembler ("sei" und "cli" zu verwenden anstatt SREG zu setzten?
Hallo nochmals! Habe es nun hin bekommen! Ich aktiviere und deaktiviere einfach den Interrupt nicht mehr, sondern regel alles ueber eine Einschaltbedingung! Vielen Dank Feadi fuer den Hinweis! Aber den sei-/cli und SREG unterschied habe ich dennoch nicht verstanden?? Scheonen Tag LARA
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.