ATmega1608 TCB0 Periodic Interrupt mode

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all,

I've been trying to use the TCB0 peripheral on an ATmega1608 and started by trying to blink an LED using a simple ISR. Instead the LED just stays on (it'd be too fast to see with the eye if it did work, I checked with a scope and it's just constantly on). There's just an 'ledflag' variable that's changed in the ISR, and the main loop checks the variable value and switches the LED based on it. I'm new to microcontrollers in general so it might seem like a trivial question but I've stared at the datasheet for a while now and am completely stumped, any help appreciated!

 


#include <avr/io.h>
#include <avr/interrupt.h>

volatile unsigned char ledflag = 0;

int main(void)
{
	TCB0_CCMP = 0xFFFF;           //Counter 'TOP' value to max
	PORTD_DIRSET = 0b00010000;	  //LED is on this pin
	TCB0_CTRLA = 0b00000011;	  //Enable counter with /2 clock prescaler
	TCB0_INTCTRL = 0b00000001;	  //Enable timer interrupts
	TCB0_CNT = 0;                 //Set counter to 0
	SREG |= 0b10000000;           //Enable global interrupts
    while (1) 
    {
		if (ledflag == 0)
		{
			PORTD_OUT = 0b00010000;		//LED on
		}
		else
		{
			PORTD_OUT = 0b00000000;		//LED off
		}
    }
}

ISR(TCB0_INT_vect)
{
	if (ledflag == 0)
	{
		ledflag = 1;
	}
	else
	{
		ledflag = 0;
	}
	TCB0_INTFLAGS = 0;	//Reset interrupt flag;
}

Thanks,

Ion

This topic has a solution.
Last Edited: Sat. Jun 5, 2021 - 12:50 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The interrupt flag has not been cleared.
Please do it like this.

	TCB0_INTFLAGS = 1;	//Reset interrupt flag;

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yep, I missed it in the datasheet: 'This bit is cleared by writing a ‘1’ to it or when the Capture register is read in Capture mode.' Thanks!