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 15:37:54 2014 +0000
Revision:
1:17443d6d2740
Parent:
0:6ac8f630d9a0
Child:
2:fdea8ffb3c4f
Nice looking progress bar.; Underlined text.

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 0:6ac8f630d9a0 96 // TBD
medvdv 0:6ac8f630d9a0 97 }
medvdv 0:6ac8f630d9a0 98
medvdv 0:6ac8f630d9a0 99 void lcd128::InverseMode(bool invert)
medvdv 0:6ac8f630d9a0 100 {
medvdv 0:6ac8f630d9a0 101 // TBD
medvdv 0:6ac8f630d9a0 102 }
medvdv 0:6ac8f630d9a0 103
medvdv 0:6ac8f630d9a0 104 // Update buffer to LCD
medvdv 0:6ac8f630d9a0 105 void lcd128::Update()
medvdv 0:6ac8f630d9a0 106 {
medvdv 0:6ac8f630d9a0 107 char* p = buffer;
medvdv 0:6ac8f630d9a0 108
medvdv 0:6ac8f630d9a0 109 for(int j=0; j<LCD_Y; j++) {
medvdv 0:6ac8f630d9a0 110 write(0x00, true);
medvdv 0:6ac8f630d9a0 111 write(0x10, true);
medvdv 0:6ac8f630d9a0 112 write(0xb0+j, true);
medvdv 0:6ac8f630d9a0 113 for(int i=0; i<LCD_X; i++) write(*p++, false);
medvdv 0:6ac8f630d9a0 114 }
medvdv 0:6ac8f630d9a0 115 }
medvdv 0:6ac8f630d9a0 116
medvdv 0:6ac8f630d9a0 117 // Clear all buffer or just one row
medvdv 0:6ac8f630d9a0 118 void lcd128::Clear(int row)
medvdv 0:6ac8f630d9a0 119 {
medvdv 0:6ac8f630d9a0 120 if(row == -1)
medvdv 0:6ac8f630d9a0 121 memset(buffer, 0, sizeof(buffer));
medvdv 0:6ac8f630d9a0 122 else {
medvdv 0:6ac8f630d9a0 123 if(row<0) row=0;
medvdv 0:6ac8f630d9a0 124 if(row>LCD_Y) row=0;
medvdv 0:6ac8f630d9a0 125
medvdv 0:6ac8f630d9a0 126 memset(buffer+row*LCD_X, 0, LCD_X);
medvdv 0:6ac8f630d9a0 127 }
medvdv 0:6ac8f630d9a0 128
medvdv 0:6ac8f630d9a0 129 Update();
medvdv 0:6ac8f630d9a0 130 }
medvdv 0:6ac8f630d9a0 131
medvdv 0:6ac8f630d9a0 132 // Change current output position
medvdv 0:6ac8f630d9a0 133 // X in pixels [0..LCD_X-1]
medvdv 0:6ac8f630d9a0 134 // Y in rows [0..LCD_Y-1]
medvdv 0:6ac8f630d9a0 135 void lcd128::XY(int x, int y)
medvdv 0:6ac8f630d9a0 136 {
medvdv 0:6ac8f630d9a0 137 if (x<0) x=0;
medvdv 0:6ac8f630d9a0 138 if (x>(LCD_X-1)) x=LCD_X-1;
medvdv 0:6ac8f630d9a0 139 if (y<0) y=0;
medvdv 0:6ac8f630d9a0 140 if (y>(LCD_Y-1)) y=LCD_Y-1;
medvdv 0:6ac8f630d9a0 141
medvdv 0:6ac8f630d9a0 142 X = x;
medvdv 0:6ac8f630d9a0 143 Y = y;
medvdv 0:6ac8f630d9a0 144 }
medvdv 0:6ac8f630d9a0 145
medvdv 0:6ac8f630d9a0 146 // Write one 8bit row
medvdv 0:6ac8f630d9a0 147 // with inversion and XY update
medvdv 0:6ac8f630d9a0 148 void lcd128::Write(char byte)
medvdv 0:6ac8f630d9a0 149 {
medvdv 1:17443d6d2740 150 if (underline) byte |= 0x80;
medvdv 0:6ac8f630d9a0 151 buffer[X+Y*LCD_X] = invert?(~byte):byte;
medvdv 0:6ac8f630d9a0 152
medvdv 0:6ac8f630d9a0 153 if (++X > (LCD_X-1)) {
medvdv 0:6ac8f630d9a0 154 X=0;
medvdv 0:6ac8f630d9a0 155 if (++Y > (LCD_Y-1)) Y=0;
medvdv 0:6ac8f630d9a0 156 }
medvdv 0:6ac8f630d9a0 157 }
medvdv 0:6ac8f630d9a0 158
medvdv 0:6ac8f630d9a0 159 // Write array of 8bit rows
medvdv 0:6ac8f630d9a0 160 void lcd128::Write(char* data, int size)
medvdv 0:6ac8f630d9a0 161 {
medvdv 1:17443d6d2740 162 for (int i=0; i<size; i++) Write(data[i]);
medvdv 0:6ac8f630d9a0 163 }
medvdv 0:6ac8f630d9a0 164
medvdv 0:6ac8f630d9a0 165 // Write array of 8bit rows, twice each
medvdv 0:6ac8f630d9a0 166 void lcd128::Write2(char* data, int size)
medvdv 0:6ac8f630d9a0 167 {
medvdv 1:17443d6d2740 168 for (int i=0; i<size; i++) {
medvdv 0:6ac8f630d9a0 169 Write(data[i]);
medvdv 0:6ac8f630d9a0 170 Write(data[i]);
medvdv 0:6ac8f630d9a0 171 }
medvdv 0:6ac8f630d9a0 172 }
medvdv 0:6ac8f630d9a0 173
medvdv 0:6ac8f630d9a0 174 // Write 8bit row 'count' times
medvdv 0:6ac8f630d9a0 175 void lcd128::Write(char byte, int count)
medvdv 0:6ac8f630d9a0 176 {
medvdv 1:17443d6d2740 177 for (int i=0; i<count; i++) Write(byte);
medvdv 0:6ac8f630d9a0 178 }
medvdv 0:6ac8f630d9a0 179
medvdv 0:6ac8f630d9a0 180 // Draw one proportional font character
medvdv 0:6ac8f630d9a0 181 // Jump to next line if empty space is not enought
medvdv 0:6ac8f630d9a0 182 void lcd128::Character(char chr)
medvdv 0:6ac8f630d9a0 183 {
medvdv 0:6ac8f630d9a0 184 if( chr < font.first_code ) return;
medvdv 0:6ac8f630d9a0 185 if( chr > font.first_code + font.glyphs_total - 1 ) return;
medvdv 0:6ac8f630d9a0 186
medvdv 0:6ac8f630d9a0 187 chr -= font.first_code;
medvdv 0:6ac8f630d9a0 188
medvdv 0:6ac8f630d9a0 189 int width = font.widths[chr];
medvdv 0:6ac8f630d9a0 190
medvdv 0:6ac8f630d9a0 191 if (bold) width*=2;
medvdv 0:6ac8f630d9a0 192
medvdv 0:6ac8f630d9a0 193 if ((X + width) > (LCD_X-1)) {
medvdv 0:6ac8f630d9a0 194 if (++Y > (LCD_Y-1)) Y = 0;
medvdv 0:6ac8f630d9a0 195 XY(0,Y);
medvdv 0:6ac8f630d9a0 196 }
medvdv 0:6ac8f630d9a0 197
medvdv 0:6ac8f630d9a0 198 if (bold) {
medvdv 0:6ac8f630d9a0 199 Write2( (char*) font.glyphs[chr], (int) font.widths[chr] );
medvdv 0:6ac8f630d9a0 200 if (X != 0) {
medvdv 0:6ac8f630d9a0 201 Write(0);
medvdv 0:6ac8f630d9a0 202 Write(0);
medvdv 0:6ac8f630d9a0 203 }
medvdv 0:6ac8f630d9a0 204 } else {
medvdv 0:6ac8f630d9a0 205 Write( (char*) font.glyphs[chr], (int) font.widths[chr] );
medvdv 0:6ac8f630d9a0 206 if (X != 0) Write(0);
medvdv 0:6ac8f630d9a0 207 }
medvdv 0:6ac8f630d9a0 208 }
medvdv 0:6ac8f630d9a0 209
medvdv 0:6ac8f630d9a0 210 // Calculate width of concrete character
medvdv 0:6ac8f630d9a0 211 // takes into account bold setting
medvdv 0:6ac8f630d9a0 212 int lcd128::CharacterWidth(char chr)
medvdv 0:6ac8f630d9a0 213 {
medvdv 0:6ac8f630d9a0 214 if( chr < font.first_code ) return 0;
medvdv 0:6ac8f630d9a0 215 if( chr > font.first_code + font.glyphs_total - 1 ) return 0;
medvdv 0:6ac8f630d9a0 216
medvdv 0:6ac8f630d9a0 217 chr -= font.first_code;
medvdv 0:6ac8f630d9a0 218
medvdv 0:6ac8f630d9a0 219 if (bold)
medvdv 0:6ac8f630d9a0 220 return 2 * (font.widths[chr] + 1);
medvdv 0:6ac8f630d9a0 221 else
medvdv 0:6ac8f630d9a0 222 return font.widths[chr] + 1;
medvdv 0:6ac8f630d9a0 223 }
medvdv 0:6ac8f630d9a0 224
medvdv 0:6ac8f630d9a0 225 // Write string
medvdv 0:6ac8f630d9a0 226 void lcd128::String(char* str)
medvdv 0:6ac8f630d9a0 227 {
medvdv 0:6ac8f630d9a0 228 while(*str) Character(*str++);
medvdv 0:6ac8f630d9a0 229 }
medvdv 0:6ac8f630d9a0 230
medvdv 0:6ac8f630d9a0 231 // Predict string width
medvdv 0:6ac8f630d9a0 232 int lcd128::StringWidth(char* str)
medvdv 0:6ac8f630d9a0 233 {
medvdv 0:6ac8f630d9a0 234 int width = 0;
medvdv 0:6ac8f630d9a0 235
medvdv 0:6ac8f630d9a0 236 while(*str) width += CharacterWidth(*str++);
medvdv 0:6ac8f630d9a0 237
medvdv 0:6ac8f630d9a0 238 return width;
medvdv 0:6ac8f630d9a0 239 }
medvdv 0:6ac8f630d9a0 240
medvdv 0:6ac8f630d9a0 241 // Clear one line,
medvdv 0:6ac8f630d9a0 242 // then write string from it's begin
medvdv 0:6ac8f630d9a0 243 void lcd128::Row(int Y, char* str)
medvdv 0:6ac8f630d9a0 244 {
medvdv 0:6ac8f630d9a0 245 Clear(Y);
medvdv 0:6ac8f630d9a0 246 XY(0, Y);
medvdv 0:6ac8f630d9a0 247 String(str);
medvdv 0:6ac8f630d9a0 248 }
medvdv 1:17443d6d2740 249
medvdv 1:17443d6d2740 250 void lcd128::Bar(int width, float fill)
medvdv 1:17443d6d2740 251 {
medvdv 1:17443d6d2740 252 if (width < 2) return;
medvdv 1:17443d6d2740 253 if (fill < 0.0) fill = 0.0;
medvdv 1:17443d6d2740 254 if (fill > 1.0) fill = 1.0;
medvdv 1:17443d6d2740 255
medvdv 1:17443d6d2740 256 int a = (width - 2)*fill;
medvdv 1:17443d6d2740 257 int b = width - 2 - a;
medvdv 1:17443d6d2740 258
medvdv 1:17443d6d2740 259 Write(LCD_BAR_B);
medvdv 1:17443d6d2740 260 Write(LCD_BAR_F, a);
medvdv 1:17443d6d2740 261 Write(LCD_BAR_U, b);
medvdv 1:17443d6d2740 262 Write(LCD_BAR_E);
medvdv 1:17443d6d2740 263
medvdv 1:17443d6d2740 264 }