Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

16 bit TIMER1 doesn't work #29

Closed
gfeun opened this issue Apr 2, 2020 · 4 comments · Fixed by #30
Closed

16 bit TIMER1 doesn't work #29

gfeun opened this issue Apr 2, 2020 · 4 comments · Fixed by #30
Labels
bug Something isn't working

Comments

@gfeun
Copy link
Contributor

gfeun commented Apr 2, 2020

Took me a while to figure this out.

Interrupts are triggered here:

if (
(this.WGM === WGM_NORMAL ||
this.WGM === WGM_PWM_PHASE_CORRECT ||
this.WGM === WGM_FASTPWM) &&
val > newVal
) {
this.TIFR |= TOV;
}

The this.WGM is implement here:

get WGM() {
return ((this.TCCRB & 0x8) >> 1) | (this.TCCRA & 0x3);
}

The timer1 is managed a bit differently than the 8 bit timers 0 and 2.
The WGM is 4 bits with : WG11/WG10 in bits 1/0 of TCCR1A and WG13/WG12 in bits 4/3 of TCCR1B

See pages 140 and 142 of http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf

We should implement timer 0/2 and timer 1 differently

@urish urish added the bug Something isn't working label Apr 2, 2020
@urish
Copy link
Contributor

urish commented Apr 2, 2020

What code / library did you use to see the effect of this?

@gfeun
Copy link
Contributor Author

gfeun commented Apr 2, 2020

This should demonstrate: http://www.engblaze.com/microcontroller-tutorial-avr-and-arduino-timer-interrupts/ (see end of post for the code)

I adapted to toggle LED_BUILTIN so that you can copy paste on this playground: https://wokwi.com/playground/blink

void setup()
{
pinMode(LED_BUILTIN, OUTPUT);

// initialize Timer1
cli(); // disable global interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B

// set compare match register to desired timer count:
OCR1A = 15624;
// turn on CTC mode:
TCCR1B |= (1 << WGM12);
// Set CS10 and CS12 bits for 1024 prescaler:
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS12);
// enable timer compare interrupt:
TIMSK1 |= (1 << OCIE1A);
// enable global interrupts:
sei();
}

void loop()
{
// do some crazy stuff while my LED keeps blinking
}

ISR(TIMER1_COMPA_vect)
{
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}

@gfeun
Copy link
Contributor Author

gfeun commented Apr 2, 2020

For reference, a working code using TIMER0 based on the same blog post:

void setup(){
  pinMode(LED_BUILTIN, OUTPUT);
  // initialize 8 bits Timer0
  // disable global interrupts
  cli();

  TCCR0A = 0;
  TCCR0B = 0;

  // set compare match register to desired timer count:
  OCR0A = 254;

  // turn on CTC mode:
  TCCR0A |= 1 << WGM01;
  // Set CS10 and CS12 bits for 1024 prescaler:
  TCCR0B |= 0x05;
  // enable timer compare interrupt:
  TIMSK0 |= (1 << OCIE0A);

  // enable global interrupts:
  sei();
}

void loop(){}

ISR(TIMER0_COMPA_vect)
{
  static int nb = 0;
  nb++;
  if (nb > 60) {
    nb = 0;
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
  }
}

@urish
Copy link
Contributor

urish commented Apr 2, 2020

Thank Glenn! Actually, looking into the playground, I realized it doesn't even use Timer 1, seems like 0 and 2 were sufficient for all the code samples I've ran to date.

So I guess this also means I never tested it with Timer 1 :-)

@urish urish linked a pull request Apr 4, 2020 that will close this issue
@urish urish closed this as completed in #30 Apr 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants