Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Mbed in A Nutshell: Hardware Platform: Freescale KL25Z With Mbed Toolchain

Download as pdf or txt
Download as pdf or txt
You are on page 1of 6

Mbed in a Nutshell

From Interactive Device Design Fall 2014

Contents
1 Hardware Platform: Freescale KL25Z with mbed toolchain
1.1 Why don't we use Arduino?
2 Conceptual Overview
2.1 Overview: Writing Code for mbed
2.2 How to program your board
3 Pin Names
4 Code Examples
4.1 Hello World: Blinking an LED
4.2 Input: Read a Button to toggle an LED
4.3 Connect an external LED
4.4 Running without a Computer
4.5 Serial Communication with a Computer
4.5.1 OS X Terminal Configuration
4.5.2 Windows Terminal Configuration
4.6 Fading an LED by reading an analog voltage
5 Authoritative Data Sheets and Manuals for KL25Z
6 References

Hardware Platform: Freescale KL25Z with mbed toolchain


This semester, we will use 32-bit ARM Cortex microcontrollers for your homeworks and class project. These microcontrollers are very powerful and cheap. They can be
found in a large number of consumer devices - so the technology you use in class could directly translate into a commercial project.

In particular, we will start working with the Freescale FRDM KL25Z board (http://mbed.org/platforms/KL25Z/), which uses a chip based on the ARM Cortex-M0+
architecture. This board runs at 48MHz, has 128kB of Flash storage for code, 16kB of RAM for variables. It also has an on-board tri-color LED, a 3-axis accelerometer, and
a capacitive touch slider. At the time of writing, the board retails for $13, e.g., from Mouser (http://www.mouser.com/ProductDetail/Freescale-Semiconductor/FRDM-
KL25Z/). Just the microcontrollers themselves in this family cost about $1-$4 in low quantities, depending on speed and memory. Later in the semester you may want to
switch to other ARM platforms (e.g., to get a smaller board, coin cell battery operation, or Bluetooth / WiFi networking) - this should be relatively easy, as a number of
different boards are can run your mbed code (http://mbed.org/platforms).

Why don't we use Arduino?

Arduino is a fantastic learning platform, and we've used it in past offerings of this course. However, projects can quickly reach the memory and compute limits of what this
8-bit platform can support. Also, for price and performance reasons, the 8-bit Atmel AVR architecture is not generally used for production. We hope that mbed strikes a
balance between being easy to program on one hand, and "future proof" in case you want to commercialize your idea on the other hand. Arduino is also moving into the
direction of offering ARM chips (with the Due and Zero, and the 3rd party Teensy 3), so it may be a good platform for this course again in the future.

Conceptual Overview

Overview: Writing Code for mbed

To program the board, we'll use the mbed online IDE (http://mbed.org). This is a browser-based code editor and server-hosted compiler. The main benefit of this approach is
that it is OS-agnostic (Win,OSX,Linux) since you don't have to install any toolchains on your local computer (only potentially a driver on Windows). You will write code in
C++. Your code will use the mbed SDK (http://mbed.org/handbook/mbed-SDK), a standard set of libraries that make working with the board's features easy. Many users
have contributed C++ libraries for common sensors and other external components that you can use.

One downside of the online IDE is that it does not have an integrated debugger. Simple code can often be debugged with printf() statements. If your code gets very complex,
you can also install a regular embedded IDE on your computer. The main advantage of an "offline" IDE is breakpoint debugging. However, the setup of the toolchain can be
complex initially, and very few support OSX or Linux. You may find time-limited trial versions or free versions that limit code size and other features, like Keil uVision[1]
or IAR Embedded Workbench[2]. For OSX/Linux there is the open source gcc-arm toolchain (https://launchpad.net/gcc-arm-embedded/4.7/4.7-2012-q4-major). See
Exporting to Offline Toolchains (https://mbed.org/handbook/Exporting-to-offline-toolchains) in the mbed handbook.

How to program your board


The steps below are roughly the same for all mbed-compatible hardware platforms (http://mbed.org/platforms/).

Connect a USB cable to your computer and to the USB port on the KL25Z. Use the port labeled "SDA" on top and "OpenSDA" on the bottom (SDA stands for "serial
and debug adapter").
The board shows up as a mass storage device (like a USB flash drive) called MBED on your computer, containing one file: mbed.htm. Double-click this file to launch
the online IDE (or go directly to mbed.org/compiler (http://mbed.org/compiler)).
Write your code and compile in the online IDE in your browser. Compilation generates a binary .bin file, which your browser should automatically download.
Drag and drop this .bin file from your Download directory onto the MBED drive to transfer and load the program.
Press the reset button to start running your code.

Pin Names
To access pins and to send messages to a connected computer or other attached devices, your code will have to refer to specific pin names. The KL25Z is a powerful
platform with a large number of pins, each of which can be configured to take on a number of different functions. To keep things simple initially, we'll start by using the
outer row of pin headers, which have the same physical layout and names as pins found on the Arduino Uno:

Note that many pins have aliases - the same pin can be referred to by multiple names. For example. USBTX and D0 refer to the same pin; and LED1 and LED_RED refer to
the same pin as well. These aliases only serve as syntactic sugar to make remembering meaningful names a bit easier. Each pin also has a "port name" like PTC4 (port C, pin
4) which are linked to the physical location of a pin on the microcontroller itself. You may find these longer port names in code examples. Since they don't neatly correspond
to the position on the external connectors, we'll use the simpler labeling above for the examples in this document.

The full set of Pin names and functions is here: http://mbed.org/platforms/KL25Z/

Code Examples

Hello World: Blinking an LED

The standard "Hello World" program in embedded computing just blinks an LED. Here's the MBED version that blinks the red onboard LED (also on the mbed website
(https://mbed.org/users/simon/code/HelloWorld/docs/03c191369089/main_8cpp_source.html)):

#include "mbed.h"

DigitalOut myled(LED1);

int main() {
while(1) {
myled = 1;
wait(0.2);
myled = 0;
wait(0.2);
}
}

In case this code is not self-explanatory:

Line 1: All mbed programs must include the mbed.h header file.
Line 3: Creates a variable named myled of type DigitalOut. Passes the pre-defined pin name LED1 as an argument to the DigitalOut constructor. (Each mbed platform
has a set of these pre-defined pin names in a file called PinNames.h)
Here is PinNames.h for the KL25Z
(https://mbed.org/users/mbed_official/code/mbed/docs/6213f644d804/TARGET__KL25Z_2TARGET__Freescale_2TARGET__KLXX_2TARGET__KL25Z_2PinName
DigitalOut documentation: Handbook page (https://mbed.org/handbook/DigitalOut) (not very helpful), Class reference
(https://mbed.org/users/mbed_official/code/mbed/docs/tip/classmbed_1_1DigitalOut.html) (comprehensive)
Line 5: The function main() is the default entry point for all mbed programs.
Line 6: while(1) loops forever - It is typical for embedded programs to first do some one-time initialization (as in line 3) and then enter an infinite run-loop.
Line 7-10: The pin connected to LED1 is first toggled HIGH for 200ms, then LOW for 200ms.

Exercise: Pins can either source current or sink current - so sending a pin HIGH could either turn the LED on or off. Determine which of these options is the case on the
KL25Z.

Input: Read a Button to toggle an LED

Next, we will use basic binary input: we'll toggle an LED based on the state of a button. The GPIO (general purpose input/output) pins D0 to D15 can be configured as either
inputs or outputs. There are many other pins on the KL25Z that can also be used in this way (66 to be precise), but let's start with D0-D15. As the pin diagram above shows,
D0 and D1 are also often used to send serial messages to a PC. Since you'll want to do this frequently (e.g., for debugging) it is a good idea to not use these pins for other
input or output.

We'll connect a button to the next free pin, D2 (also called PTD4 in the diagram below). The code then sets the LED state to the current state of the button. The momentary
button is "normally open" which means there is no connection between its terminals when the button is not pressed; and the connection is closed when the button is pressed.

We use the internal pull-up function of the pin, which connects an internal resistor (20-50KOhm[3]) between the pin and the supply voltage (3.3V). This mean the pin is
"pulled up" to 3.3V by default. When the button is pressed, a connection between the pin and GND is made and the pin is pulled to 0V.

#include "mbed.h"

DigitalOut myled(LED_RED);
DigitalIn button(D2);
// SPST Pushbutton demo using internal PullUp function
// no external PullUp resistor needed
// Pushbutton from D2 to GND.
int main() {
button.mode(PullUp);
while(1) {
myled = button;
}
}

Source (discusses many other useful topics like debouncing and interrupts): https://mbed.org/users/4180_1/notebook/pushbuttons/

Class reference for DigitalIn (https://mbed.org/users/mbed_official/code/mbed/docs/tip/classmbed_1_1DigitalIn.html)

Exercise: If 1 is HIGH (3.3V) and 0 is LOW (0V), what is the value of the variable button when the button is not pressed, and when it is pressed? Check whether this is in
line with your expectation about the way the LED is connected in the previous example

Connect an external LED

To safely connect external components, we first have to consider their electrical characteristics.

As with many other low-power ARM chips, the KL25Z can only provide (source) or sink a very limited amount of current: up to 5 mA per pin [4]; and no more than 100mA
across all pins at a time[5]. Maximum instantaneous per pin ratings are 20mA[6]. If you source or sink more current than 5mA continuously or 20mA instantaneously, you
will damage the board.
Let's look at a particular LED: Avago HLMP-4700[7]. The Datasheet shows a typical forward voltage of 1.7V (max forward voltage: 2.0V), and a typical current
consumption of 2mA (up to 10mA ok). Note that these are Low Current LEDs. If you grab a random LED in the lab, it's more likely that it'll have a forward voltage (drop)
of 2V, but a standard current of 20mA. You cannot source 20mA from this processor and would need a driver circuit, which we'll introduce later.

We need to drop (3.3V-1.7V = 1.6V) at a current of 2-4mA. According to Ohm's law, R= U/I = 1.6V / 2mA = 800 Ohm. At twice the current, we'd be at 400 Ohm. A 470
Ohm resistor seems a decent in-between choice.

The code here is identical to our initial "Hello World" program, except that we are now using a different pin, connected to the external LED.

#include "mbed.h"

DigitalOut myled(D3);
//hook up low-current LED (Avago HMP-4700) to D3
//and 470 Ohm resistor from LED to GND

int main() {
while(1) {
myled = 1;
wait(0.2);
myled = 0;
wait(0.2);
}
}

Running without a Computer

When the KL25Z is connected via USB to a computer, it draws power from the computer's USB port. You can also run the KL25Z in stand-alone mode in two ways:

Use a USB AC adapter (e.g. your phone's charger) or a battery pack with 5V USB output (e.g., Sparkfun 1800mAh Battery Pack
(https://www.sparkfun.com/products/11359)) in place of your laptop and continue to power through the USB cable
Use a battery (4.5V to 9V) and connect it to the VIn pin

It may also be possible to power the board directly at 3.3V, e.g. with a rechargeable LiPo battery and a low-drop-out 3.3V regulator. Someone should try this.

Serial Communication with a Computer

The KL25Z has three different hardware UARTs for serial communication. (A UART is a piece of hardware that makes buffering, transmitting and receiving messages over
serial lines easy). One of them, at pins USBTX and USBRX (D0 and D1, respectively) is connected on the board to the serial and debug adapter, which in turn makes it
available to a connected computer as a USB Serial port. On OS X, this works out of the box. On Windows, you'll have to install a com port driver - see the mbed PC
configuration (https://mbed.org/platforms/KL25Z/#pc-configuration) section.

Here is the serial template code available in the online IDE when starting a new project. It just opens a port and counts up, sending each number along the way, and toggling
an onboard LED to show progress:

#include "mbed.h"

DigitalOut myled(LED_GREEN);
Serial pc(USBTX, USBRX);

int main()
{
int i = 0;
pc.printf("Hello World!\n");

while (true) {
wait(0.5f); // wait a small period of time
pc.printf("%d \n", i); // print the value of variable i
i++; // increment the variable
myled = !myled; // toggle a led
}
}

Some explanations:

Line 4: defines a variable named pc of type Serial, passing USBTX and USBRX pin references into the constructor. According to the Serial class reference
(http://mbed.org/users/mbed_official/code/mbed/docs/tip/classmbed_1_1Serial.html) documentation, the default speed is 9600 baud.
Line 9: the Serial class is a sub-class of the Stream class (https://mbed.org/users/mbed_official/code/mbed/docs/tip/Stream_8h_source.html), which offers character
and string emitting functions like putc() and printf()

To configure and see the serial port messages on the computer, refer to https://mbed.org/handbook/SerialPC .

OS X Terminal Configuration

On OS X, when this program runs, you can either use the built in screenprogram or a dedicated terminal program like CoolTerm (http://freeware.the-meiers.org/) to see the
output. Your serial port name will be /dev/tty.usbmodemWXYZ where WXYZ is a unique number. Execute ls /dev/tty.usbmodem*with and without the KL25Z plugged in
to determine the name on your system.

Once you have that name, run the following command line: screen /dev/tty.usbmodemWXYZ 9600(substituting the correct name and changing the speed if necessary)

Use Control-A followed by Control-\ to exit your screen session.

Windows Terminal Configuration

Fading an LED by reading an analog voltage

This last example covers two concepts: analog input, and pulse width modulation output. Many sensors output a continuous parameter in the form of a changing resistance or
a changing voltage. You read analog voltages with an Analog-to-Digital Converter (ADC). The pins A0 through A5 are all connected to ADCs. You can convert a changing
resistance to a voltage by means of a voltage divider (http://en.wikipedia.org/wiki/Voltage_divider). A potentiometer is one example of a voltage divider in which a wiper
moves over a resistive track. By varying the amount of resistive distance between the voltage supply and the wiper on one side; and the wiper and ground on the other side,
the corresponding voltage at the wiper changes.

(Other sensors communicate digitally through a particular messaging protocol like SPI or I2C -- we'll cover those later).

In code, use class AnalogIn (reference (https://mbed.org/users/mbed_official/code/mbed/docs/tip/classmbed_1_1AnalogIn.html)). A voltage between 0V and 3.3V is mapped
into the float interval from 0.0 to 1.0.

The KL25Z has only one true AnalogOut pin (suitable, for example, for generating audio output). However, for many purposes, it is sufficient to approximate analog output
by quickly and cyclically switching a digital pin on and off. This technique is called pulse width modulation (PWM). The pins D0 to D15 all support PWM. By changing the
duty cycle (the amount of time the pin is on vs off throughout one time period), we can for example create the perception of dimming an LED. PWM also applies to
positioning servo motors, controlling motor speed, etc.

Code example for reading a slider to dim an LED with PWM:

#include "mbed.h"
AnalogIn slider(A0);
PwmOut led(LED1);

int main() {
led.period(0.001);
while(1) {
led=(float)(slider);
wait(0.01);//wait 1ms - for a number of cycles to have taken place
}
}

Line 2: we'll read analog voltage from pin A0.


Line 3: we'll output PWM on the built-in LED1 (the red LED).
Line 6: (optional) sets the period (cycle time) of the PWM pin to 1 millisecond
Line 8: the "=" operator is shorthand for led.write(float value), which expects a value between 0.0 and 1.0.
Line 8: the (float) operator is shorthand for slider.read() which returns the voltage as a ratio between 0.0 and 1.0
Line 9: because our main loop is executing much faster than a PWM period, wait a while to make sure a few cycles have happened before changing the PWM value.

Authoritative Data Sheets and Manuals for KL25Z

Follow-on Reading: Fast and Effective Embedded Systems Design[8]


KL25 Sub-Family Data Sheet: Technical Data (http://cache.freescale.com/files/32bit/doc/data_sheet/KL25P80M48SF0.pdf?fasp=1) ( Local copy
KL25 Sub-Family Reference Manual (http://cache.freescale.com/files/32bit/doc/ref_manual/KL25P80M48SF0RM.pdf)

References

1. Download the Keil MDK-ARM v5; free version is limited to 32kB code and is Windows only. https://www.keil.com/demo/eval/arm.htm
2. The "Kickstart" version is limited to 16 Kbyte for Cortex-M0/M0+/M1 - http://www.iar.com/Products/IAR-Embedded-Workbench/ARM/
3. KL25 Data Sheet (http://cache.freescale.com/files/32bit/doc/data_sheet/KL25P80M48SF0.pdf?fasp=1), Page 8, RPU
4. KL 25 Data Sheet (http://cache.freescale.com/files/32bit/doc/data_sheet/KL25P80M48SF0.pdf?fasp=1), page 7, I_OH=5mA at 3.3V supply for "normal drive pads".
There are 4 "high drive pads" that can be configured to source/sink up to 18mA at 3.3V: "PTB0, PTB1, PTD6, and PTD7 I/O have both high drive and normal drive
capability selected by the associated PTx_PCRn[DSE] control bit. All other GPIOs are normal drive only."
5. Ibid., Page 7, I_OHT=100mA
6. Ibid. pg4, ID=-20mA to 20mA.
7. Digikey part 516-1325-ND (http://www.digikey.com/product-detail/en/HLMP-4700/516-1325-ND/637589), Datasheet (http://www.avagotech.com/docs/AV02-
1557EN))
8. Amazon: http://www.amazon.com/gp/product/B008EROBWE

Retrieved from "http://husk.eecs.berkeley.edu/courses/cs294-84-fall14/index.php?title=Mbed_in_a_Nutshell&oldid=119"

This page was last modified on 4 September 2014, at 01:31.


This page has been accessed 5,194 times.

You might also like