Hello ,
Ive been consulting the Atmega328 datasheet + some internet tutorials and i want to use timer 1 to generate variable frequency with constant duty cycle. Ive written a code but it doesn`t work as aspected. For testing i am using a led on digital pin 9 (OC1A pin) , when the timer passes the OCR1A limit the OC1A pin(9) should be set high by the hardware , when the timer passes OCR1B the TIMER1_COMPB ISR must be serviced , this means timer will reset and the CPU will process the ISR making pin 9 LOW.
It works(the led blinks) but the timing is off..... As long as OCR1A<OCR1B and OCR1A,OCR1A=(10000...50000) the led will be ON for aprox 4 sec and OFF for 4 sec. Ive spend some time trying to find my mistake but i can`t see it.
Thanks for your time !
void setup()
{
pinMode(9,OUTPUT); //Set the OC1A pin to output
TIMSK1 &= ~((1<<TOIE1)|(1<<OCIE1A)|(1<<ICIE1)); //Disable all interrupts except OCIE1B
TCCR1A &= ~((1<<WGM11) | (1<<WGM10)); //Configure timer1 in normal mode (no PWM)
TCCR1B &= ~(1<<WGM12); // Configure timer1 in normal mode (no PWM)
TCCR1A |= (1 << COM1A1)|(1 << COM1A0); //Set OC1A on Compare Match (Set output to high level).
TCCR1A &= ~((1 << COM1B1)|(1 << COM1B0)); //Set normal port operation,OC1B disconnected.
OCR1A = 5024; //Set Output Compare Register 1 A
OCR1B = 5224; //Set Output Compare Register 1 B
TCCR1B |= (1<<CS12) | (1<<CS10) ; // Set bits for timer prescaler /1024
TCCR1B &= ~(1<<CS11); // Clear bits for timer prescaler /1024
TIMSK1 |= (1<<OCIE1B); //Set the interrupt for OCIE1B for timer 1
}
/* Install the Interrupt Service Routine (ISR) for Timer1. */
ISR(TIMER1_COMPB_vect) {
digitalWrite(9, LOW); //Set the pin LOW // The timer should autoreset
}
void loop()
{
//Nothing
}