No reti - M328P Timer1 overflow

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

AS 7.0.1645  ATmega328P,  also happens on ATmega328PB, Timer1 & Timer4.

 

oid TIMER1_OVF_vect()
{
    knt++;
  b6:    80 91 00 01     lds    r24, 0x0100    ; 0x800100 <_edata>
  ba:    90 91 01 01     lds    r25, 0x0101    ; 0x800101 <_edata+0x1>
  be:    a0 91 02 01     lds    r26, 0x0102    ; 0x800102 <_edata+0x2>
  c2:    b0 91 03 01     lds    r27, 0x0103    ; 0x800103 <_edata+0x3>
  c6:    01 96           adiw    r24, 0x01    ; 1
  c8:    a1 1d           adc    r26, r1
  ca:    b1 1d           adc    r27, r1
  cc:    80 93 00 01     sts    0x0100, r24    ; 0x800100 <_edata>
  d0:    90 93 01 01     sts    0x0101, r25    ; 0x800101 <_edata+0x1>
  d4:    a0 93 02 01     sts    0x0102, r26    ; 0x800102 <_edata+0x2>
  d8:    b0 93 03 01     sts    0x0103, r27    ; 0x800103 <_edata+0x3>
  dc:    08 95           ret

 

//ATmega328P
#include <avr/io.h>
uint32_t knt;

int main(void)
{
	TIMSK1 = 1;
	knt = 1;
	TCCR1B = 5;
    /* Replace with your application code */
    while (1) 
    {
    }
}

void TIMER1_OVF_vect()
{
	knt++;
}

 

This topic has a solution.
Last Edited: Mon. Feb 26, 2018 - 07:51 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Interesting, I tried with AS4.18 and got the same result. Then I thought it may have been because the sei() instruction and #include <avr/interrupt.h> wasn't there but same result.

 

Then I added some code in main and still nothing! This is crazy. It must be something we are not doing right, This is what I have now.

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

uint32_t knt;

int main(void)
{
	TIMSK1 = 1;
	knt = 1;
	TCCR1B = 5;
    /* Replace with your application code */

	sei();

    while (1)
    {
	PORTC ^= (1<<0);
    }
}

void TIMER1_OVF_vect()
{
	knt++;
}

but still no reti

 

int main(void)
{
    TIMSK1 = 1;
  90:    81 e0           ldi    r24, 0x01    ; 1
  92:    80 93 6f 00     sts    0x006F, r24
    knt = 1;
  96:    81 e0           ldi    r24, 0x01    ; 1
  98:    90 e0           ldi    r25, 0x00    ; 0
  9a:    a0 e0           ldi    r26, 0x00    ; 0
  9c:    b0 e0           ldi    r27, 0x00    ; 0
  9e:    80 93 00 01     sts    0x0100, r24
  a2:    90 93 01 01     sts    0x0101, r25
  a6:    a0 93 02 01     sts    0x0102, r26
  aa:    b0 93 03 01     sts    0x0103, r27
    TCCR1B = 5;
  ae:    85 e0           ldi    r24, 0x05    ; 5
  b0:    80 93 81 00     sts    0x0081, r24
    /* Replace with your application code */

    sei();
  b4:    78 94           sei

    while (1)
    {
    PORTC ^= (1<<0);
  b6:    91 e0           ldi    r25, 0x01    ; 1
  b8:    88 b1           in    r24, 0x08    ; 8
  ba:    89 27           eor    r24, r25
  bc:    88 b9           out    0x08, r24    ; 8
  be:    fc cf           rjmp    .-8          ; 0xb8 <main+0x28>

000000c0 <__vector_13>:
    }
}

void TIMER1_OVF_vect()
{
    knt++;
  c0:    80 91 00 01     lds    r24, 0x0100
  c4:    90 91 01 01     lds    r25, 0x0101
  c8:    a0 91 02 01     lds    r26, 0x0102
  cc:    b0 91 03 01     lds    r27, 0x0103
  d0:    01 96           adiw    r24, 0x01    ; 1
  d2:    a1 1d           adc    r26, r1
  d4:    b1 1d           adc    r27, r1
  d6:    80 93 00 01     sts    0x0100, r24
  da:    90 93 01 01     sts    0x0101, r25
  de:    a0 93 02 01     sts    0x0102, r26
  e2:    b0 93 03 01     sts    0x0103, r27
}
  e6:    08 95           ret

000000e8 <_exit>:
  e8:    f8 94           cli

000000ea <__stop_program>:
  ea:    ff cf           rjmp    .-2          ; 0xea <__stop_program>

 

 

on the other hand the interrupt routine is never executed, maybe the timer is not set up correctly, maybe you can check that. I need to do some work now. cheeky

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

Last Edited: Mon. Feb 26, 2018 - 01:44 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does TIMER1_OVF_vect () be recognized as an interrupt service routine?

 

//ATmega328P
#include <avr/io.h>
#include <avr/interrupt.h>  //<<<<<<<<<<<<<<<<<<<<<<<<
uint32_t knt;

int main(void)
{
	TIMSK1 = 1;
	knt = 1;
	TCCR1B = 5;
	/* Replace with your application code */
	while (1)
	{
	}
}

ISR(TIMER1_OVF_vect)  //<<<<<<<<<<<<<<<<<<<<<<<<
{
	knt++;
}

ISR(TIMER1_OVF_vect)

{

  b6: 1f 92        push r1

  b8: 0f 92        push r0

  ba: 0f b6        in r0, 0x3f ; 63

  bc: 0f 92        push r0

  be: 11 24        eor r1, r1

  c0: 8f 93        push r24

  c2: 9f 93        push r25

  c4: af 93        push r26

  c6: bf 93        push r27

knt++;

  c8: 80 91 00 01 lds r24, 0x0100 ; 0x800100 <_edata>

  cc: 90 91 01 01 lds r25, 0x0101 ; 0x800101 <_edata+0x1>

  d0: a0 91 02 01 lds r26, 0x0102 ; 0x800102 <_edata+0x2>

  d4: b0 91 03 01 lds r27, 0x0103 ; 0x800103 <_edata+0x3>

  d8: 01 96        adiw r24, 0x01 ; 1

  da: a1 1d        adc r26, r1

  dc: b1 1d        adc r27, r1

  de: 80 93 00 01 sts 0x0100, r24 ; 0x800100 <_edata>

  e2: 90 93 01 01 sts 0x0101, r25 ; 0x800101 <_edata+0x1>

  e6: a0 93 02 01 sts 0x0102, r26 ; 0x800102 <_edata+0x2>

  ea: b0 93 03 01 sts 0x0103, r27 ; 0x800103 <_edata+0x3>

  ee: bf 91        pop r27

  f0: af 91        pop r26

  f2: 9f 91        pop r25

  f4: 8f 91        pop r24

  f6: 0f 90        pop r0

  f8: 0f be        out 0x3f, r0 ; 63

  fa: 0f 90        pop r0

  fc: 1f 90        pop r1

  fe: 18 95        reti

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does TIMER1_OVF_vect () be recognized as an interrupt service routine?

Of course not! blush I knew it was a case of a loose nut behind the keyboard......

 

This is better and we get the reti.

 

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

uint32_t knt;

int main(void)
{
	TIMSK1 = 1;
	knt = 1;
	TCCR1B = 5;
    /* Replace with your application code */

	sei();

    while (1)
    {
	PORTC ^= (1<<0);
    }
}

ISR (TIMER1_OVF_vect)
{
	knt++;
}

 

edit oh I see that you had already fixed it.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

Last Edited: Mon. Feb 26, 2018 - 02:57 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Doesn't the variable 'knt' have to be declared as volatile in order to be the same variable inside and outside of the ISR(TIMER1_OVF_vect)?

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

Yes, it will not be reloaded in main unless declared volatile.
Although I was aware of it, I judged it as irrelevant as the content of the question and ignored it.

Last Edited: Mon. Feb 26, 2018 - 04:05 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

allano wrote:
Doesn't the variable 'knt' have to be declared as volatile in order to be the same variable inside and outside of the ISR(TIMER1_OVF_vect)?

Yes, it should be volatile - but that is not the reason!

 

kabasan wrote:
Yes, it will (sic) not be reloaded in main unless declared volatile.

Well, it might - but you need volatile to ensure that it will.

 

See: https://www.avrfreaks.net/forum/tutcoptimization-and-importance-volatile-gcc?skey=volatile

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...