delay function not working at 4mhz crystal with atmega328p

i am working with atmega328p with an external 4Mhz crystal, idea is to use atmega328p from 3V to 1.8V.

So this will be a battery operated device to work with sleep modes.

Problem

  1. I am not able to use delay function since it is not working properly, since i am generating waveforms with the help of delay it is very important for me to have precise delay.

  2. I am not able to upload my sketch though serial cable, currently i am using usbasp upload as programmer.

One more question can i use atmega328p with internal 4Mhz, it would be best to remove extra component.

Thanks in Advance. Varun

varun_pal:
I am working with atmega328p with an external 4Mhz crystal, idea is to use atmega328p from 3V to 1.8V.

OK.

varun_pal:
So this will be a battery operated device to work with sleep modes.

OK

varun_pal:

  1. I am not able to use delay function since it is not working properly, since I am generating waveforms with the help of delay it is very important for me to have precise delay.

The delay function will produce four times the delay at 4 MHz as it will at 16 MHz. Your minimum delay and increment will be 4 ms. You can modify the bootloader and boards.txt to re-calibrate the delay, but that really does not matter so much as you do not ever need to use delay anyway.

varun_pal:
2. I am not able to upload my sketch though serial cable, currently I am using USBASP upload as programmer.

Just set the baudrate in the IDE to a quarter of normal and the standard bootloader will work. Mind you, if you are using USBASP you do not need the bootloader anyway.

In a sketch, define the baudrate as four times what you actually want to use.

varun_pal:
One more question can I use atmega328p with internal 4Mhz, it would be best to remove extra component.

That would make total nonsense of your first assertion, that “it is very important for me to have precise delay”.

And the 328P has a 8MHZ crystal, not 4MHZ.

Isaac96:
And the 328P has a 8MHZ crystal, not 4MHZ.

Almost correct… the 328P has an 8MHz internal calibrated oscillator that can be configured to run at 8MHz or 1MHz with a fuse setting then configured to run at 8MHz / N where N is 1, 2, 4, 8, 16, 32, 64, 128, 256 with a register setting.

In other words, the 8MHz internal calibrated oscillator can be configured to run at 8MHz or 1MHz when the processor comes to life then reconfigured to run at 4MHz during initialization.

However, use of the internal calibrated oscillator is precluded by a requirement…

…it is very important for me to have precise delay…

varun_pal: 1. I am not able to use delay function since it is not working properly

F_CPU is wrong.

  1. I am not able to upload my sketch though serial cable, currently i am using usbasp upload as programmer.

Did you install a bootloader configured to run at 4 MHz?

thanks everyone for your suggestions now everything is working fine with external crystal @ 4Mhz, except one thing

PROBLEM:

i am still unable to upload the program using Serial programmer
although the steps i followed are as below

to make delay work, i changed my wiring.c to this

