skip navigational linksPJRC
Shopping Cart Checkout Shipping Cost Download Website
Home MP3 Player 8051 Tools All Projects PJRC Store Site Map
You are here: Teensy How-To Tips Clock Speed

PJRC Store
Teensy 3.6, $29.25
Teensy 3.5, $24.25
Teensy 3.2, $19.80
Teensy LC, $11.65
Teensy 2.0, $16.00
Teensy++ 2.0, $24.00
Teensy
Main Page
Hardware
Getting Started
How-To Tips
Code Library
Projects
Teensyduino
Reference

Setting CPU Clock Speed

The information on this page applies only to Teensy 2.0 and Teensy++ 2.0.

For newer Teensy-LC, Teensy 3.0 and Teensy 3.1, use the Snooze library to access power saving features.

 

The first thing your C-based program should do is set the CPU to the correct speed. This speed should match the F_OSC variable in your Makefile.

Teensy defaults to only 2 MHz, for compatibility with lower voltage power supplies. To run at 16 MHz, you MUST set the speed. This setting affects the CPU and ALL periperals, except USB.

Symbol definitions

These macros make setting the clock prescaler easier.

#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
#define CPU_16MHz       0x00
#define CPU_8MHz        0x01
#define CPU_4MHz        0x02
#define CPU_2MHz        0x03
#define CPU_1MHz        0x04
#define CPU_500kHz      0x05
#define CPU_250kHz      0x06
#define CPU_125kHz      0x07
#define CPU_62kHz       0x08

Interrupts MUST be disabled while setting the speed.

Simplest Method

The easiest way is to just set the speed at the beginning of your program. Interrupt aren't enabled yet, so you don't need to worry about them.

int main(void)
{
    CPU_PRESCALE(CPU_16MHz);
    // rest of program

3.3 Volts = 8 MHz Maximum

If your Teensy is modified to run at 3.3 volts, 8 MHz is the maximum. Most Teensy boards will actually run at 16 MHz, at least a room temperature, but technically 16 MHz at 3.3 volts is overclocking. Setting to 8 MHz is safe.

int main(void)
{
    CPU_PRESCALE(CPU_8MHz); // 3.3 volt compatible
    // rest of program

Slowly Starting Power Supplies

When Teensy is used with a power supply that features a "soft start", you may need wait for the voltage to reach 5 volts before switching to 16 MHz. This is easy, but remember the "_delay_ms()" function works with F_OSC, so it will delay longer.

int main(void)
{
    CPU_PRESCALE(CPU_125kHz);  // power supply still ramping up voltage
    _delay_ms(1);              // actual delay 128 ms when F_OSC is 16000000
    CPU_PRESCALE(CPU_16MHz);
    // rest of program

Running Slow To Save Power

You can save power by switching to a slower speed when the full 16 MHz isn't needed. Placing the CPU into an idle or sleep mode also helps. The idle mode, where the CPU is stopped but peripherals keep running, saves a lot of power when used together with reduced clock speed.

However, all peripherals except USB depend on the clock prescaler. If you are using timers to generate waveforms, those outputs will slow down. If the UART is being used, the baud rate will change. Saving power with clock speed changes while peripherals are in use requires careful attention to configurations.

Here is a simple example of waiting for pushbuttons, using a slow clock.

char wait_pushbutton_press(void)
{
    char retval=0;

    cli();
    CPU_PRESCALE(CPU_125kHz);
    sei();
    // pushbuttons connected to PC0, PC1, PC2
    // those pins configured as input with pullup
    while (1) {
        if ((PINC & 1) == 0) {
            retval = 1;
            break;
        }
        if ((PINC & 2) == 0) {
            retval = 2;
            break;
        }
        if ((PINC & 4) == 0) {
            retval = 3;
            break;
        }
    }
    cli();
    CPU_PRESCALE(CPU_16MHz);
    sei();
    return retval;
}

If interrupts may occur, they will run at the slow clock. If that is an issue, code can be added to switch the clock back to 16 MHz. Switching speeds while your program is running can add a number of complex issues, but it can also dramatically reduce power consumption, especially when USB is not in use and idle mode is used.