LPC812 MAX Experiment: Digital Out
Experiment: Control a LED
In this first experiment you will learn how to control the I/O pins of the LPC8xx microcontroller. More specifically you will learn how to control a LED.
Hardware
This lab uses only the onboard RGB LED so no external components are needed.
1) Description
The schematics tells us that the RGB LED is connected to the following pins:
- PIO0_16 to the BLUE LED
- PIO0_17 to the GREEN LED
- PIO0_7 to the RED LED
The pins are specified in the mbed library with the actual pin names as well as some useful aliases:
| Pin Name | mbed Standard Alias | LPC812 Specific Alias |
|---|---|---|
| P0_16 | LED1 | LED_BLUE |
| P0_17 | LED2 | LED_GREEN |
| P0_7 | LED3 | LED_RED |
The mbed library has a DigitalOut class to simplify using the GPIOs:
Import library
Public Member Functions |
|
| DigitalOut (PinName pin) | |
|
Create a
DigitalOut
connected to the specified pin.
|
|
| void | write (int value) |
|
Set the output, specified as 0 or 1 (int)
|
|
| int | read () |
|
Return the output setting, represented as 0 or 1 (int)
|
|
| DigitalOut & | operator= (int value) |
|
A shorthand for
write()
|
|
| operator int () | |
|
A shorthand for
read()
|
|
All three LEDs are active low meaning that they will turn on when the respective LPC812 pin is low. The example below demonstrates how to use the different alias to create instances of DigitalOut to blink the LEDs.
main.cpp
#include "mbed.h"
DigitalOut myled1(P0_16);
DigitalOut myled2(LED2);
DigitalOut myled3(LED_RED);
int main() {
//Turn all LEDs off
myled1 = 1; //LED1 is active low, turn it off
myled2 = 1; //LED2 is active low, turn it off
myled3 = 1; //LED3 is active low, turn it off
//Enter forever loop
while(1) {
myled3 = 1; //Turn LED3 off
myled1 = 0; //Turn LED1 on
wait(0.2); //Wait 200 ms
myled1 = 1; //Turn LED1 off
myled2 = 0; //Turn LED2 on
wait(0.2); //Wait 200 ms
myled2 = 1; //Turn LED2 off
myled3 = 0; //Turn LED3 on
wait(0.2); //Wait 200 ms
}
}
Setting the DigitalOut to 0 to turn the LED on might be confusing and it is not good practice to keep writing comments on all lines in the program just to keep track of the LEDs. An alternative might be to create an LED class like this:
LED.h
#ifndef LED_H
#define LED_H
class LED {
public:
enum ActiveLevel {
ActiveHigh = 0,
ActiveLow = 1
};
/** Create a LED controller
*
*/
LED(PinName pin, ActiveLevel level);
/** Turn the LED on
*/
void on();
/** Turn the LED off
*/
void off();
/** Turn the LED on/off.
*
* @param turnOn Turns the LED on if true, off if false
*/
void setState(bool turnOn);
private:
DigitalOut _out;
ActiveLevel _level;
};
#endif
LED.cpp
#include "mbed.h"
#include "LED.h"
LED::LED(PinName pin, ActiveLevel level) : _out(pin), _level(level)
{
off();
}
void LED::on()
{
if (_level == ActiveHigh) {
_out = 1;
} else {
_out = 0;
}
}
void LED::off()
{
if (_level == ActiveHigh) {
_out = 0;
} else {
_out = 1;
}
}
void LED::setState(bool turnOn)
{
if (turnOn) {
on();
} else {
off();
}
}
With the new LED class and better variable names the code looks much cleaner:
main.cpp
#include "mbed.h"
#include "LED.h"
LED blueLED(P0_16, LED::ActiveLow);
LED greenLED(LED2, LED::ActiveLow);
LED redLED(LED_RED, LED::ActiveLow);
int main() {
//Turn all LEDs off
blueLED.off();
greenLED.off();
redLED.off();
//Enter forever loop
while(1) {
redLED.off();
blueLED.on();
wait(0.2); //Wait 200 ms
blueLED.off();
greenLED.on();
wait(0.2); //Wait 200 ms
greenLED.off();
redLED.on();
wait(0.2); //Wait 200 ms
}
}
2) Description
The programs in the previous step were controlled by delays. There are more sophisticated ways to control the LED flashing, for example by using the mbed ticker functionality. More information can be found here. The ticker functionality is a prime example of the powerful mbed framework. Advanced functionality can quickly be incorporated into your application by just instantiating an object.
Test the code below and experiment with different flash patterns.
main.cpp
#include "mbed.h"
#include "LED.h"
Ticker tickObject;
LED blueLED(P0_16, LED::ActiveLow);
LED greenLED(LED2, LED::ActiveLow);
LED redLED(LED_RED, LED::ActiveLow);
void flashHandler(void) {
static int ledState = 0;
//Turn all LEDs off
blueLED.off();
greenLED.off();
redLED.off();
switch (ledState) {
case 0: blueLED.on(); break;
case 1: greenLED.on(); break;
case 2: redLED.on(); break;
default: ledState = 0;
}
ledState++;
if (ledState >= 3)
ledState = 0;
}
int main() {
//Turn all LEDs off
blueLED.off();
greenLED.off();
redLED.off();
//Repeatedly call flashHandler(), once every 200ms
tickObject.attach(&flashHandler, 0.2);
//Enter forever loop
while(1) {
; //do something useful while LED flashing is handled in the background
}
}
There is also a timeout functionality that can be used, for example if varying time intervals are needed between calling flashHandler(). The timeout must then be restarted after every call to flashHandler().
Please log in to post comments.
