Mein Ziel ist es von zwei LEDs die eine im definierten Abstand blinken zu lassen, während die andere über den Fast PWM Modus von Timer0 an/aus fadet. Dabei verwende ich zum hoch/runterzählen der OCR0A keine Schleife mit den (üblichen) 12ms als Wartezeit (also nicht _delay_ms(12); wie ich es vorher hatte), sondern hab den Prescaler auf 64 eingestellt und lasse eine ISR bei Compare Match OCR0A verändern. Das kommt auch ganz gut hin, also der Verlauf sieht so flüssig aus, wie ichs gerne hätte, jedoch kommt die andere, blinkende LED immer wieder ins Stocken.
Code:
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
volatile uint8_t OCR0Adirection=0, OCR0Avalue=1;
//0->OCR0A raufzählen 1-> OCR0A runterzählen
ISR(TIMER0_COMPA_vect){
if(OCR0Adirection==0){
OCR0Avalue += 1;
if(OCR0Avalue==254) OCR0Adirection=1;
}else
if(OCR0Adirection==1){
OCR0Avalue -= 1;
if(OCR0Avalue==1) OCR0Adirection=0;
}
OCR0A = OCR0Avalue; //nur einmal schreiben, statt zweimal lesen und einmal schreiben
}
int main (void)
{
TCCR0A = (1 << COM0A1) | (1 << COM0A0) | (1 << WGM00) | (1 << WGM01);
TCCR0B = (1 << CS00) | (1 << CS01);
OCR0A = 1;
DDRB = (1 << PB2); //pin PB2 auf Ausgang (das ist OC0A)
DDRD = (1 << PD5);//die blinkende led
TIMSK = (1 << OCIE0A);
sei();
while(1){
PORTD &= ~(1<<PD5); //pins auf 0
_delay_ms(100);
PORTD |= (1<<PD5); //pins auf 1
_delay_ms(100);
}
}
Immer wenn die LED an PB2 grade besonders hell oder besonders dunkel ist, also an den Wechselpunkten,
macht die LED an PD5 nur noch ganz kurze delays im Aus-Zustand.
Meine Theorie ist, dass es an den Ifs liegt, die OCR0Adirection umschreiben, was anderes, besonderes passiert ja nicht.
Kann man das irgentwie besser ins Gleichgewicht bringen? Meine ISR ist ja eigentlich gar nicht so lang und wenn die den Programmablauf schon so sehr beeinflusst, wie würde es dann erst bei etwas längeren Methoden aussehen...
Lesezeichen