Go Down

Topic: SOLVED! ATMega328P at 14.7456 MHz (Read 3198 times) previous topic - next topic

avenue33

May 30, 2011, 09:25 pm Last Edit: Jun 01, 2011, 06:40 pm by avenue33 Reason: 1
Hi!

As describe at the thread Help! High Speed RS485 Serial Software, I plan to use my Arduino as a slave connected to a 921 600 bauds RS485 master. I can't lower the 921 600 speed of the bus.

I bought a Breadboard Arduino Compatible Kit from oomlout and a 14.7456 MHz crystal, since 14 745 600 / 16 gives 921 600. The RS485 to serial converter is a SN65176B / SN75176B.

I experienced no problem to build the kit and it worked fine from the start with the supplied 16 MHz crystal.

I use the Arduino Serial USB Board sold by Sparkfun to upload the sketches, with the classic trick of a 0.1 uF capacitor between USB DTR and Arduino Reset pin for automatic reset.

Now, when I use the 14,7456 MHz crystal, I can't upload any sketch.

I updated the following files:

/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/boards.txt
Code: [Select]
pro147.name=Arduino Board 5V 14,7456 MHz ATmega328

pro147.upload.protocol=stk500
pro147.upload.maximum_size=30720
pro147.upload.speed=57600

pro147.bootloader.low_fuses=0xFF
pro147.bootloader.high_fuses=0xDA
pro147.bootloader.extended_fuses=0x05
pro147.bootloader.path=atmega
pro147.bootloader.file=ATmegaBOOT_168_atmega328_14_7MHz.hex
pro147.bootloader.unlock_bits=0x3F
pro147.bootloader.lock_bits=0x0F

pro147.build.mcu=atmega328p
pro147.build.f_cpu=14745600L
pro147.build.core=arduino


/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/bootloaders/atmega/ATmegaBOOT_168.c around line 583
Code: [Select]
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__)
while(bit_is_set(EECR,EEPE)); //Wait for previous EEPROM writes to complete
#else
// while(bit_is_set(EECR,EEWE)); //Wait for previous EEPROM writes to complete
while(!eeprom_is_ready());
// http://arduino.cc/forum/index.php?action=printpage;topic=58154.0
// Title: ATmegaBOOT_168.c bootloader does not compile with newer AVR tools
// Post by: bperrybap on April 11, 2011, 02:26:42 AM

#endif


/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/bootloaders/atmega/Makefile
Code: [Select]
##################################################################
#
# May 28, 2011
#
atmega328147: TARGET = atmega328_14_7MHz
atmega328147: MCU_TARGET = atmega328p
atmega328147: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600
atmega328147: AVR_FREQ = 14745600L
atmega328147: LDSECTION  = --section-start=.text=0x7800
atmega328147: $(PROGRAM)_atmega328_14_7MHz.hex

atmega328147_isp: atmega328
atmega328147_isp: TARGET = atmega328_14_7MHz
atmega328147_isp: MCU_TARGET = atmega328p
atmega328147_isp: HFUSE = DA
atmega328147_isp: LFUSE = FF
atmega328147_isp: EFUSE = 05
atmega328147_isp: isp

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


 
I burned the boot-loader thanks to the procedure Using an Arduino as an AVR ISP. Burning went fine.

Two problems:

  • Auto-reset doesn't work. However, uploading a sketch with a manual reset runs fine and is successful.

  • The standard blinking LED with 1 second on and 1 second off is slower than expected. It seems the 14.7456 MHz is ignored, even when I declare

Code: [Select]
#define F_CPU        14745000L

So, two questions:

  • How to make the auto-reset working properly?

  • How to obtain the right speed in accordance to the 14.7456 MHz crystal?



Thank you for your help!

retrolefty

#1
May 30, 2011, 09:50 pm Last Edit: May 30, 2011, 09:56 pm by retrolefty Reason: 1
I will only talk about the bootloader/auto-reset part of your problem(s). The bootloader is hard coded to work at 16mhz for the specific upload baudrate specified in the boards.txt file. To change the bootloader to operate at the same baudrate now running at 14.7456 Mhz requires it be be recompiled with different baudrate values so as to work at the new clock frequency. This is not something you can do with the arduino IDE software.

EDIT: I see below that you are using a new/modified bootloader, so disregard my post.  ;)

Lefty

johnwasser

I read somewhere that SOMETHING in the Arduino is dependent on the processor speed being 1,000,000 * 2^^n (1MHz, 2MHz, 4MHz, 8MHz or 16MHz).  This may be what you are running into.  Maybe you can just ignore the problem is there aren't any critical delays in your code or you can shorten the delays to bring them back to spec.
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Coding Badly

I read somewhere that SOMETHING in the Arduino is dependent on the processor speed being 1,000,000 * 2^^n (1MHz, 2MHz, 4MHz, 8MHz or 16MHz).


The interrupt service routine for timer 0 (millis, micros) requires a power-of-two clock speed.

At 14745600 Hz, the error is 0.64%.  I think delay and delayMicroseconds integrate the error so "blink without delay" should give better results.

johnwasser


I read somewhere that SOMETHING in the Arduino is dependent on the processor speed being 1,000,000 * 2^^n (1MHz, 2MHz, 4MHz, 8MHz or 16MHz).


The interrupt service routine for timer 0 (millis, micros) requires a power-of-two clock speed.

At 14745600 Hz, the error is 0.64%.  I think delay and delayMicroseconds integrate the error so "blink without delay" should give better results.


I see it now in wiring.h and wiring.c:  The "clockCyclesPerMicrosecond" macro divides F_CPU by 1,000,000 (both integers).  Then micros() function will return a time based on a 14MHz clock and, worse, will integer divide that '14' it into 64 which gives a value of 4, same as for a clock speed of 16MHz.  The delay() function is based on the micros() clock so it, too, thinks the clock is running at 16MHz.

The delayMicroseconds() function is even worse.  If F_CPU is not equal to 16000000L then it is ASSUMED to be 8 MHz.
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Coding Badly

Quote
After some research, I found a strange collection of low level header files


That would be "AVR Libc".

Quote

#define F_CPU 14745600L  // This line is unnecessary.  The Arduino IDE provides this definition for you.  I suggest removing it.

#define BAUD  921600
#include <util/setbaud.h>
#include <util/delay.h>

Go Up