title: avr timer1 16bit fast PWM
body: <p>I am using an Atmega328p-pu. I am trying to use the timer 1 for both a 16 bit PWM as well as using the overflow inturrupt to increment a timer. My code is below, I also set the F_CPU to 8000000UL in the make file. </p>
  
  <p>I would like the to have a variable that counts up for a defined amount of time and then resets and continues. so far I would expect it to count up for 7.5 seconds. I believe I should have a clock frequency of 8 MHz, then with fast PWM with a 1 prescaler and ICR1 at 5000 I would expect the inturrupt to happen at 1600 Hz. Then I let it count up for 12000 counts. I would expect this to take 7.5 seconds. but I've measured it at around 57 seconds. I'm not sure what I'm missing, maybe something in the setting of the registers, but I'm not sure where. thanks for your help, </p>
  
  <p>here is what I think is most important, </p>
  
  <pre class="lang-c prettyprint-override"><code>// values for timer1
  // WGM      13 12 11 10 is 
  // fast PWM  1  1  1  0
  
  TCCR1A |=  (1 &lt;&lt; 7); // output on A pin (COM1A1)
  TCCR1A |=  (1 &lt;&lt; 1); // WGM 11 
  TCCR1A &amp;= ~(1 &lt;&lt; 0); // WGM 10 
  
  TCCR1B |= (1 &lt;&lt; 4); // WGM 13 
  TCCR1B |= (1 &lt;&lt; 3); // WGM 12 
  
  //for prescaler of 1  set  CS12  CS11  CS10 
                              0     0     1 
  
  TCCR1B &amp;= ~(1 &lt;&lt; 2); // set prescaler to 1x CS12
  TCCR1B &amp;= ~(1 &lt;&lt; 1); // set prescaler to 1x CS11
  TCCR1B |=  (1 &lt;&lt; 0); // set prescaler to 1x CS10
  
  TIMSK1 = 0;  // enable output compare A inturrupt
  TIMSK1 |= (1 &lt;&lt; 0);  // Set the Overflow inturrupt
  TCNT1 = 0;            // set the counter to zero on startup
  ICR1 =  5000; //Set the top of the counter
  OCR1A = 0;  //set the duty cycle  
  ....
  ISR(TIMER1_OVF_vect){
  longTimer++;
  ....
      if (longTimer &gt;= 12000){
      longTimer = 0;
  </code></pre>
  
  <p>and here is the entire code </p>
  
  <pre class="lang-c prettyprint-override"><code>                                                           /* Light Control */
  
  // ------- Preamble -------- //
  #include &lt;avr/io.h&gt;                        /* Defines pins, ports, etc */
  #include &lt;avr/interrupt.h&gt;
  
  // Global variables 
  volatile uint8_t tick = 0;
  volatile uint8_t fastTimer = 0;
  volatile uint16_t longTimer = 0;
  volatile uint16_t fader = 0;
  volatile uint16_t dayBrightness = 0;
  volatile uint8_t nightBrightness = 0;
  uint8_t Day = 0; 
  
  void init(void) { 
  
  // values for push button inturrupt
    EIMSK = (1 &lt;&lt; 0);
    EICRA = (1 &lt;&lt; 1) &amp; (1 &lt;&lt; 0);
  
  // values for timer1
  // WGM      13 12 11 10 is 
  // fast PWM  1  1  1  0
  
    TCCR1A |=  (1 &lt;&lt; 7); // output on A pin (COM1A1)
    TCCR1A |=  (1 &lt;&lt; 1); // WGM 11 
    TCCR1A &amp;= ~(1 &lt;&lt; 0); // WGM 10 
  
    TCCR1B |= (1 &lt;&lt; 4); // WGM 13 
    TCCR1B |= (1 &lt;&lt; 3); // WGM 12 
  
    //for prescaler of 1  set  CS12  CS11  CS10 
                                  0     0     1 
  
    TCCR1B &amp;= ~(1 &lt;&lt; 2); // set prescaler to 1x CS12
    TCCR1B &amp;= ~(1 &lt;&lt; 1); // set prescaler to 1x CS11
    TCCR1B |=  (1 &lt;&lt; 0); // set prescaler to 1x CS10
  
    TIMSK1 = 0;  // enable output compare A inturrupt
    TIMSK1 |= (1 &lt;&lt; 0);  // Set the Overflow inturrupt
    TCNT1 = 0;          // set the counter to zero on startup
    ICR1 =  5000; //Set the top of the counter
    OCR1A = 0;  //set the duty cycle 
  
      sei();
  
  // values for IO
    DDRB |= 0b00000011;            /* Data Direction Register B: writing a one to the bit enables output. */
    DDRD  = 0x00;                 /* zero sets all as input */            
    PORTD = 0xff;                 /* set all inputs as pull ups */
  }
  
  ISR(INT0_vect){
      //longTimer = 0;
  } 
  
  ISR(TIMER1_OVF_vect){
  longTimer++;
  if(Day){
      fader++;
  }
  else{
      if(fader &gt; 0){
          fader--;
      }
  }
  } 
  
  int main(void) {
  
      init();
  
  // ------ Event loop ------ //
    while (1) {
  
      if(Day) {
          if (fader &gt;= 5000){
              OCR1A = 5000;
          }
          else {
              OCR1A = fader;
          }
      }
      else {
          OCR1A = fader;
      }
  
  
      if (longTimer &gt;= 12000){
          longTimer = 0;
          if(Day){
              fader = 5000;
          }
          else{
              fader = 0;
          }
          tick = 1;
      }
  
      if (tick == 1){
          Day ^= 1;
          tick = 0;
      }
  
    }                                                  /* End event loop */
    return 0;                            /* This line is never reached */
  }
  </code></pre>