1

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

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);
}
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 that clock_prescale_set() does not rely on r1 being zero, so init1 is fine. Commented 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. Commented Dec 11, 2017 at 14:54
0

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.

1
  • All the CKDIV8 fuse does though is start with the prescaler at /8 instead of /1. Commented Dec 6, 2017 at 1:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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