Lib for the LCD display on mbed lab Board

Dependents:   SprintUSBModemWebsocketTest-LCD-RO iOSAppChat Christmas-LCD led_dimm ... more

Basic information

The LCD on the mbed lab board has 128 x 32 pixels and is connected via spi. It use a ST7565R controller. The spi connection is fast, but it has one drawback - you can't read the display buffer. This is a problem, because each bit reflect a pixel. If you want to set only one bit / pixel, you have to know the status of the other seven bits / pixel. Because of this we have to use a framebuffer (128 * 32 / 8 = 512 Byte). All drawing functions are working on this framebuffer. If you use the LPC1768 based mbed, the dma channel 0 is used to speed up the transfer to the lcd. This information is only relevant if you also want to use the dma controller. You have to switch to a other channel.

There are two update mode. After startup the automode is turned on. This means that the display is automaticly updated after the drawing. For example - if you call the function

lcd.line(x0, y0, x1, y1, 1);

a line from x0,y0 to x1,y1 is drawn inside the framebuffer and after that the framebuffer is copied to the lcd. If you draw more lines, it will be faster to draw all graphics inside the framebuffer and update the lcd only once. To do so, you can use the function :

lcd.set_auto_up(0);

This switch off the autoupdate. If you want to see it, you have to refresh the lcd by calling the function :

lcd.copy_to_lcd();

lcd.set_auto_up(1);

will switch back to auto update mode.

Basic functions

To use the lcd we have to create a lcd object :

C12832_LCD lcd;

There are two drawing modes : NORMAL and XOR. At startup the mode is NORMAL. If you use

lcd.setmode(XOR);

you switch to XOR mode. In this mode a pixel in the frambuffer is inverted if you set it to 1.

lcd.setmode(NORMAL);

switch back to normal mode.

The function :

lcd.invert(1);

will invert the lcd. This is done by the lcd controller. The framebuffer is not changed.

lcd.invert(0);

will switch back.

The function :

lcd.cls();

clear the screen.

The function :

lcd.set_contrast(25);

will set the contrast. The lib start with 23. A value between 10 and 35 will be visible.

Text

To print text you simply have to use the printf function. The output of the stdout is redirected to the lcd.

lcd.printf("temperature : %3.2f F",heat);

The position can be set up with the function :

lcd.locate(x,y);

At startup a 7 pixel font is used. If you want to use a different font you can include the lib http://mbed.org/users/dreschpe/code/LCD_fonts. This lib include four additional fonts. From 6 pixel to 23 pixel. To switch the font use :

lcd.set_font((unsigned char*) Arial_9);

The names of the fonts are : Small_6, Small_7, Arial_9, Arial12x12 and Arial24x23.

The function :

lcd._putc(c);

print the char c on the actual cursor position.

The function :

lcd.character(x, y, c);

print the char c at position x,y.

Graphic

The function :

lcd.line(x0, y0, x1, y1, color);

draw a single pixel line from x0,y0 to x1,y1. If color is 1 : black, 0 : white.

The function :

lcd.rect(x0, y0, x1, y1, color);

draw a single pixel rectangle from x0, y0 to x1, y1. If color is 1 : black, 0 : white.

The function :

lcd.fillrect(x0, y0, x1, y1, color);

draw a filled rectangle from x0, y0 to x1, y1. If color is 1 : black, 0 : white.

The function :

lcd.circle(x, y, r, color);

draw a circle with x,y center and radius r. If color is 1 : black, 0 : white.

The function :

lcd.fillcircle(x, y, r, color);

draw a filled circle with x,y center and radius r. If color is 1 : black, 0 : white.

The function :

lcd.pixel(x, y, color);

set a single pixel at x,y. If color is 1 : black, 0 : white. This function is not updating the lcd ! Even if the autoupdate is on. You have to call lcd.copy_to_lcd() after using this function - or to use a other function with autoupdate afterwards.

mbed rtos

To use the mbed rtos with the lib we have to make the lib thread save. What is the problem ? If different threads are writing to the lcd it can end in troubble. Thread1 is using the pintf("hello mbed") function to print this string to the actual position. After the chars "hel" are printed ,the scheduler is switching to thread2. This thread is writing at a different position on the screen. After that the scheduler is switch back to thread1 and the print function continue. Thread1 did not know that the internal cursor position has changed ....

To protect the access to the lcd we use a Mutex. If a thread has the mutex and a other thread also want it, the second thread has to wait.

