3
\$\begingroup\$

I am trying to use the Timer0 overflow interrupt to make a little project. I used such a timer in the ATtiny45 and it worked, but with ATtiny10 no result.

So I tried an easy LED blinking program and even that didn't work.

Here is the simple code:

#define F_CPU 1000000UL  // 1 MHz

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>

volatile uint16_t overflow_val=0;

ISR (TIMER0_OVF_vect){
  overflow_val++;
}

int main(void){
  DDRB = (1<<PB1);
  // Timer0 normal mode
  TCCR0A = 0x00;
  // Start timer with presc 1:1024
  TCCR0B = (1<<CS02) | (1<<CS00);
  TCNT0 = 0;
  TIMSK0 |= (1 << TOIE0);
  sei();

  for(;;){  
    if(overflow_val >= 1)
        {
            if(TCNT0 >= 145){
                PORTB ^= (1 << PB1);
                TCNT0 = 0;
                overflow_val = 0;
            }
        }
  }
  return 0;
}

Hope someone can help me. Thanks!

EDIT1:

I changed line

TCCR0B = (1<<CS02) | (1<<CS00);  

to line

TCCR0B = (1 << CS01);  // clk/8

in my code to achieve an overflow every 0.524sec. But the LED is not blinking at all.

EDIT2:

Here is the size:

>avr-size test_attiny10_2.ino.elf
   text    data     bss     dec     hex filename
    138       0       2     140      8c test_attiny10_2.ino.elf

EDIT3:

I changed my if statement in the main as follows:

int main(void){

  ...

  TCCR0B = (1 << CS01);

  ...

  for(;;){
    if(TCNT0 >= 0xFFFE)
        {
                PORTB ^= (1 << PB1);
                TCNT0 = 0;
        }
  }
  return 0;
}

Now my LED is flashing all 0.524 seconds as it should!

So something is wrong with my volatile unit16_t variable overflow_val. Not only i tested it directly on hardware, but did also a simulation with atmelstudio. Also in the simulation the program is never entering the if statement if i use the variable overflow_val to toggle the LED.

EDIT 4

I think something is not right with my ISR fkt. I testet the following code and i never got the LED switched on.

#define F_CPU 1000000UL  // 1 MHz

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

volatile uint8_t ovf_counter = 0;

void ioinit(void){
    // PB1->outputs
    DDRB = (1<<PB1);

    // Start timer with presc 1:64
    TCCR0B = (1<<CS01) | (1<<CS00);
    // Initialize counter Overflow at 0xFFFF
    TCNT0 = 0;

    // Enable global interrupts
    sei(); 
}

int main(void){
    ioinit();
    TIMSK0 |= (1<<TOIE0);
      while(1){        
        if(ovf_counter>=2){
          PORTB = (1<<PB1);
          ovf_counter=0;    
        }
      }
}

ISR(TIMER0_OVF_vect){
  ovf_counter++;
  TCNT0 = 0;
}

i dont know what is wrong.

If i check in the while(1) loop the status of the counter register TCNT0 it works. So the counter is overflowing as it should, but it never enters on a overflow event the ISR(TIMER0_OVF_vect) function.

\$\endgroup\$
8
  • \$\begingroup\$ Too little RAM to use interrupts in C. Post what avr-size shows on your elf. Especially the data and bss sections. \$\endgroup\$
    – filo
    Sep 6, 2018 at 14:39
  • \$\begingroup\$ Are you linking in the crttn10.o startup file? \$\endgroup\$
    – C_Elegans
    Sep 6, 2018 at 14:51
  • 2
    \$\begingroup\$ Are you sure you waited long enough? This looks like it would take about 67 seconds to overflow. google.com/… \$\endgroup\$
    – bigjosh
    Sep 6, 2018 at 15:32
  • \$\begingroup\$ I'm not an AVR guy, but I suspect you need to globally enable interrupts --avrfreaks.net/forum/tut-newbies-guide-avr-interrupts?page=all \$\endgroup\$ Sep 7, 2018 at 13:05
  • 2
    \$\begingroup\$ @ScottSeidman the sei(); call does that. \$\endgroup\$ Sep 7, 2018 at 13:10

2 Answers 2

4
\$\begingroup\$

I found my mistake. I used:

ISR(TIMER0_OVF_vect){. . .}

instead of

ISR(TIM0_OVF_vect){. . .}

Now it works! At the overflow of timer0 the interrupt routine will be executed. Thanks for your help

\$\endgroup\$
1
\$\begingroup\$

It may look similar, but ATtiny45 Timer/Counter0 is 8-bit (it needs to count to 256 + 1 for overflow) , so for example waiting for overflow interrupt when CLK=1MHz, prescaler 1024 will take about 0.26 sec.
ATtiny10 Timer/Counter0 is 16-bit (counts to 65536). For same settings as above (1MHz clock, prescaler 1024) it gives 256 times 0.26sec = almost 67 seconds to overflow (as mentioned by bigjosh).

\$\endgroup\$
1
  • \$\begingroup\$ Hi, i changed now the prescaler to have clk/8 with the line TCCR0B = (1 << CS01); So i will have an overflow every 0.524seconds. But i can't see the LED blinking. \$\endgroup\$
    – sepplhans
    Sep 7, 2018 at 12:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.