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:
Wed Feb 05 00:10:23 2014 +0000
Revision:
2:fdea8ffb3c4f
Parent:
1:17443d6d2740
Child:
3:c0e409cda493
Inverse mode of display, Power down mode

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