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:
Mon May 26 20:14:58 2014 +0000
Revision:
4:1bd241d1fad0
Parent:
3:c0e409cda493
Child:
5:ff31feb7d966
comments updated

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 4:1bd241d1fad0 17
medvdv 0:6ac8f630d9a0 18 void lcd128::write(char data, bool cmd)
medvdv 0:6ac8f630d9a0 19 {
medvdv 4:1bd241d1fad0 20 a0 = cmd ? 0 : 1;
medvdv 0:6ac8f630d9a0 21 cs = 0;
medvdv 0:6ac8f630d9a0 22 spi.write(data);
medvdv 0:6ac8f630d9a0 23 cs = 1;
medvdv 0:6ac8f630d9a0 24 }
medvdv 0:6ac8f630d9a0 25
medvdv 4:1bd241d1fad0 26 // Constructor, SPI setup and defaults
medvdv 4:1bd241d1fad0 27
medvdv 0:6ac8f630d9a0 28 lcd128::lcd128(PinName mosi, PinName sclk, PinName p_a0, PinName p_cs, PinName p_rst):
medvdv 0:6ac8f630d9a0 29 spi(mosi, NC, sclk), rst(p_rst), cs(p_cs), a0(p_a0)
medvdv 0:6ac8f630d9a0 30 {
medvdv 0:6ac8f630d9a0 31 // Setup SPI
medvdv 0:6ac8f630d9a0 32 spi.format(8, 3);
medvdv 0:6ac8f630d9a0 33 spi.frequency(20000000);
medvdv 0:6ac8f630d9a0 34
medvdv 0:6ac8f630d9a0 35 // Setup default font
medvdv 0:6ac8f630d9a0 36 font.first_code = 32;
medvdv 0:6ac8f630d9a0 37 font.glyphs_total = 128 - 32;
medvdv 0:6ac8f630d9a0 38 font.widths = lcd_font8p_widths;
medvdv 0:6ac8f630d9a0 39 font.glyphs = lcd_font8p;
medvdv 0:6ac8f630d9a0 40
medvdv 0:6ac8f630d9a0 41 invert = false;
medvdv 1:17443d6d2740 42 bold = false;
medvdv 1:17443d6d2740 43 underline = false;
medvdv 0:6ac8f630d9a0 44 }
medvdv 0:6ac8f630d9a0 45
medvdv 4:1bd241d1fad0 46 // Inverting chars on / off
medvdv 4:1bd241d1fad0 47
medvdv 0:6ac8f630d9a0 48 void lcd128::Invert(bool invert)
medvdv 0:6ac8f630d9a0 49 {
medvdv 0:6ac8f630d9a0 50 this -> invert = invert;
medvdv 0:6ac8f630d9a0 51 }
medvdv 0:6ac8f630d9a0 52
medvdv 4:1bd241d1fad0 53 // Bold mode (twice wide chars) on / off
medvdv 4:1bd241d1fad0 54
medvdv 0:6ac8f630d9a0 55 void lcd128::Bold(bool bold)
medvdv 0:6ac8f630d9a0 56 {
medvdv 0:6ac8f630d9a0 57 this -> bold = bold;
medvdv 0:6ac8f630d9a0 58 }
medvdv 0:6ac8f630d9a0 59
medvdv 4:1bd241d1fad0 60 // Underline mode on / off
medvdv 4:1bd241d1fad0 61
medvdv 1:17443d6d2740 62 void lcd128::Underline(bool underline)
medvdv 1:17443d6d2740 63 {
medvdv 1:17443d6d2740 64 this -> underline = underline;
medvdv 1:17443d6d2740 65 }
medvdv 1:17443d6d2740 66
medvdv 0:6ac8f630d9a0 67 // Reset LCD, configure defaults and contrast
medvdv 4:1bd241d1fad0 68
medvdv 0:6ac8f630d9a0 69 void lcd128::Reset()
medvdv 0:6ac8f630d9a0 70 {
medvdv 0:6ac8f630d9a0 71 a0 = 0;
medvdv 0:6ac8f630d9a0 72 cs = 1;
medvdv 0:6ac8f630d9a0 73 rst = 0;
medvdv 4:1bd241d1fad0 74
medvdv 0:6ac8f630d9a0 75 wait_us(50);
medvdv 4:1bd241d1fad0 76
medvdv 0:6ac8f630d9a0 77 rst = 1;
medvdv 0:6ac8f630d9a0 78
medvdv 0:6ac8f630d9a0 79 wait_ms(5);
medvdv 0:6ac8f630d9a0 80
medvdv 0:6ac8f630d9a0 81 write(0xae, true);
medvdv 0:6ac8f630d9a0 82 write(0xa2, true);
medvdv 0:6ac8f630d9a0 83 write(0xa0, true);
medvdv 0:6ac8f630d9a0 84 write(0xc8, true);
medvdv 0:6ac8f630d9a0 85 write(0x22, true);
medvdv 0:6ac8f630d9a0 86 write(0x2f, true);
medvdv 0:6ac8f630d9a0 87 write(0x40, true);
medvdv 0:6ac8f630d9a0 88
medvdv 0:6ac8f630d9a0 89 write(0xaf, true);
medvdv 0:6ac8f630d9a0 90 write(0x81, true);
medvdv 0:6ac8f630d9a0 91 write(0x17, true);
medvdv 0:6ac8f630d9a0 92 write(0xa6, true);
medvdv 0:6ac8f630d9a0 93
medvdv 0:6ac8f630d9a0 94 wait_ms(5);
medvdv 0:6ac8f630d9a0 95
medvdv 0:6ac8f630d9a0 96 XY();
medvdv 0:6ac8f630d9a0 97 Clear();
medvdv 0:6ac8f630d9a0 98 Update();
medvdv 0:6ac8f630d9a0 99 }
medvdv 0:6ac8f630d9a0 100
medvdv 4:1bd241d1fad0 101 // LCD power on / off
medvdv 4:1bd241d1fad0 102
medvdv 0:6ac8f630d9a0 103 void lcd128::Power(bool power)
medvdv 0:6ac8f630d9a0 104 {
medvdv 2:fdea8ffb3c4f 105 if (!power) {
medvdv 2:fdea8ffb3c4f 106 write(0xae, true);
medvdv 2:fdea8ffb3c4f 107 write(0xa5, true);
medvdv 2:fdea8ffb3c4f 108 } else {
medvdv 2:fdea8ffb3c4f 109 write(0xaf, true);
medvdv 2:fdea8ffb3c4f 110 write(0xa4, true);
medvdv 2:fdea8ffb3c4f 111 }
medvdv 0:6ac8f630d9a0 112 }
medvdv 0:6ac8f630d9a0 113
medvdv 4:1bd241d1fad0 114 // Invert LCD on / off
medvdv 4:1bd241d1fad0 115
medvdv 0:6ac8f630d9a0 116 void lcd128::InverseMode(bool invert)
medvdv 0:6ac8f630d9a0 117 {
medvdv 2:fdea8ffb3c4f 118 if (!invert)
medvdv 2:fdea8ffb3c4f 119 write(0xa6, true);
medvdv 2:fdea8ffb3c4f 120 else
medvdv 2:fdea8ffb3c4f 121 write(0xa7, true);
medvdv 0:6ac8f630d9a0 122 }
medvdv 0:6ac8f630d9a0 123
medvdv 0:6ac8f630d9a0 124 // Update buffer to LCD
medvdv 4:1bd241d1fad0 125
medvdv 0:6ac8f630d9a0 126 void lcd128::Update()
medvdv 0:6ac8f630d9a0 127 {
medvdv 0:6ac8f630d9a0 128 char* p = buffer;
medvdv 0:6ac8f630d9a0 129
medvdv 0:6ac8f630d9a0 130 for(int j=0; j<LCD_Y; j++) {
medvdv 0:6ac8f630d9a0 131 write(0x00, true);
medvdv 0:6ac8f630d9a0 132 write(0x10, true);
medvdv 0:6ac8f630d9a0 133 write(0xb0+j, true);
medvdv 0:6ac8f630d9a0 134 for(int i=0; i<LCD_X; i++) write(*p++, false);
medvdv 0:6ac8f630d9a0 135 }
medvdv 0:6ac8f630d9a0 136 }
medvdv 0:6ac8f630d9a0 137
medvdv 0:6ac8f630d9a0 138 // Clear all buffer or just one row
medvdv 4:1bd241d1fad0 139
medvdv 0:6ac8f630d9a0 140 void lcd128::Clear(int row)
medvdv 0:6ac8f630d9a0 141 {
medvdv 0:6ac8f630d9a0 142 if(row == -1)
medvdv 0:6ac8f630d9a0 143 memset(buffer, 0, sizeof(buffer));
medvdv 0:6ac8f630d9a0 144 else {
medvdv 0:6ac8f630d9a0 145 if(row<0) row=0;
medvdv 4:1bd241d1fad0 146 if(row>LCD_Y) row=0;
medvdv 0:6ac8f630d9a0 147 memset(buffer+row*LCD_X, 0, LCD_X);
medvdv 0:6ac8f630d9a0 148 }
medvdv 0:6ac8f630d9a0 149
medvdv 0:6ac8f630d9a0 150 Update();
medvdv 0:6ac8f630d9a0 151 }
medvdv 0:6ac8f630d9a0 152
medvdv 0:6ac8f630d9a0 153 // Change current output position
medvdv 0:6ac8f630d9a0 154 // X in pixels [0..LCD_X-1]
medvdv 0:6ac8f630d9a0 155 // Y in rows [0..LCD_Y-1]
medvdv 4:1bd241d1fad0 156
medvdv 0:6ac8f630d9a0 157 void lcd128::XY(int x, int y)
medvdv 0:6ac8f630d9a0 158 {
medvdv 0:6ac8f630d9a0 159 if (x<0) x=0;
medvdv 0:6ac8f630d9a0 160 if (x>(LCD_X-1)) x=LCD_X-1;
medvdv 0:6ac8f630d9a0 161 if (y<0) y=0;
medvdv 0:6ac8f630d9a0 162 if (y>(LCD_Y-1)) y=LCD_Y-1;
medvdv 0:6ac8f630d9a0 163
medvdv 0:6ac8f630d9a0 164 X = x;
medvdv 0:6ac8f630d9a0 165 Y = y;
medvdv 0:6ac8f630d9a0 166 }
medvdv 0:6ac8f630d9a0 167
medvdv 0:6ac8f630d9a0 168 // Write one 8bit row
medvdv 0:6ac8f630d9a0 169 // with inversion and XY update
medvdv 4:1bd241d1fad0 170
medvdv 0:6ac8f630d9a0 171 void lcd128::Write(char byte)
medvdv 0:6ac8f630d9a0 172 {
medvdv 1:17443d6d2740 173 if (underline) byte |= 0x80;
medvdv 0:6ac8f630d9a0 174 buffer[X+Y*LCD_X] = invert?(~byte):byte;
medvdv 0:6ac8f630d9a0 175
medvdv 0:6ac8f630d9a0 176 if (++X > (LCD_X-1)) {
medvdv 0:6ac8f630d9a0 177 X=0;
medvdv 0:6ac8f630d9a0 178 if (++Y > (LCD_Y-1)) Y=0;
medvdv 0:6ac8f630d9a0 179 }
medvdv 0:6ac8f630d9a0 180 }
medvdv 0:6ac8f630d9a0 181
medvdv 0:6ac8f630d9a0 182 // Write array of 8bit rows
medvdv 4:1bd241d1fad0 183
medvdv 0:6ac8f630d9a0 184 void lcd128::Write(char* data, int size)
medvdv 0:6ac8f630d9a0 185 {
medvdv 1:17443d6d2740 186 for (int i=0; i<size; i++) Write(data[i]);
medvdv 0:6ac8f630d9a0 187 }
medvdv 0:6ac8f630d9a0 188
medvdv 0:6ac8f630d9a0 189 // Write array of 8bit rows, twice each
medvdv 4:1bd241d1fad0 190
medvdv 0:6ac8f630d9a0 191 void lcd128::Write2(char* data, int size)
medvdv 0:6ac8f630d9a0 192 {
medvdv 1:17443d6d2740 193 for (int i=0; i<size; i++) {
medvdv 0:6ac8f630d9a0 194 Write(data[i]);
medvdv 0:6ac8f630d9a0 195 Write(data[i]);
medvdv 0:6ac8f630d9a0 196 }
medvdv 0:6ac8f630d9a0 197 }
medvdv 0:6ac8f630d9a0 198
medvdv 0:6ac8f630d9a0 199 // Write 8bit row 'count' times
medvdv 4:1bd241d1fad0 200
medvdv 0:6ac8f630d9a0 201 void lcd128::Write(char byte, int count)
medvdv 0:6ac8f630d9a0 202 {
medvdv 1:17443d6d2740 203 for (int i=0; i<count; i++) Write(byte);
medvdv 0:6ac8f630d9a0 204 }
medvdv 0:6ac8f630d9a0 205
medvdv 0:6ac8f630d9a0 206 // Draw one proportional font character
medvdv 0:6ac8f630d9a0 207 // Jump to next line if empty space is not enought
medvdv 4:1bd241d1fad0 208
medvdv 0:6ac8f630d9a0 209 void lcd128::Character(char chr)
medvdv 0:6ac8f630d9a0 210 {
medvdv 0:6ac8f630d9a0 211 if( chr < font.first_code ) return;
medvdv 0:6ac8f630d9a0 212 if( chr > font.first_code + font.glyphs_total - 1 ) return;
medvdv 0:6ac8f630d9a0 213
medvdv 0:6ac8f630d9a0 214 chr -= font.first_code;
medvdv 0:6ac8f630d9a0 215
medvdv 0:6ac8f630d9a0 216 int width = font.widths[chr];
medvdv 0:6ac8f630d9a0 217
medvdv 0:6ac8f630d9a0 218 if (bold) width*=2;
medvdv 0:6ac8f630d9a0 219
medvdv 0:6ac8f630d9a0 220 if ((X + width) > (LCD_X-1)) {
medvdv 0:6ac8f630d9a0 221 if (++Y > (LCD_Y-1)) Y = 0;
medvdv 0:6ac8f630d9a0 222 XY(0,Y);
medvdv 0:6ac8f630d9a0 223 }
medvdv 0:6ac8f630d9a0 224
medvdv 0:6ac8f630d9a0 225 if (bold) {
medvdv 0:6ac8f630d9a0 226 Write2( (char*) font.glyphs[chr], (int) font.widths[chr] );
medvdv 0:6ac8f630d9a0 227 if (X != 0) {
medvdv 0:6ac8f630d9a0 228 Write(0);
medvdv 0:6ac8f630d9a0 229 Write(0);
medvdv 0:6ac8f630d9a0 230 }
medvdv 0:6ac8f630d9a0 231 } else {
medvdv 0:6ac8f630d9a0 232 Write( (char*) font.glyphs[chr], (int) font.widths[chr] );
medvdv 0:6ac8f630d9a0 233 if (X != 0) Write(0);
medvdv 0:6ac8f630d9a0 234 }
medvdv 0:6ac8f630d9a0 235 }
medvdv 0:6ac8f630d9a0 236
medvdv 0:6ac8f630d9a0 237 // Calculate width of concrete character
medvdv 0:6ac8f630d9a0 238 // takes into account bold setting
medvdv 4:1bd241d1fad0 239
medvdv 0:6ac8f630d9a0 240 int lcd128::CharacterWidth(char chr)
medvdv 0:6ac8f630d9a0 241 {
medvdv 0:6ac8f630d9a0 242 if( chr < font.first_code ) return 0;
medvdv 0:6ac8f630d9a0 243 if( chr > font.first_code + font.glyphs_total - 1 ) return 0;
medvdv 0:6ac8f630d9a0 244
medvdv 0:6ac8f630d9a0 245 chr -= font.first_code;
medvdv 0:6ac8f630d9a0 246
medvdv 0:6ac8f630d9a0 247 if (bold)
medvdv 0:6ac8f630d9a0 248 return 2 * (font.widths[chr] + 1);
medvdv 0:6ac8f630d9a0 249 else
medvdv 0:6ac8f630d9a0 250 return font.widths[chr] + 1;
medvdv 0:6ac8f630d9a0 251 }
medvdv 0:6ac8f630d9a0 252
medvdv 0:6ac8f630d9a0 253 // Write string
medvdv 4:1bd241d1fad0 254
medvdv 0:6ac8f630d9a0 255 void lcd128::String(char* str)
medvdv 0:6ac8f630d9a0 256 {
medvdv 0:6ac8f630d9a0 257 while(*str) Character(*str++);
medvdv 0:6ac8f630d9a0 258 }
medvdv 0:6ac8f630d9a0 259
medvdv 0:6ac8f630d9a0 260 // Predict string width
medvdv 4:1bd241d1fad0 261
medvdv 0:6ac8f630d9a0 262 int lcd128::StringWidth(char* str)
medvdv 0:6ac8f630d9a0 263 {
medvdv 0:6ac8f630d9a0 264 int width = 0;
medvdv 0:6ac8f630d9a0 265
medvdv 0:6ac8f630d9a0 266 while(*str) width += CharacterWidth(*str++);
medvdv 0:6ac8f630d9a0 267
medvdv 0:6ac8f630d9a0 268 return width;
medvdv 0:6ac8f630d9a0 269 }
medvdv 0:6ac8f630d9a0 270
medvdv 0:6ac8f630d9a0 271 // Clear one line,
medvdv 0:6ac8f630d9a0 272 // then write string from it's begin
medvdv 4:1bd241d1fad0 273
medvdv 0:6ac8f630d9a0 274 void lcd128::Row(int Y, char* str)
medvdv 0:6ac8f630d9a0 275 {
medvdv 0:6ac8f630d9a0 276 Clear(Y);
medvdv 0:6ac8f630d9a0 277 XY(0, Y);
medvdv 0:6ac8f630d9a0 278 String(str);
medvdv 0:6ac8f630d9a0 279 }
medvdv 1:17443d6d2740 280
medvdv 4:1bd241d1fad0 281 // Same, but center text
medvdv 4:1bd241d1fad0 282
medvdv 3:c0e409cda493 283 void lcd128::RowCenter(int Y, char* str)
medvdv 3:c0e409cda493 284 {
medvdv 3:c0e409cda493 285 Clear(Y);
medvdv 3:c0e409cda493 286 XY((LCD_X/2)-StringWidth(str)/2,Y);
medvdv 3:c0e409cda493 287 String(str);
medvdv 3:c0e409cda493 288 }
medvdv 3:c0e409cda493 289
medvdv 4:1bd241d1fad0 290 // Draw progress bar
medvdv 4:1bd241d1fad0 291 // fill from 0.0f to 1.0f
medvdv 4:1bd241d1fad0 292
medvdv 1:17443d6d2740 293 void lcd128::Bar(int width, float fill)
medvdv 1:17443d6d2740 294 {
medvdv 1:17443d6d2740 295 if (width < 2) return;
medvdv 1:17443d6d2740 296 if (fill < 0.0) fill = 0.0;
medvdv 1:17443d6d2740 297 if (fill > 1.0) fill = 1.0;
medvdv 1:17443d6d2740 298
medvdv 1:17443d6d2740 299 int a = (width - 2)*fill;
medvdv 1:17443d6d2740 300 int b = width - 2 - a;
medvdv 1:17443d6d2740 301
medvdv 1:17443d6d2740 302 Write(LCD_BAR_B);
medvdv 1:17443d6d2740 303 Write(LCD_BAR_F, a);
medvdv 1:17443d6d2740 304 Write(LCD_BAR_U, b);
medvdv 1:17443d6d2740 305 Write(LCD_BAR_E);
medvdv 1:17443d6d2740 306 }