/* Delay for the given number of microseconds. Handles 20, 16, 8 or 4 MHz clock */
/* The 20 MHz change was in V1.0.1, the 4 MHz is my unofficial change.          */
void delayMicroseconds(unsigned int us)
{
	// calling avrlib's delay_us() function with low values (e.g. 1 or
	// 2 microseconds) gives delays longer than desired.
	//delay_us(us);
#if F_CPU >= 20000000L
	// for the 20 MHz clock on rare Arduino boards

	// for a one-microsecond delay, simply wait 2 cycle and return. The
	// overhead of the function call yields a delay of exactly 1 microsecond.
	__asm__ __volatile__ (
		"nop" "\n\t"
		"nop"); //just waiting 2 cycle
	if (--us == 0)
		return;

	// the following loop takes a 1/5 of a microsecond (4 cycles)
	// per iteration, so execute it five times for each microsecond of
	// delay requested.
	us = (us<<2) + us; // x5 us

	// account for the time taken in the preceeding commands.
	us -= 2;

#elif F_CPU >= 16000000L
	// for the 16 MHz clock on most Arduino boards

	// for a one-microsecond delay, simply return.  the overhead
	// of the function call yields a delay of approximately 1 1/8 us.
	if (--us == 0)
		return;

	// the following loop takes a quarter of a microsecond (4 cycles)
	// per iteration, so execute it four times for each microsecond of
	// delay requested.
	us <<= 2;

	// account for the time taken in the preceeding commands.
	us -= 2;
#elif F_CPU >= 8000000L
	// for the 8 MHz internal clock on the ATmega168

	// for a one- or two-microsecond delay, simply return.  the overhead of
	// the function calls takes more than two microseconds.  can't just
	// subtract two, since us is unsigned; we'd overflow.
	if (--us == 0)
		return;
	if (--us == 0)
		return;

	// the following _asm_ loop takes 4 cycles (half a microsecond at 8 MHz)
	// per iteration, so execute it twice for each microsecond of
	// delay requested.
	us <<= 1;

	// partially compensate for the time taken by the preceeding commands.
	// we can't subtract any more than this or we'd overflow w/ small delays.
	us--;
#else
	// For the 4 MHz case:  Do not change us.

	// for a 1 microsecond delay, simply return.  The overhead of
	// the function calls takes more than four microseconds.
	if (--us == 0)
		return;

	// the following _asm_ loop takes 4 cycles (one microsecond at 4MHz)
	// per iteration, so execute once for every microsecond of the argument.

#endif

	// busy wait
	__asm__ __volatile__ (
		"1: sbiw %0,1" "\n\t" // 2 cycles
		"brne 1b" : "=w" (us) : "0" (us) // 2 cycles
	);
}

the delay is working fine now if i upload the program through usbasp.

since i did a change in boards.txt for serial programming given below

##############################################################
pAvaR6LP.name=pAVA R6 Low Power (4 MHz) w/ ATmega328
pAvaR6LP.upload.protocol=arduino
pAvaR6LP.upload.maximum_size=30720
pAvaR6LP.upload.speed=28800

pAvaR6LP.bootloader.tool=arduino:avrdude
pAvaR6LP.upload.tool=avrdude

pAvaR6LP.bootloader.low_fuses=0xFF
pAvaR6LP.bootloader.high_fuses=0xDE
pAvaR6LP.bootloader.extended_fuses=0x05
pAvaR6LP.bootloader.path=optiboot
pAvaR6LP.bootloader.file=optiboot_atmega328.hex
pAvaR6LP.bootloader.unlock_bits=0x3F
pAvaR6LP.bootloader.lock_bits=0x0F
pAvaR6LP.build.mcu=atmega328p
pAvaR6LP.build.f_cpu=4000000L
pAvaR6LP.build.core=arduino
pAvaR6LP.build.variant=standard

##############################################################

Program does not upload and gives an error messages

C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avrdude -CC:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -carduino -PCOM9 -b28800 -D -Uflash:w:C:\Users\VAADYA01\AppData\Local\Temp\build7173828598596770212.tmp/sketch_jun24a.cpp.hex:i 

avrdude: Version 6.0.1, compiled on Apr 15 2015 at 19:59:58
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch

         System wide configuration file is "C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf"

         Using Port                    : COM9
         Using Programmer              : arduino
         Overriding Baud Rate          : 28800
avrdude: serial_baud_lookup(): Using non-standard baud rate: 28800         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : Arduino
         Description     : Arduino
avrdude: stk500_recv(): programmer is not responding
Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

firstly i uploaded arduino UNO bootloader (optiboot selecting uno board) and then i used my board (pAVA R6 Low Power) with 1/4th of uno’s upload speed (28800) but still i am unable to upload my program using serial programmer yet i am getting an error message given above.

please help me.

Look at the post from Coding Badly. Did you upload appropriate bootloader? It must be compiled for F_CPU=4000000.
If it not fits the serial uploading will not work.