ATMEGA644PA _delay_ms() super slow

7 posts / 0 new
Author
Message

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.

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.

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

I will let you know how it goes tomorrow.

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

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

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

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?

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