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

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

[avr-gcc-list] Problem with interrupt on a MEGA8535


From: dlc
Subject: [avr-gcc-list] Problem with interrupt on a MEGA8535
Date: Tue, 19 Feb 2008 11:10:00 -0700
User-agent: Thunderbird 2.0.0.9 (Macintosh/20071031)

I have an odd problem and I'm hoping that by trying to explain it I can solve it...

What I have is an timer overflow ISR that tics off every 10us. I've coded it thusly:

// variables at the top (global)
//ISR variables, volatile by nature
volatile uint16_t t_10us=0;
volatile uint32_t t_1ms=0;
volatile uint16_t repeat=0;
volatile uint16_t  match=0;             // The single servo used
uint8_t servo = 150;

// past initializations and such ...

SIGNAL(SIG_OUTPUT_COMPARE0)
/*
 * 10 microsecond ISR
 */
{
    t_10us++;
    if (t_10us > 100)
    {
        t_1ms++;                        //1ms background clock
        t_10us = 0;
        repeat++;
        if (repeat == 19)
        {
                repeat = 0;
                SPIN = 1;               //raise servo pin high
                match = 0;              //start servo timer
        }
    }
    match++;                            //increment every 1
    if (match == servo)
        SPIN=0;                         //drop servo bit
}

Now for the weird part. This all above seems to work fine unless I update "servo" too often. As seen below:

// More code goes by...

            servo = 100;
            for (i=100;i<215;i+=2)
            {
                servo = i;

// If these lines are used it seems to work, but with skipped beats
//              printf("servo = %d\n\r",i):
//              WaitMS(40);

// With this next line I just get the extremes, no intermediate steps
                WaitMS(150);
                if(PIR)
                {
                        RIGHT_STATUS = 1;
                        break;
                }
            }

What happens is that I only get the servo to move to the extreme locations, none of the intermediate ones when I am not using the printf() routine. This suggests a timing issue, but at 9600 baud those printf()'s aren't taking more than 10-12ms I'd guess, and its hardware so they shouldn't block either. I'm baffled.

 void WaitMS(uint16_t mswait)
 /*
  * WaitMS() will delay for the considered number of ms.
  */
 {
        uint32_t started = t_1ms + mswait;
        
    while (t_1ms < started)
          ;
    return;
 }

While I'm typing this it comes to me that perhaps the assembly in the ISR is not so compact as I would like and that it simply does not have time to do what needs done - But 150ms? I'm not so sure. Can anyone offer some suggestions why this code will not function properly? Any ideas accepted, including "Dennis you ignorant <expletive deleted>...

  In the mean time, I'm going to examine the assembler output...

many thanks,
DLC

--
-------------------------------------------------
Dennis Clark          TTT Enterprises
www.techtoystoday.com
-------------------------------------------------




reply via email to

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