'How to stop timer on ATmega328

I wrote some simple code where I am using the timer1 on my Arduino Uno. The problem is I can't stop the timer any way I try.

I am using this program to count and show on the display the number of external interrupts on pin 2 while measuring the time. But when I press button fin I want to stop generating interrupts for the program which is increasing the variable time called cas. Can you help somehow, please?

My code:

#include <OLED_I2C.h>
#define alarm_output 10 
#define fin 13

int suma=0;
int alarm=0;
float cas=0;

OLED  myOLED(SDA, SCL, 8);
extern uint8_t MediumNumbers[];
extern uint8_t BigNumbers[];
extern uint8_t SmallFont[];

void setup(void) {

   pinMode(alarm_output,OUTPUT);
   digitalWrite(alarm_output,LOW);
   pinMode(fin,INPUT_PULLUP);
   pinMode(9,INPUT_PULLUP);

   //interrupt
   interrupts(); 
   attachInterrupt(digitalPinToInterrupt(2), displej, CHANGE);

   //first screen
   myOLED.begin();
   myOLED.setFont(SmallFont);
   myOLED.print("TIME:", 0, 30);
   myOLED.print("INTERRUPT:", 0, 56);
   myOLED.print("Laser game", CENTER, 0);
   myOLED.setFont(MediumNumbers);
   myOLED.printNumF(cas,1,RIGHT,20);
   myOLED.setFont(BigNumbers);
   myOLED.printNumI(suma, RIGHT, 40);
   myOLED.update();

   //start loop
   up:;
   if(digitalRead(9)==1)
      goto up;

   // TIMER 1 for interrupt frequency 10 Hz:
   cli(); // stop interrupts
   TCCR1A = 0; // set entire TCCR1A register to 0
   TCCR1B = 0; // same for TCCR1B
   TCNT1  = 0; // initialize counter value to 0
   // set compare match register for 10 Hz increments
   OCR1A = 24999; // = 16000000 / (64 * 10) - 1 (must be <65536)
   // turn on CTC mode
   TCCR1B |= (1 << WGM12);
   // Set CS12, CS11 and CS10 bits for 64 prescaler
   TCCR1B |= (0 << CS12) | (1 << CS11) | (1 << CS10);
   // enable timer compare interrupt
   TIMSK1 |= (1 << OCIE1A);
   sei(); // allow interrupts
}

void displej(){
   suma++;
   alarm=3; 
}

ISR(TIMER1_COMPA_vect){
   cas=cas+0.1;
   if(alarm>0)
      alarm--;  

}

void loop(void) {
   myOLED.setFont(MediumNumbers);
   myOLED.printNumF(cas,1,RIGHT,20);
   myOLED.setFont(BigNumbers);
   myOLED.printNumI(suma, RIGHT, 40);
   myOLED.update();

   if(digitalRead(fin)==0){
      cli();
      TCCR1B |= (0 << CS12) | (0 << CS11) | (0 << CS10);  //this do now work
      detachInterrupt(digitalPinToInterrupt(2));
      sei();
   }
   if(alarm>0)
       digitalWrite(alarm_output,HIGH);
   else
       digitalWrite(alarm_output,LOW);

   delay(10);

}



Solution 1:[1]

Sure thing! There are two ways you can do it. You can simply stop the timer interrupt but leave the timer running using:

TIMSK1 &= ~(1 << OCIE1A);

Or, you can stop the timer altogether by altering the clock source to "none" like:

TCCR1B &= ~((1 << CS12) | (1 << CS11) | (1 << CS10));

which effectively undoes what you did to select the clock source in the first place. After this the CS12-CS11-CS10 bits will be 0-0-0 and the clock source will be stopped. See p. 134 of the datasheet.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 maxschlepzig