Learning the Teensy LC: Manual PWM


I’m in the process of learning how to use the Teensy LC, which is the newest Arduino-compatible module from PJRC. It is built around the MKL26Z64VFT4 (ARM Cortex-M0+), which can be had for around $2.20 for 100 (according to Digi-Key). I really like the microcontroller, as it is much more powerful than the ubiquitous ATmega 328p (not that I don’t like the 328p) for about the same price.

The awesome people at PJRC have gone through the process of creating a set of libraries and hardware definitions so that you can program the entire Teensy line from Arduino. It is quite slick, and if you have not tried it yet, I suggest you give it a shot. It does require installing some software on top of the Arduino IDE, but it opens up the world of ARM to Arduino users.

Because I have decided to use the Teensy LC (or, more specifically, the MKL26Z64VFT4) for a personal project, I wanted to learn how to manually set up interrupts. As it turns out, ARM interrupts are more complicated than the interrupts found in most ATmega processors. More importantly, I wanted to learn how to do this from the Arduino IDE (because reasons). PJRC still has many of the labels for registers and bit fields set to the Teensy 3.1, which work well enough for the Teensy LC, but might not be correct.

To get the example code to work, attach an LED (with a limiting resistor, of course) to pin 6 of the Teensy LC, and upload the code from the Teensyduino IDE. There is definitely a better way of doing this (using labels for bit fields instead of hardcoded values, for example), but this was a learning exercise on how to appropriately set the timer registers.

The program sets up a hardware PWM on pin 6 of the Teensy LC and then does nothing in the while loop. In essence, I’m doing analogWrite() the hard way.

[Edit 05/24/15] It looks like I was setting FTM0_C4SC incorrectly. As per the notes on p. 575 of the datasheet, you need to set it to 0 first (“channel must first be disabled”). We add a magical delay (1 microsecond) to allow the register to be set to 0 before writing the value. Additionally, the edge bits were wrong. They should have been 0b10 to have the PWM value set on timer reset and clear on value match. These changes have been reflected below.


Leave a Reply