NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Project Help and Ideas » double delay time

October 01, 2015
by scootergarrett
scootergarrett's Avatar

I think I'm loosing it. My delay functions are off by a factor of two, but the real time interrupts are fine. I run this delay code:

#define TestPin B,1

int main()
{
    // LED as output
    OUTPUT(TestPin);

    TCCR1B |= (1<<CS12) | (1<<CS10) | (1<<WGM12);
    TIMSK1 |= (1<<OCIE1A);

    while(1)
    {
        TOGGLE(TestPin);
        delay_ms(1000);
    }

  return 0;
}

and get a ~2s delay between pin changes:

2sec pic

then I run this code with OCR1A = 14399; for a one second delay, and that is exactly what I get.

#define TestPin B,1

int main()
{
    OUTPUT(TestPin);

    // Interrupt Timing setup //
    TCCR1B |= (1<<CS12) | (1<<CS10) | (1<<WGM12);
    TIMSK1 |= (1<<OCIE1A);
    OCR1A = 14399;                 // Interrupt timing

    sei();          // Enable interrupts

    while(1);

    return 0;
}

/// Interrupt code ///
ISR(TIMER1_COMPA_vect)
{
    // Interrupt code ...

    TOGGLE(TestPin);
    return;
}

1sec pic

Are the fuses I'm using wrong? I dont understand how the clock is wrong for some features. any ideas?

else ifeq ($(MCU),atmega328p)
    BOOT_SECTION_START = 0x7C00
    LFUSE = F7
    HFUSE = D2
    EFUSE = FD
    LOCK = EF
October 02, 2015
by BobaMosfet
BobaMosfet's Avatar

scootergarrett-

Make sure you are overriding the default F_CPU value in delay.h.

BM

October 05, 2015
by scootergarrett
scootergarrett's Avatar

I don't understand how changing F_CPU will effect the delay code, its never used

// delay.c
// for NerdKits with ATmega168, 14.7456 MHz clock
// mrobbins@mit.edu

#include <inttypes.h>
#include "delay.h"

// delay_us(...):
// delays a given number of microseconds
inline void delay_us(uint16_t us) {
  //_delay_us(us);
  uint16_t i;
  for(i=0; i<us; i++) {
    NOP;    // two is right for 8MHz, tested by mikey and robtruax
    NOP;

    NOP;    // so adding 7 more will yield a slightly slow clock (1.017us)
    NOP;
    NOP;
    NOP;
    NOP;
    NOP;
    NOP;
  }
}

// delay_ms(...):
// delays a given number of milliseconds
void delay_ms(uint16_t ms) {
  //_delay_ms(ms);
  uint16_t i;
  for(i=0; i<ms; i++)
    delay_us(1000);
}
October 08, 2015
by BobaMosfet
BobaMosfet's Avatar

scootergarrett-

Sorry, I thought you were using standard library routines, not custom.

Make sure the delay code you're looking at is actually getting included. Look at your disassembly.

BM

October 09, 2015
by scootergarrett
scootergarrett's Avatar

I didn't think I was using custom librarys, this is what the Nerdkits uses right?

October 09, 2015
by BobaMosfet
BobaMosfet's Avatar

scootergarrett-

You'll have to look at how your compiler/makefile setup is. I know that what you're looking at doesn't match the macro I have in the delay.h file my compiler links in:

void
_delay_us(double __us)
{
    uint8_t __ticks;
    double __tmp = ((F_CPU) / 3e6) * __us;
    if (__tmp < 1.0)
        __ticks = 1;
    else if (__tmp > 255)
    {
        _delay_ms(__us / 1000.0);
        return;
    }
    else
        __ticks = (uint8_t)__tmp;
    _delay_loop_1(__ticks);
}

The thing is, the chip is going to do exactly what you tell it to do. So if the output doesn't match your expectation, you need to determine why your expectation is wrong, and find where you're misdirecting the computer. Debugging is about checking all assumptions at the door and methodically checking each possibility.

BM

October 09, 2015
by BobaMosfet
BobaMosfet's Avatar

substitute 'device' for computer in my last. It's all the same, it's binary.

Post a Reply

Please log in to post a reply.

Did you know that interrupts can cause problems if you're not careful about timing and memory access? Learn more...