The task is: after five clicks on OK, the built-in LED starts flashing with a frequency of 5Hz using an interrupt. After the eighth click on OK, the flashing (and glowing) should stop.Why is flashing not working
bool ledState = false;
volatile bool ledOn = true;
void setup(){
TCCR2A = 0;
TCCR2B = 0;
TIMSK2 = 0;
TCNT2 = 0;
OCR2A = 77;
TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20);
TIMSK2 |= (1 << OCIE2A);
pinMode(13, OUTPUT);
}
void loop(){
if(button5.buttonPressedCount >= 5 && button5.buttonPressedCount < 8){
ledState = true;
}
if(button5.buttonPressedCount > 7){
ledState = false;
}
}
ISR(TIMER2_COMPA_vect){
if(ledState){
digitalWrite(13, ledOn);
ledOn = !ledOn;
}
}
1 Answer 1
On the Uno (ATmega328P microcontroller), timers 0 and 2 are 8-bit only: they cannot count beyond 255. Timer 1, on the other hand, is 16-bits. This is the most convenient timer for generating low frequencies.
Speaking of frequencies... One LED period involves two toggles (turn on, then turn off). Thus, if you want the LED to blink at 5 Hz, the toggle action should happen at 10 Hz. Given that the CPU is clocked at 16 MHz, this means you have to toggle the LED every 1,600,000 CPU cycles.
If you set the prescaler to 1,024, you then you have to count 1,600,000/1,024 = 1,562.5 timer cycles. You cannot count a non-integer number of cycles, but you probably do not care about such accuracy. If you do care, set the prescaler to 256 and count 1,600,000/256 = 6,250 timer cycles by setting the compare match register to 6,249.
One last issue: keep in mind that, in normal counting mode, the timer counts up to its maximum value (65,535, or 255 on an 8-bit timer) and then restarts at zero. If you want it to count only up the value set in the compare match register, you should choose the appropriate waveform generation mode: the fast PWM mode that lets you control the TOP value with OCR1A.
-
then it should look like this?
TCCR1A = 0; TCCR1B = 0; TIMSK1 = 0; TCNT1 = 0; OCR1A = 6249; // Set compare match value for prescaler 256 TCCR1B |= (1 << CS12); // Set prescaler to 256 TIMSK1 |= (1 << OCIE1A); // Enable interrupt on compare match A
Good York– Good York2023年05月11日 13:51:12 +00:00Commented May 11, 2023 at 13:51 -
@GoodYork: Read the datasheet and see how to set the appropriate waveform generation mode.Edgar Bonet– Edgar Bonet2023年05月11日 13:57:35 +00:00Commented May 11, 2023 at 13:57
-
like this:
TCCR1A = (1 << WGM11) | (1 << COM1A0); TCCR1B = (1 << WGM12) | (1 << WGM13) | (1 << CS12); TIMSK1 = (1 << OCIE1A); OCR1A = 6250;
Good York– Good York2023年05月11日 13:58:14 +00:00Commented May 11, 2023 at 13:58
OCR2A = 77;
?OCR2A = 77;
?