avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Mega32 wierdness


From: Jonny Dyer
Subject: Re: [avr-gcc-list] Mega32 wierdness
Date: Sun, 23 Jan 2005 10:34:35 -0800

Listing for the code in question follows:

Disassembly of section .text:

00000000 <main>:
/* volatile means value can change without explicit assignment */
volatile uint8_t timer_step;

int main (void)
{
   0:   c0 e0           ldi     r28, 0x00       ; 0
   2:   d0 e0           ldi     r29, 0x00       ; 0
   4:   de bf           out     0x3e, r29       ; 62
   6:   cd bf           out     0x3d, r28       ; 61
        uint8_t save;
        timer_step = 0;
   8:   10 92 00 00     sts     0x0000, r1
        DDRD = 0xFF;
   c:   8f ef           ldi     r24, 0xFF       ; 255
   e:   81 bb           out     0x11, r24       ; 17
        PORTD = 0x00;
  10:   12 ba           out     0x12, r1        ; 18

        TIFR  = BV(TOIE0);
  12:   91 e0           ldi     r25, 0x01       ; 1
  14:   98 bf           out     0x38, r25       ; 56
        TCCR0  = BV(CS02) | BV(CS00); /* CTC, prescale = 128 */
  16:   85 e0           ldi     r24, 0x05       ; 5
  18:   83 bf           out     0x33, r24       ; 51
        TCNT0  = 0;
  1a:   12 be           out     0x32, r1        ; 50
        TIMSK = BV(TOIE0);    /* enable Timer0 overflow interrupt*/
  1c:   99 bf           out     0x39, r25       ; 57
        sei();
  1e:   78 94           sei

        for(;;)
        {
                if(timer_step > 10)
  20:   80 91 00 00     lds     r24, 0x0000
  24:   8b 30           cpi     r24, 0x0B       ; 11
  26:   e0 f3           brcs    .-8             ; 0x20
                {
                        timer_step = 0;
  28:   10 92 00 00     sts     0x0000, r1
  2c:   f9 cf           rjmp    .-14            ; 0x20

0000002e <__vector_11>:
                }
        }
}

SIGNAL(SIG_OVERFLOW0)
{
  2e:   1f 92           push    r1
  30:   0f 92           push    r0
  32:   0f b6           in      r0, 0x3f        ; 63
  34:   0f 92           push    r0
  36:   11 24           eor     r1, r1
  38:   8f 93           push    r24
        timer_step++;
  3a:   80 91 00 00     lds     r24, 0x0000
  3e:   8f 5f           subi    r24, 0xFF       ; 255
  40:   80 93 00 00     sts     0x0000, r24
        PORTD ^= 0xff;
  44:   82 b3           in      r24, 0x12       ; 18
  46:   80 95           com     r24
  48:   82 bb           out     0x12, r24       ; 18
}
  4a:   8f 91           pop     r24
  4c:   0f 90           pop     r0
  4e:   0f be           out     0x3f, r0        ; 63
  50:   0f 90           pop     r0
  52:   1f 90           pop     r1
  54:   18 95           reti

Jonny

On Jan 23, 2005, at 5:56 AM, Trampas wrote:

Jonny,

I can not see anything wrong with your code, why don't you post the listing?


Also you want to be careful when changing variables that are used in
interrupt routines. That is you need to make sure that the changes to the
variables happen in one cycle, which should be the case for your code.
However if you changed the timer_step to a 16bit value, you would need to disable the interrupt before reading/changing timer_step in your main line
code.


Regards,
Trampas


-----Original Message-----
From: address@hidden [mailto:address@hidden
On Behalf Of Jonny Dyer
Sent: Sunday, January 23, 2005 4:39 AM
To: address@hidden
Subject: [avr-gcc-list] Mega32 wierdness

I am trying to get started working with GCC for AVR and am having a
terrible time with a Mega32.  Note that I am experience with AVR
assembly and the aTinys, but this is my first C AVR project.

As a simple test program, I have Timer0 interrupt enabled and am
running Timer0 at clk/1024.  On overflow, I am toggling all the pins on
Port D. If I do just this and nothing else, the program works fine.
However, I wanted to add a counter to the overflow function so that I
can divide the timer overflows further and only toggle the LED, say,
every 5 overflows. If I define my counter variable as volatile (as I
have read is necessary when working with interrupts several other
places), increment it in the interrupt function and leave the PORTD
toggling in that function, it still operates the same (as it should):

SIGNAL(SIG_OVERFLOW0)
{
        timer_step++;
        PORTD ^= 0xff;
}

However, if I do anything to timer_step in the rest of the code (namely
in main()), it's as if the timer overflow stops being called and the
pins on PORTD no longer flash.  Note that I am doing nothing at all to
my interrupt routine:

volatile uint8_t timer_step;

int main (void)
{
        uint8_t save;
        timer_step = 0;
        DDRD = 0xFF;
        PORTD = 0x00;
        
        TIFR  = BV(TOIE0);
        TCCR0  = BV(CS02) | BV(CS00); /* CTC, prescale = 128 */
        TCNT0  = 0;
        TIMSK = BV(TOIE0);    /* enable Timer0 overflow interrupt*/
        sei();
        
        for(;;)
        {
                if(timer_step > 10)
                {
                        timer_step = 0;
                }
        }
}

SIGNAL(SIG_OVERFLOW0)
{
        timer_step++;
        PORTD ^= 0xff;
}

I have disassembled the code and I can see nothing wrong with the code
GCC is generating either.  It is almost as if somehow messing with
timer_step (which gcc is saving at r0) outside of the interrupt
function corrupts TIMSK or TIFR or the interrupt vector.  Any help is
greatly appreciated.

Thanks
Jonny
_______________________________________________
avr-gcc-list mailing list
address@hidden
http://www.avr1.org/mailman/listinfo/avr-gcc-list





reply via email to

[Prev in Thread] Current Thread [Next in Thread]