I want to use an Arduino Mega at 8MHz because my power supply is bad and I have only 4.3V (no way I can fix that), which is outside the operation range of the ATMega1280 at 16MHz. I think the right way to do it is to put a pre-factor 2 on CLKPR (tell me if I am wrong)? I know that several pages explain how to do so in a sketch: see How can you reduce the clock frequency of an Arduino Mega? , https://playground.arduino.cc/Code/Prescaler .
However, both those methods reduce the Mega frequency at run time, by setting the CLKPR register during the setup loop or another function, mess up with the millis(), delay(), Serial etc, and in addition I guess this means that the Mega is running at an out-of-spec 16MHz until the prefactor is set in the setup loop (?). So my question (I searched for it but found no answer) is:
- Can one set the clock prefactor at compile time, so that:
- the compiler knows about it,
- the millis(), delay(), Serial and similar are not disturbed
- the register is set immediately at boot (i.e. no need to change the registers in the setup)
?
2 Answers 2
1 and 3 can be solved by putting it in one of the initialization sections. 2 can be solved by creating and using a board.txt entry with the appropriate FCPU.
#include <avr/power.h>
void __attribute__((naked, section(".init1"))) preprescale(void)
{
clock_prescale_set(clock_div_2);
}
-
1. avr-gcc 4.9.2 tells me "error: attributes are not allowed on a function-definition". I took the liberty to edit your code into a form that this version of gcc accepts. 2. I would normally use
.init3
for that, but it appears thatclock_prescale_set()
does not rely onr1
being zero, soinit1
is fine.Edgar Bonet– Edgar Bonet2017年12月05日 18:44:41 +00:00Commented Dec 5, 2017 at 18:44 -
@EdgarBonet: Thank you for fixing it, it's been a while since I've had to actually do this.Ignacio Vazquez-Abrams– Ignacio Vazquez-Abrams2017年12月11日 14:54:15 +00:00Commented Dec 11, 2017 at 14:54
Clock speed is controlled by fuse settings and as such can be set at compile time - whether that will conflict with your bootloader is anyone's guess.
Gcc-avr allows fuse settings but you will need to burn it separately. F_CPU needs to be changed accordingly.
-
All the CKDIV8 fuse does though is start with the prescaler at /8 instead of /1.Ignacio Vazquez-Abrams– Ignacio Vazquez-Abrams2017年12月06日 01:20:45 +00:00Commented Dec 6, 2017 at 1:20