0
\$\begingroup\$

I'm currently using ATmega32 device with external clock speed of 16 MHz . the problem when i use a delay of for example 16,000 ms in the software, it actually delays only a 1000 ms in actual world. I mean the uC CPU divides the delay time by the clock frequency in MHz to make the delay (16,000 ms / 16 MHz). Also when i use a 8 MHz clock with the same amount of delay it would make a delay of 2,000 ms. What would be the reason for that?

Edit "Here is my code"

include avr/io.h>

include util/delay.h>

include stdio.h>

include stdlib.h>


define F_CPU 16000000 

define BAUD 9600

define BRC  ((F_CPU/BAUD/16)-1)


void USART_Init(unsigned int brc)

{   

// set baud rate

    UBRRH = (unsigned char) (brc >> 8)  ;
    UBRRL = (unsigned char) brc ;

    UCSRB = (1 << TXEN ) | (1 << RXEN) ; // enable receiver and transmitter
    UCSRC = (0 << UMSEL); // setting Asynchronous mode
    UCSRC = (1 << UCSZ1) | (1 << UCSZ0); // set communication number of bits (8 in this case)
}

int main(void)
{


    USART_Init(BRC) ;
    while(1)
    {
        char c;

        _delay_ms(32000);
        for (int i=0 ; i<=3 ; i++)
        {
            if (UCSRA & (1 << UDRE))
            {

                UDR = i;
                _delay_ms(8000);
            }
        }

    }
}
\$\endgroup\$
  • \$\begingroup\$ It sounds like your delay routine is anticipating a clock frequency of 1 MHz. \$\endgroup\$ – Andy aka Aug 22 '18 at 15:23
  • \$\begingroup\$ @Andyaka Yes, but how to change that \$\endgroup\$ – Ahmed M.Zahran Aug 22 '18 at 15:36
  • 1
    \$\begingroup\$ Does your delay routine use that defined constant? Share the code for your delay function/macro, and we'll have a better chance of helping. \$\endgroup\$ – The Photon Aug 22 '18 at 15:56
  • 2
    \$\begingroup\$ "I have defined in my code that FCPU is 16000000" - You have defined F_CPU after including delay.h. Did the compiler give any warnings? \$\endgroup\$ – Bruce Abbott Aug 22 '18 at 22:49
  • 2
    \$\begingroup\$ Move the line '#define F_CPU 16000000' up to the top of the file. Make sure that compiler optimization is turned on (eg. -Os). Read and respond to any compiler warnings. \$\endgroup\$ – Bruce Abbott Aug 26 '18 at 6:21
1
\$\begingroup\$

You cannot use _delay_ms to wait for that long. According to the AVR GCC description of the function:

The maximal possible delay is 262.14 ms / F_CPU in MHz.

When the user request delay which exceed the maximum possible one, _delay_ms() provides a decreased resolution functionality. In this mode _delay_ms() will work with a resolution of 1/10 ms, providing delays up to 6.5535 seconds (independent from CPU frequency). The user will not be informed about decreased resolution.

Also, you should check that you set CLKDIV8 and CLKSEL correctly for your system.

\$\endgroup\$
  • \$\begingroup\$ in ATmega32 the CLKDIV8 fuse is not available, rather a fuse called BODLEVEL exists. \$\endgroup\$ – Ahmed M.Zahran Aug 25 '18 at 8:22
0
\$\begingroup\$

Doesn't sound like you have the "divide by system clock by 8" fuse set correctly, which is independent of the code.

\$\endgroup\$
  • \$\begingroup\$ In case of an accidentally set CLKDIV8 fuse, the actual delay would be longer than expected, not shorter. Also, the Atmega32 does not feature a clock division fuse. \$\endgroup\$ – Marco Zollinger Sep 4 '18 at 18:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.