Mutex lcd_mutex;  // define the mutex
    //...
lcd_mutex.lock(); // get the mutex or wait

//acccess to the lcd
 
lcd_mutex.unlock(); // free the mutex 

We use this framing to access the lcd.

Test program to show : http://mbed.org/users/dreschpe/code/lab1/

Committer:
sam_grove
Date:
Sun Oct 27 23:16:07 2013 +0000
Revision:
10:8f86576007d6
Parent:
0:4bbc531be6e2
Don't claim stdout by default. Make the user of the library do that.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dreschpe 0:4bbc531be6e2 1 /* mbed GraphicsDisplay Display Library Base Class
dreschpe 0:4bbc531be6e2 2 * Copyright (c) 2007-2009 sford
dreschpe 0:4bbc531be6e2 3 * Released under the MIT License: http://mbed.org/license/mit
dreschpe 0:4bbc531be6e2 4 */
dreschpe 0:4bbc531be6e2 5
dreschpe 0:4bbc531be6e2 6 #include "GraphicsDisplay.h"
dreschpe 0:4bbc531be6e2 7
dreschpe 0:4bbc531be6e2 8 const unsigned char FONT8x8[97][8] = {
dreschpe 0:4bbc531be6e2 9 0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00, // columns, rows, num_bytes_per_char
dreschpe 0:4bbc531be6e2 10 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // space 0x20
dreschpe 0:4bbc531be6e2 11 0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00, // !
dreschpe 0:4bbc531be6e2 12 0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00, // "
dreschpe 0:4bbc531be6e2 13 0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00, // #
dreschpe 0:4bbc531be6e2 14 0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00, // $
dreschpe 0:4bbc531be6e2 15 0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00, // %
dreschpe 0:4bbc531be6e2 16 0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00, // &
dreschpe 0:4bbc531be6e2 17 0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00, // '
dreschpe 0:4bbc531be6e2 18 0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00, // (
dreschpe 0:4bbc531be6e2 19 0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00, // )
dreschpe 0:4bbc531be6e2 20 0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00, // *
dreschpe 0:4bbc531be6e2 21 0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00, // +
dreschpe 0:4bbc531be6e2 22 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30, // ,
dreschpe 0:4bbc531be6e2 23 0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00, // -
dreschpe 0:4bbc531be6e2 24 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00, // .
dreschpe 0:4bbc531be6e2 25 0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00, // / (forward slash)
dreschpe 0:4bbc531be6e2 26 0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00, // 0 0x30
dreschpe 0:4bbc531be6e2 27 0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00, // 1
dreschpe 0:4bbc531be6e2 28 0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00, // 2
dreschpe 0:4bbc531be6e2 29 0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00, // 3
dreschpe 0:4bbc531be6e2 30 0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00, // 4
dreschpe 0:4bbc531be6e2 31 0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00, // 5
dreschpe 0:4bbc531be6e2 32 0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00, // 6
dreschpe 0:4bbc531be6e2 33 0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00, // 7
dreschpe 0:4bbc531be6e2 34 0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00, // 8
dreschpe 0:4bbc531be6e2 35 0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00, // 9
dreschpe 0:4bbc531be6e2 36 0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00, // :
dreschpe 0:4bbc531be6e2 37 0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30, // ;
dreschpe 0:4bbc531be6e2 38 0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00, // <
dreschpe 0:4bbc531be6e2 39 0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00, // =
dreschpe 0:4bbc531be6e2 40 0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00, // >
dreschpe 0:4bbc531be6e2 41 0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00, // ?
dreschpe 0:4bbc531be6e2 42 0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00, // @ 0x40
dreschpe 0:4bbc531be6e2 43 0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00, // A
dreschpe 0:4bbc531be6e2 44 0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00, // B
dreschpe 0:4bbc531be6e2 45 0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00, // C
dreschpe 0:4bbc531be6e2 46 0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00, // D
dreschpe 0:4bbc531be6e2 47 0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00, // E
dreschpe 0:4bbc531be6e2 48 0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00, // F
dreschpe 0:4bbc531be6e2 49 0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00, // G
dreschpe 0:4bbc531be6e2 50 0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00, // H
dreschpe 0:4bbc531be6e2 51 0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // I
dreschpe 0:4bbc531be6e2 52 0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00, // J
dreschpe 0:4bbc531be6e2 53 0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00, // K
dreschpe 0:4bbc531be6e2 54 0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00, // L
dreschpe 0:4bbc531be6e2 55 0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00, // M
dreschpe 0:4bbc531be6e2 56 0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00, // N
dreschpe 0:4bbc531be6e2 57 0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00, // O
dreschpe 0:4bbc531be6e2 58 0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00, // P 0x50
dreschpe 0:4bbc531be6e2 59 0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00, // Q
dreschpe 0:4bbc531be6e2 60 0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00, // R
dreschpe 0:4bbc531be6e2 61 0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00, // S
dreschpe 0:4bbc531be6e2 62 0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00, // T
dreschpe 0:4bbc531be6e2 63 0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00, // U
dreschpe 0:4bbc531be6e2 64 0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00, // V
dreschpe 0:4bbc531be6e2 65 0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00, // W
dreschpe 0:4bbc531be6e2 66 0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00, // X
dreschpe 0:4bbc531be6e2 67 0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00, // Y
dreschpe 0:4bbc531be6e2 68 0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00, // Z
dreschpe 0:4bbc531be6e2 69 0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00, // [
dreschpe 0:4bbc531be6e2 70 0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00, // \ (back slash)
dreschpe 0:4bbc531be6e2 71 0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00, // ]
dreschpe 0:4bbc531be6e2 72 0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00, // ^
dreschpe 0:4bbc531be6e2 73 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF, // _
dreschpe 0:4bbc531be6e2 74 0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00, // ` 0x60
dreschpe 0:4bbc531be6e2 75 0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00, // a
dreschpe 0:4bbc531be6e2 76 0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00, // b
dreschpe 0:4bbc531be6e2 77 0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00, // c
dreschpe 0:4bbc531be6e2 78 0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00, // d
dreschpe 0:4bbc531be6e2 79 0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00, // e
dreschpe 0:4bbc531be6e2 80 0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00, // f
dreschpe 0:4bbc531be6e2 81 0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C, // g
dreschpe 0:4bbc531be6e2 82 0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00, // h
dreschpe 0:4bbc531be6e2 83 0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00, // i
dreschpe 0:4bbc531be6e2 84 0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C, // j
dreschpe 0:4bbc531be6e2 85 0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00, // k
dreschpe 0:4bbc531be6e2 86 0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // l
dreschpe 0:4bbc531be6e2 87 0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00, // m
dreschpe 0:4bbc531be6e2 88 0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00, // n
dreschpe 0:4bbc531be6e2 89 0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00, // o
dreschpe 0:4bbc531be6e2 90 0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78, // p
dreschpe 0:4bbc531be6e2 91 0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F, // q
dreschpe 0:4bbc531be6e2 92 0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00, // r
dreschpe 0:4bbc531be6e2 93 0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00, // s
dreschpe 0:4bbc531be6e2 94 0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00, // t
dreschpe 0:4bbc531be6e2 95 0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00, // u
dreschpe 0:4bbc531be6e2 96 0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00, // v
dreschpe 0:4bbc531be6e2 97 0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00, // w
dreschpe 0:4bbc531be6e2 98 0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00, // x
dreschpe 0:4bbc531be6e2 99 0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C, // y
dreschpe 0:4bbc531be6e2 100 0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00, // z
dreschpe 0:4bbc531be6e2 101 0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00, // {
dreschpe 0:4bbc531be6e2 102 0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00, // |
dreschpe 0:4bbc531be6e2 103 0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00, // }
dreschpe 0:4bbc531be6e2 104 0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00, // ~
dreschpe 0:4bbc531be6e2 105 0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00}; // DEL
dreschpe 0:4bbc531be6e2 106
dreschpe 0:4bbc531be6e2 107 GraphicsDisplay::GraphicsDisplay(const char *name):TextDisplay(name) {
dreschpe 0:4bbc531be6e2 108 foreground(0xFFFF);
dreschpe 0:4bbc531be6e2 109 background(0x0000);
dreschpe 0:4bbc531be6e2 110 }
dreschpe 0:4bbc531be6e2 111
dreschpe 0:4bbc531be6e2 112 void GraphicsDisplay::character(int column, int row, int value) {
dreschpe 0:4bbc531be6e2 113 blitbit(column * 8, row * 8, 8, 8, (char*)&(FONT8x8[value - 0x1F][0]));
dreschpe 0:4bbc531be6e2 114 }
dreschpe 0:4bbc531be6e2 115
dreschpe 0:4bbc531be6e2 116 void GraphicsDisplay::window(int x, int y, int w, int h) {
dreschpe 0:4bbc531be6e2 117 // current pixel location
dreschpe 0:4bbc531be6e2 118 _x = x;
dreschpe 0:4bbc531be6e2 119 _y = y;
dreschpe 0:4bbc531be6e2 120 // window settings
dreschpe 0:4bbc531be6e2 121 _x1 = x;
dreschpe 0:4bbc531be6e2 122 _x2 = x + w - 1;
dreschpe 0:4bbc531be6e2 123 _y1 = y;
dreschpe 0:4bbc531be6e2 124 _y2 = y + h - 1;
dreschpe 0:4bbc531be6e2 125 }
dreschpe 0:4bbc531be6e2 126
dreschpe 0:4bbc531be6e2 127 void GraphicsDisplay::putp(int colour) {
dreschpe 0:4bbc531be6e2 128 // put pixel at current pixel location
dreschpe 0:4bbc531be6e2 129 pixel(_x, _y, colour);
dreschpe 0:4bbc531be6e2 130 // update pixel location based on window settings
dreschpe 0:4bbc531be6e2 131 _x++;
dreschpe 0:4bbc531be6e2 132 if(_x > _x2) {
dreschpe 0:4bbc531be6e2 133 _x = _x1;
dreschpe 0:4bbc531be6e2 134 _y++;
dreschpe 0:4bbc531be6e2 135 if(_y > _y2) {
dreschpe 0:4bbc531be6e2 136 _y = _y1;
dreschpe 0:4bbc531be6e2 137 }
dreschpe 0:4bbc531be6e2 138 }
dreschpe 0:4bbc531be6e2 139 }
dreschpe 0:4bbc531be6e2 140
dreschpe 0:4bbc531be6e2 141 void GraphicsDisplay::fill(int x, int y, int w, int h, int colour) {
dreschpe 0:4bbc531be6e2 142 window(x, y, w, h);
dreschpe 0:4bbc531be6e2 143 for(int i=0; i<w*h; i++) {
dreschpe 0:4bbc531be6e2 144 putp(colour);
dreschpe 0:4bbc531be6e2 145 }
dreschpe 0:4bbc531be6e2 146 }
dreschpe 0:4bbc531be6e2 147
dreschpe 0:4bbc531be6e2 148 void GraphicsDisplay::cls() {
dreschpe 0:4bbc531be6e2 149 fill(0, 0, width(), height(), _background);
dreschpe 0:4bbc531be6e2 150 }
dreschpe 0:4bbc531be6e2 151
dreschpe 0:4bbc531be6e2 152 void GraphicsDisplay::blit(int x, int y, int w, int h, const int *colour) {
dreschpe 0:4bbc531be6e2 153 window(x, y, w, h);
dreschpe 0:4bbc531be6e2 154 for(int i=0; i<w*h; i++) {
dreschpe 0:4bbc531be6e2 155 putp(colour[i]);
dreschpe 0:4bbc531be6e2 156 }
dreschpe 0:4bbc531be6e2 157 }
dreschpe 0:4bbc531be6e2 158
dreschpe 0:4bbc531be6e2 159 void GraphicsDisplay::blitbit(int x, int y, int w, int h, const char* colour) {
dreschpe 0:4bbc531be6e2 160 window(x, y, w, h);
dreschpe 0:4bbc531be6e2 161 for(int i = 0; i < w*h; i++) {
dreschpe 0:4bbc531be6e2 162 char byte = colour[i >> 3];
dreschpe 0:4bbc531be6e2 163 int offset = i & 0x7;
dreschpe 0:4bbc531be6e2 164 int c = ((byte << offset) & 0x80) ? _foreground : _background;
dreschpe 0:4bbc531be6e2 165 putp(c);
dreschpe 0:4bbc531be6e2 166 }
dreschpe 0:4bbc531be6e2 167 }
dreschpe 0:4bbc531be6e2 168
dreschpe 0:4bbc531be6e2 169 int GraphicsDisplay::columns() {
dreschpe 0:4bbc531be6e2 170 return width() / 8;
dreschpe 0:4bbc531be6e2 171 }
dreschpe 0:4bbc531be6e2 172
dreschpe 0:4bbc531be6e2 173 int GraphicsDisplay::rows() {
dreschpe 0:4bbc531be6e2 174 return height() / 8;
dreschpe 0:4bbc531be6e2 175 }
dreschpe 0:4bbc531be6e2 176