Clocks and timers


  • Same routine: power up, configure
  • As before, I'll point you to the documentation
  • APB1 Clock: 8 MHz
  • Configuration: one shot, autoreload, prescaler
  • Introduce: busy waiting while ! {}
  • Re-implement delay::ms

In this section, we'll re-implement the LED roulette application. I'm going to give you back the led module but this time I'm going to take away the delay module :-).

Here's the starter code. The delay function is unimplemented so if you run this program the LEDs will blink so fast that they'll appear to always be on.


extern crate pg;

use core::iter;

use pg::led::LEDS;
use pg::peripheral;

fn delay(ms: u16) {
    // TODO implement this

pub fn main() -> ! {
    unsafe {
        let rcc = peripheral::rcc_mut();
        let tim7 = peripheral::tim7_mut();

    // TODO initialize TIM7

    loop {
        for (current, next) in LEDS.iter()
            .zip(LEDS.iter().skip(1).chain(iter::once(&LEDS[0]))) {

Functional description:

  • The timer is enabled
  • A counter register increments its value on each "tick"
  • When the counter reaches the value held in the auto-reload register, it will reset back to zero and generate an update event.

The timer can operate in two modes:

  • Continuous mode: After an update event, the timer will start counting again.
  • One pulse mode: After an update event, the timer will stop.

How long does this "tick" last? That's determined by the APB1 clock and the counter and prescaler settings.

TIM6/TIM7 registers - Section 22.4 - Page 681 - Reference Manual.

Initialization is as usual: power up the peripheral then configure it.

  • Use TIM7EN in RCC::APB1ENR to power up the peripheral.
  • TIM7::CR1, the configuration register.
  • TIM7::PSC, the prescaler register.
  • TIM7::ARR, the auto-reload register.
  • TIM7::CNT, the counter register.
  • TIM7::SR, the status register, indicates if an update event has occurred.
  • TIM7::EGR, the event generation register. Can be used to generate an update. event.

The catch: the auto-reload register is buffered. When you write to it, it won't immediately change until the next update event. You can synthesize an update event using EGR.