ATMEGA644PA _delay_ms() super slow

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

Hi all

https://imgur.com/a/eb4cLXU

This is my circuit on my PCB

I am having a problem with delay_ms going super slow. 


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

int main(){
	DDRD |= 1 << PIND4; 
	while (1){
		PORTD ^= 1 << PIND4;
		_delay_ms(100);
	}
   return(0);

}

that _delay_ms(100); is like about a second in real world time. What am I doing wrong?

I set my frequency to 16000000UL

 

Any help is appreciated.

 

 

This topic has a solution.
Last Edited: Fri. Jan 25, 2019 - 04:24 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,  

  Your AVR is running at 1MHz internal RC clock, which is the factory setting of the chip.  You need to adjust the fuse values to external crystal or external oscillator and attach a 16MHz crystal or oscillator to the AVR.   We can tell this by the delay(100) being about 1/8 - 1/10th of the expected speed.

 

  Simply changing the FOSC value to 16000000 in the software doesn't affect the actual hardware setting of the AVR's system clock.  The FOSC setting tells the compiler to expect that the system will be running at 16MHz:  it doesn't make the system actually run at 16MHz.

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

Thank you Simonetta. I am new to this but I know what your talking about!

I will let you know how it goes tomorrow.

 

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

Where and how do you: 

joshagirgis wrote:
I set my frequency to 16000000UL

 

When looking at the source code of: /usr/lib/avr/include/util/delay.h

/** \file */
/** \defgroup util_delay <util/delay.h>: Convenience functions for busy-wait delay loops
    \code
    #define F_CPU 1000000UL  // 1 MHz
    //#define F_CPU 14.7456E6
    #include <util/delay.h>
    \endcode

    \note As an alternative method, it is possible to pass the
    F_CPU macro down to the compiler from the Makefile.
    Obviously, in that case, no \c \#define statement should be
    used.

    The functions in this header file are wrappers around the basic
    busy-wait functions from <util/delay_basic.h>.  They are meant as
    convenience functions where actual time values can be specified
    rather than a number of cycles to wait for.  The idea behind is
    that compile-time constant expressions will be eliminated by
    compiler optimization so floating-point expressions can be used
    to calculate the number of delay cycles needed based on the CPU
    frequency passed by the macro F_CPU.

    \note In order for these functions to work as intended, compiler
    optimizations <em>must</em> be enabled, and the delay time
    <em>must</em> be an expression that is a known constant at
    compile-time.  If these requirements are not met, the resulting
    delay will be much longer (and basically unpredictable), and
    applications that otherwise do not use floating-point calculations
    will experience severe code bloat by the floating-point library
    routines linked into the application.

    The functions available allow the specification of microsecond, and
    millisecond delays directly, using the application-supplied macro
    F_CPU as the CPU clock frequency (in Hertz).
*/

...

#ifndef F_CPU
/* prevent compiler error by supplying a default */
# warning "F_CPU not defined for <util/delay.h>"
/** \ingroup util_delay
    \def F_CPU
    \brief CPU frequency in Hz

    The macro F_CPU specifies the CPU frequency to be considered by
    the delay macros.  This macro is normally supplied by the
    environment (e.g. from within a project header, or the project's
    Makefile).  The value 1 MHz here is only provided as a "vanilla"
    fallback if no such user-provided definition could be found.

    In terms of the delay functions, the CPU frequency can be given as
    a floating-point constant (e.g. 3.6864E6 for 3.6864 MHz).
    However, the macros in <util/setbaud.h> require it to be an
    integer value.
 */
# define F_CPU 1000000UL
#endif

Do you see that "#warning F_CPU not defined..." pop up in the compiler output ?

 

I'm kind of dissapointed they provide a default #define.

I would have much prefered:

#error "Please provide a valid F_CPU for <util/delay.h> and recompile."

 

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

Last Edited: Fri. Jan 25, 2019 - 12:59 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I do this in my CCFLAGS for avr-gcc  -DF_CPU=16000000UL

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

Got it, I did this avrdude -c stk500 -P com17 -p m644p -U lfuse:w:0xff:m -U hfuse:w:0xDE:m -U efuse:w:0xFD:m

This had BOD enabled though. Are there any advantages to disabling that?

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

I find the AVR fuses pretty ... confusing.

sometimes I use the engbedded website to generate some fuse settings, but always verify them with the datasheet to be sure.

Atmel studio also has a function to make fuse settings combinations in "human readable form".

 

An advantage of disabling BOD is that you can run your power supply from a lower power supply voltage.

This can be handy for battery operated equipment to get more usefull life out ouf the batteries.

 

The goal of the BOD is to prevent the AVR from executing "random" instructions during periods of low power supply voltage.

The most quoted malfunction are random writes to the EEPROM memory

 

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com