Lightweight proportional text library for C12832 LCD. Easy to modify, fast, robust and compact. Nice font, good for text driven menus, messages, etc. Fell free to use and modify in any projects.

Dependents:   app-board-lcd128

Documentation will be here later.

Usage sample:

Import programapp-board-lcd128

Sample usage of lightweight C12832 LCD library

Committer:
medvdv
Date:
Sat Feb 01 13:13:37 2014 +0000
Revision:
0:6ac8f630d9a0
Child:
1:17443d6d2740
first variant, commented, tested briefly

Who changed what in which revision?

UserRevisionLine numberNew contents of line
medvdv 0:6ac8f630d9a0 1 //
medvdv 0:6ac8f630d9a0 2 // MBED Application Board
medvdv 0:6ac8f630d9a0 3 // Lightweight C12832 LCD library
medvdv 0:6ac8f630d9a0 4 // 2014, Alexander Medvedev, @medvdv
medvdv 0:6ac8f630d9a0 5 //
medvdv 0:6ac8f630d9a0 6
medvdv 0:6ac8f630d9a0 7 #include "mbed.h"
medvdv 0:6ac8f630d9a0 8
medvdv 0:6ac8f630d9a0 9 #include "lcd128lib.h"
medvdv 0:6ac8f630d9a0 10 #include "lcd128font8.h"
medvdv 0:6ac8f630d9a0 11
medvdv 0:6ac8f630d9a0 12 //
medvdv 0:6ac8f630d9a0 13 // lcd128 class implementation
medvdv 0:6ac8f630d9a0 14 //
medvdv 0:6ac8f630d9a0 15
medvdv 0:6ac8f630d9a0 16 // SPI writer with command / data switch
medvdv 0:6ac8f630d9a0 17 void lcd128::write(char data, bool cmd)
medvdv 0:6ac8f630d9a0 18 {
medvdv 0:6ac8f630d9a0 19 a0 = cmd ? 0:1;
medvdv 0:6ac8f630d9a0 20 cs = 0;
medvdv 0:6ac8f630d9a0 21 spi.write(data);
medvdv 0:6ac8f630d9a0 22 cs = 1;
medvdv 0:6ac8f630d9a0 23 }
medvdv 0:6ac8f630d9a0 24
medvdv 0:6ac8f630d9a0 25 // Constructor
medvdv 0:6ac8f630d9a0 26 lcd128::lcd128(PinName mosi, PinName sclk, PinName p_a0, PinName p_cs, PinName p_rst):
medvdv 0:6ac8f630d9a0 27 spi(mosi, NC, sclk), rst(p_rst), cs(p_cs), a0(p_a0)
medvdv 0:6ac8f630d9a0 28 {
medvdv 0:6ac8f630d9a0 29 // Setup SPI
medvdv 0:6ac8f630d9a0 30 spi.format(8, 3);
medvdv 0:6ac8f630d9a0 31 spi.frequency(20000000);
medvdv 0:6ac8f630d9a0 32
medvdv 0:6ac8f630d9a0 33 // Setup default font
medvdv 0:6ac8f630d9a0 34 font.first_code = 32;
medvdv 0:6ac8f630d9a0 35 font.glyphs_total = 128 - 32;
medvdv 0:6ac8f630d9a0 36 font.widths = lcd_font8p_widths;
medvdv 0:6ac8f630d9a0 37 font.glyphs = lcd_font8p;
medvdv 0:6ac8f630d9a0 38
medvdv 0:6ac8f630d9a0 39 invert = false;
medvdv 0:6ac8f630d9a0 40 bold = false;
medvdv 0:6ac8f630d9a0 41 }
medvdv 0:6ac8f630d9a0 42
medvdv 0:6ac8f630d9a0 43 // Start inverting chars
medvdv 0:6ac8f630d9a0 44 void lcd128::Invert(bool invert)
medvdv 0:6ac8f630d9a0 45 {
medvdv 0:6ac8f630d9a0 46 this -> invert = invert;
medvdv 0:6ac8f630d9a0 47 }
medvdv 0:6ac8f630d9a0 48
medvdv 0:6ac8f630d9a0 49 // Start bold mode (repeat twice wide)
medvdv 0:6ac8f630d9a0 50 void lcd128::Bold(bool bold)
medvdv 0:6ac8f630d9a0 51 {
medvdv 0:6ac8f630d9a0 52 this -> bold = bold;
medvdv 0:6ac8f630d9a0 53 }
medvdv 0:6ac8f630d9a0 54
medvdv 0:6ac8f630d9a0 55 // Reset LCD, configure defaults and contrast
medvdv 0:6ac8f630d9a0 56 void lcd128::Reset()
medvdv 0:6ac8f630d9a0 57 {
medvdv 0:6ac8f630d9a0 58 a0 = 0;
medvdv 0:6ac8f630d9a0 59 cs = 1;
medvdv 0:6ac8f630d9a0 60 rst = 0;
medvdv 0:6ac8f630d9a0 61 wait_us(50);
medvdv 0:6ac8f630d9a0 62 rst = 1;
medvdv 0:6ac8f630d9a0 63
medvdv 0:6ac8f630d9a0 64 wait_ms(5);
medvdv 0:6ac8f630d9a0 65
medvdv 0:6ac8f630d9a0 66 write(0xae, true);
medvdv 0:6ac8f630d9a0 67 write(0xa2, true);
medvdv 0:6ac8f630d9a0 68 write(0xa0, true);
medvdv 0:6ac8f630d9a0 69 write(0xc8, true);
medvdv 0:6ac8f630d9a0 70 write(0x22, true);
medvdv 0:6ac8f630d9a0 71 write(0x2f, true);
medvdv 0:6ac8f630d9a0 72 write(0x40, true);
medvdv 0:6ac8f630d9a0 73
medvdv 0:6ac8f630d9a0 74 write(0xaf, true);
medvdv 0:6ac8f630d9a0 75 write(0x81, true);
medvdv 0:6ac8f630d9a0 76 write(0x17, true);
medvdv 0:6ac8f630d9a0 77 write(0xa6, true);
medvdv 0:6ac8f630d9a0 78
medvdv 0:6ac8f630d9a0 79 wait_ms(5);
medvdv 0:6ac8f630d9a0 80
medvdv 0:6ac8f630d9a0 81 XY();
medvdv 0:6ac8f630d9a0 82 Clear();
medvdv 0:6ac8f630d9a0 83 Update();
medvdv 0:6ac8f630d9a0 84 }
medvdv 0:6ac8f630d9a0 85
medvdv 0:6ac8f630d9a0 86 // LCD power off
medvdv 0:6ac8f630d9a0 87 void lcd128::Power(bool power)
medvdv 0:6ac8f630d9a0 88 {
medvdv 0:6ac8f630d9a0 89 // TBD
medvdv 0:6ac8f630d9a0 90 }
medvdv 0:6ac8f630d9a0 91
medvdv 0:6ac8f630d9a0 92 void lcd128::InverseMode(bool invert)
medvdv 0:6ac8f630d9a0 93 {
medvdv 0:6ac8f630d9a0 94 // TBD
medvdv 0:6ac8f630d9a0 95 }
medvdv 0:6ac8f630d9a0 96
medvdv 0:6ac8f630d9a0 97 // Update buffer to LCD
medvdv 0:6ac8f630d9a0 98 void lcd128::Update()
medvdv 0:6ac8f630d9a0 99 {
medvdv 0:6ac8f630d9a0 100 char* p = buffer;
medvdv 0:6ac8f630d9a0 101
medvdv 0:6ac8f630d9a0 102 for(int j=0; j<LCD_Y; j++) {
medvdv 0:6ac8f630d9a0 103 write(0x00, true);
medvdv 0:6ac8f630d9a0 104 write(0x10, true);
medvdv 0:6ac8f630d9a0 105 write(0xb0+j, true);
medvdv 0:6ac8f630d9a0 106 for(int i=0; i<LCD_X; i++) write(*p++, false);
medvdv 0:6ac8f630d9a0 107 }
medvdv 0:6ac8f630d9a0 108 }
medvdv 0:6ac8f630d9a0 109
medvdv 0:6ac8f630d9a0 110 // Clear all buffer or just one row
medvdv 0:6ac8f630d9a0 111 void lcd128::Clear(int row)
medvdv 0:6ac8f630d9a0 112 {
medvdv 0:6ac8f630d9a0 113 if(row == -1)
medvdv 0:6ac8f630d9a0 114 memset(buffer, 0, sizeof(buffer));
medvdv 0:6ac8f630d9a0 115 else {
medvdv 0:6ac8f630d9a0 116 if(row<0) row=0;
medvdv 0:6ac8f630d9a0 117 if(row>LCD_Y) row=0;
medvdv 0:6ac8f630d9a0 118
medvdv 0:6ac8f630d9a0 119 memset(buffer+row*LCD_X, 0, LCD_X);
medvdv 0:6ac8f630d9a0 120 }
medvdv 0:6ac8f630d9a0 121
medvdv 0:6ac8f630d9a0 122 Update();
medvdv 0:6ac8f630d9a0 123 }
medvdv 0:6ac8f630d9a0 124
medvdv 0:6ac8f630d9a0 125 // Change current output position
medvdv 0:6ac8f630d9a0 126 // X in pixels [0..LCD_X-1]
medvdv 0:6ac8f630d9a0 127 // Y in rows [0..LCD_Y-1]
medvdv 0:6ac8f630d9a0 128 void lcd128::XY(int x, int y)
medvdv 0:6ac8f630d9a0 129 {
medvdv 0:6ac8f630d9a0 130 if (x<0) x=0;
medvdv 0:6ac8f630d9a0 131 if (x>(LCD_X-1)) x=LCD_X-1;
medvdv 0:6ac8f630d9a0 132 if (y<0) y=0;
medvdv 0:6ac8f630d9a0 133 if (y>(LCD_Y-1)) y=LCD_Y-1;
medvdv 0:6ac8f630d9a0 134
medvdv 0:6ac8f630d9a0 135 X = x;
medvdv 0:6ac8f630d9a0 136 Y = y;
medvdv 0:6ac8f630d9a0 137 }
medvdv 0:6ac8f630d9a0 138
medvdv 0:6ac8f630d9a0 139 // Write one 8bit row
medvdv 0:6ac8f630d9a0 140 // with inversion and XY update
medvdv 0:6ac8f630d9a0 141 void lcd128::Write(char byte)
medvdv 0:6ac8f630d9a0 142 {
medvdv 0:6ac8f630d9a0 143 buffer[X+Y*LCD_X] = invert?(~byte):byte;
medvdv 0:6ac8f630d9a0 144
medvdv 0:6ac8f630d9a0 145 if (++X > (LCD_X-1)) {
medvdv 0:6ac8f630d9a0 146 X=0;
medvdv 0:6ac8f630d9a0 147 if (++Y > (LCD_Y-1)) Y=0;
medvdv 0:6ac8f630d9a0 148 }
medvdv 0:6ac8f630d9a0 149 }
medvdv 0:6ac8f630d9a0 150
medvdv 0:6ac8f630d9a0 151 // Write array of 8bit rows
medvdv 0:6ac8f630d9a0 152 void lcd128::Write(char* data, int size)
medvdv 0:6ac8f630d9a0 153 {
medvdv 0:6ac8f630d9a0 154 for(int i=0; i<size; i++) Write(data[i]);
medvdv 0:6ac8f630d9a0 155 }
medvdv 0:6ac8f630d9a0 156
medvdv 0:6ac8f630d9a0 157 // Write array of 8bit rows, twice each
medvdv 0:6ac8f630d9a0 158 void lcd128::Write2(char* data, int size)
medvdv 0:6ac8f630d9a0 159 {
medvdv 0:6ac8f630d9a0 160 for(int i=0; i<size; i++) {
medvdv 0:6ac8f630d9a0 161 Write(data[i]);
medvdv 0:6ac8f630d9a0 162 Write(data[i]);
medvdv 0:6ac8f630d9a0 163 }
medvdv 0:6ac8f630d9a0 164 }
medvdv 0:6ac8f630d9a0 165
medvdv 0:6ac8f630d9a0 166 // Write 8bit row 'count' times
medvdv 0:6ac8f630d9a0 167 void lcd128::Write(char byte, int count)
medvdv 0:6ac8f630d9a0 168 {
medvdv 0:6ac8f630d9a0 169 for(int i=0; i<count; i++) Write(byte);
medvdv 0:6ac8f630d9a0 170 }
medvdv 0:6ac8f630d9a0 171
medvdv 0:6ac8f630d9a0 172 // Draw one proportional font character
medvdv 0:6ac8f630d9a0 173 // Jump to next line if empty space is not enought
medvdv 0:6ac8f630d9a0 174 void lcd128::Character(char chr)
medvdv 0:6ac8f630d9a0 175 {
medvdv 0:6ac8f630d9a0 176 if( chr < font.first_code ) return;
medvdv 0:6ac8f630d9a0 177 if( chr > font.first_code + font.glyphs_total - 1 ) return;
medvdv 0:6ac8f630d9a0 178
medvdv 0:6ac8f630d9a0 179 chr -= font.first_code;
medvdv 0:6ac8f630d9a0 180
medvdv 0:6ac8f630d9a0 181 int width = font.widths[chr];
medvdv 0:6ac8f630d9a0 182
medvdv 0:6ac8f630d9a0 183 if (bold) width*=2;
medvdv 0:6ac8f630d9a0 184
medvdv 0:6ac8f630d9a0 185 if ((X + width) > (LCD_X-1)) {
medvdv 0:6ac8f630d9a0 186 if (++Y > (LCD_Y-1)) Y = 0;
medvdv 0:6ac8f630d9a0 187 XY(0,Y);
medvdv 0:6ac8f630d9a0 188 }
medvdv 0:6ac8f630d9a0 189
medvdv 0:6ac8f630d9a0 190 if (bold) {
medvdv 0:6ac8f630d9a0 191 Write2( (char*) font.glyphs[chr], (int) font.widths[chr] );
medvdv 0:6ac8f630d9a0 192 if (X != 0) {
medvdv 0:6ac8f630d9a0 193 Write(0);
medvdv 0:6ac8f630d9a0 194 Write(0);
medvdv 0:6ac8f630d9a0 195 }
medvdv 0:6ac8f630d9a0 196 } else {
medvdv 0:6ac8f630d9a0 197 Write( (char*) font.glyphs[chr], (int) font.widths[chr] );
medvdv 0:6ac8f630d9a0 198 if (X != 0) Write(0);
medvdv 0:6ac8f630d9a0 199 }
medvdv 0:6ac8f630d9a0 200 }
medvdv 0:6ac8f630d9a0 201
medvdv 0:6ac8f630d9a0 202 // Calculate width of concrete character
medvdv 0:6ac8f630d9a0 203 // takes into account bold setting
medvdv 0:6ac8f630d9a0 204 int lcd128::CharacterWidth(char chr)
medvdv 0:6ac8f630d9a0 205 {
medvdv 0:6ac8f630d9a0 206 if( chr < font.first_code ) return 0;
medvdv 0:6ac8f630d9a0 207 if( chr > font.first_code + font.glyphs_total - 1 ) return 0;
medvdv 0:6ac8f630d9a0 208
medvdv 0:6ac8f630d9a0 209 chr -= font.first_code;
medvdv 0:6ac8f630d9a0 210
medvdv 0:6ac8f630d9a0 211 if (bold)
medvdv 0:6ac8f630d9a0 212 return 2 * (font.widths[chr] + 1);
medvdv 0:6ac8f630d9a0 213 else
medvdv 0:6ac8f630d9a0 214 return font.widths[chr] + 1;
medvdv 0:6ac8f630d9a0 215 }
medvdv 0:6ac8f630d9a0 216
medvdv 0:6ac8f630d9a0 217 // Write string
medvdv 0:6ac8f630d9a0 218 void lcd128::String(char* str)
medvdv 0:6ac8f630d9a0 219 {
medvdv 0:6ac8f630d9a0 220 while(*str) Character(*str++);
medvdv 0:6ac8f630d9a0 221 }
medvdv 0:6ac8f630d9a0 222
medvdv 0:6ac8f630d9a0 223 // Predict string width
medvdv 0:6ac8f630d9a0 224 int lcd128::StringWidth(char* str)
medvdv 0:6ac8f630d9a0 225 {
medvdv 0:6ac8f630d9a0 226 int width = 0;
medvdv 0:6ac8f630d9a0 227
medvdv 0:6ac8f630d9a0 228 while(*str) width += CharacterWidth(*str++);
medvdv 0:6ac8f630d9a0 229
medvdv 0:6ac8f630d9a0 230 return width;
medvdv 0:6ac8f630d9a0 231 }
medvdv 0:6ac8f630d9a0 232
medvdv 0:6ac8f630d9a0 233 // Clear one line,
medvdv 0:6ac8f630d9a0 234 // then write string from it's begin
medvdv 0:6ac8f630d9a0 235 void lcd128::Row(int Y, char* str)
medvdv 0:6ac8f630d9a0 236 {
medvdv 0:6ac8f630d9a0 237 Clear(Y);
medvdv 0:6ac8f630d9a0 238 XY(0, Y);
medvdv 0:6ac8f630d9a0 239 String(str);
medvdv 0:6ac8f630d9a0 240 }