Feed on
Posts
Comments

In this demo we show how we can change the ATtiny85 clock speed on the fly by modifying the prescaler. We note that using _delay_ms() is subject to the F_CPU and if we double the MHz we need to double _delay_ms() in order for the timing to be correct. Changing the clock speed on the fly may be useful for power saving applications where there might be brief moments to increase the clock speed, e.g. communicating with devices like USB.

Download the code: ATtiny85_CPU_Speed_v1.0

8 Responses to “Change ATtiny85 clock speed on the fly”

  1. ptichki_pichuzhki says:

    It was always a pain in the ass for me to calculate the delays in µs with different F_CPU values for 1-wire application (I guess it is called bit-banging when you do all those pin-up, pin-downs and delays in C). Moreover, you should watch the comments to those _delay_ms functions as they imply some restrictions to the passed parameters (which aren’t that obvious at all)

  2. Edson says:

    Hi, can you gice me a hint in how to use the file you make it available?
    I could see that is a NotePad project, however, how can I upload this to the Arduino?

    Thanks!

    Edson

    • Alex says:

      Hi Edson,

      If it’s for an ATtiny85 in Arduino IDE, the only bit of code you need are these bits:

      // Change to 2 MHz by changing clock prescaler to 4
      cli(); // Disable interrupts
      CLKPR = (1<<CLKPCE); // Prescaler enable
      CLKPR = (1<<CLKPS1); // Clock division factor 4 (0010)
      sei(); // Enable interrupts
      		
      // Change back to 1 MHz by changing clock prescaler to 8
      cli(); // Disable interrupts
      CLKPR = (1<<CLKPCE); // Prescaler enable
      CLKPR = ((1<<CLKPS1) | (1<<CLKPS0)); // Clock division factor 8 (0011)
      sei(); // Enable interrupts
  3. sms2000 says:

    Hi

    I tried the code above and succeeded. But what I’m failing to understand is how to dynamically raise the clock back 8 MHz for some time.
    I’m running most of the project at 1MHz but EEPROM library seems to like full clock. So I want to temporary raise it back to 8.

    Thanks
    Sergey

    • Alex says:

      Hi Sergey,

      The ATTiny/ATmega by default has an internal 8MHz RC oscillator and the fuse that sets the clock divider is set to 8 by default to give 1MHz out of the factory however we can change the clock divider in our code.

      Before you access any EEPROM function, you just have to use the following (assuming that you run at 1MHz with factory default fuses):

      cli(); // Disable interrupts
      CLKPR = (1<<CLKPCE); // Prescaler enable
      CLKPR = 0; // Clock division factor 1 (0000)
      sei(); // Enable interrupts

      Then after the EEPROM function, you just change the clock division factor to back to 8 to give 1MHz:

      cli(); // Disable interrupts
      CLKPR = (1<<CLKPCE); // Prescaler enable
      CLKPR = ((1<<CLKPS1) | (1<<CLKPS0)); // Clock division factor 8 (0011)
      sei(); // Enable interrupts
  4. TK says:

    And if you have a digistump Digispark clone running at around 16MHz you can also help run ultra low power on the fly by adjusting the clock pre-scaler right up to 256 if you have no need for such high clock speeds within your program 62.5KHz clock!

    cli(); // Disable interrupts
    CLKPR = (1<<CLKPCE); // Prescaler enable
    CLKPR = 8; // Clock division factor 256 (1000) divisor code n is encoded 2 the power of n with max divisor code of 8
    sei(); // Enable interrupts

    Theoretical slowest internal clock speed possible on ATTINY85 is 128KHz internal low power clock source in conjunction with clock pre-scaler of 256 producing CPU_F of… 500Hz! Which should work as ATTINY85 is completely static in operation so does not lose its state if the clocks are stopped! But setting the 128KHz internal clock source affects alll code including bootstrap firmware as it's enabled using fuses.

Leave a Reply to Alex