* mbed demo: * Software PWM on the mbed LEDs. Counting in trinary using off, half bright and full on LEDs. * Smooth scrolling a graphic on a 16x2 LCD display (using ST7066U controller). * * 2012-05-09 John Schooling The code is not in a library but gives you what you need in one file to add the required code to your own library.

Dependencies:   mbed

Committer:
JohnSchooling
Date:
Wed May 09 14:40:46 2012 +0000
Revision:
1:f0561ba3d266
Parent:
0:514531f6b9db

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JohnSchooling 0:514531f6b9db 1 /*
JohnSchooling 0:514531f6b9db 2 * mbed demo:
JohnSchooling 0:514531f6b9db 3 * Software PWM on the mbed LEDs. Counting in trinary using off, half bright and full on LEDs.
JohnSchooling 0:514531f6b9db 4 * Smooth scrolling a graphic on a 16x2 LCD display (using ST7066U controller).
JohnSchooling 0:514531f6b9db 5 *
JohnSchooling 0:514531f6b9db 6 * 2012-05-09 John Schooling
JohnSchooling 0:514531f6b9db 7 *
JohnSchooling 0:514531f6b9db 8 */
JohnSchooling 0:514531f6b9db 9
JohnSchooling 0:514531f6b9db 10 #include "mbed.h"
JohnSchooling 0:514531f6b9db 11
JohnSchooling 0:514531f6b9db 12 #define LCD_RS_DATA 1
JohnSchooling 0:514531f6b9db 13 #define LCD_RS_INST 0
JohnSchooling 0:514531f6b9db 14
JohnSchooling 0:514531f6b9db 15 /*
JohnSchooling 0:514531f6b9db 16 Crystalfontz CFAH1602BTMIJT 16x2 LCD display.
JohnSchooling 0:514531f6b9db 17 http://www.coolcomponents.co.uk/catalog/blue-16x2-display-p-151.html (also part of mbed starter kit).
JohnSchooling 0:514531f6b9db 18
JohnSchooling 0:514531f6b9db 19 Sitronix ST7066U functions (compatible with Hitachi HD44780).
JohnSchooling 0:514531f6b9db 20 CFAH1602BTMIJT_v1.0.pdf
JohnSchooling 0:514531f6b9db 21 http://www.crystalfontz.com/controllers/ST7066U.pdf
JohnSchooling 0:514531f6b9db 22
JohnSchooling 0:514531f6b9db 23 LCD initialisation takes 40ms.
JohnSchooling 0:514531f6b9db 24
JohnSchooling 0:514531f6b9db 25 Instruction RS RW 7 6 5 4 3 2 1 0 Time (270kHz)
JohnSchooling 0:514531f6b9db 26 Clear Display 0 0 0 0 0 0 0 0 0 1 1.52 ms Clear, Home, Entry Mode = Increment.
JohnSchooling 0:514531f6b9db 27 Return Home 0 0 0 0 0 0 0 0 1 x 1.52 ms.
JohnSchooling 0:514531f6b9db 28 Entry Mode Set 0 0 0 0 0 0 0 1 I S .037ms Increment cursor, Shift display (shift cursor).
JohnSchooling 0:514531f6b9db 29 Display On/Off 0 0 0 0 0 0 1 D C P .037ms Display on, Cursor on, Position on.
JohnSchooling 0:514531f6b9db 30 Cursor or Display Shift 0 0 0 0 0 1 D R x x .037ms Display shift (cursor shift), Right (left).
JohnSchooling 0:514531f6b9db 31 Function Set 0 0 0 0 1 D N F x x .037ms Data interface 8 (4) bits, Number of lines 2 (1), Font 5x11 if 1 line (5x8).
JohnSchooling 0:514531f6b9db 32 Set CGRAM address 0 0 0 1 A A A A A A .037ms Set 6 bit CGRAM address in address counter.
JohnSchooling 0:514531f6b9db 33 Set DDRAM address 0 0 1 A A A A A A A .037ms Set 7 bit DDRAM address in address counter.
JohnSchooling 0:514531f6b9db 34 Read Busy Flag and addr 0 1 F A A A A A A A .000ms Read Busy Flag and address counter.
JohnSchooling 0:514531f6b9db 35 Write data to RAM 1 0 A A A A A A A A .037ms Write data to RAM (DDRAM or CGRAM). Must do Set address first.
JohnSchooling 0:514531f6b9db 36 Read data from RAM 1 1 A A A A A A A A .037ms Read data from internal RAM (DDRAM or CGRAM). Must do Set address first.
JohnSchooling 0:514531f6b9db 37 */
JohnSchooling 0:514531f6b9db 38
JohnSchooling 0:514531f6b9db 39 int face1[8][8] = {
JohnSchooling 0:514531f6b9db 40 {0x01, 0x02, 0x04, 0x08, 0x13, 0x14, 0x14, 0x13} // Top left.
JohnSchooling 0:514531f6b9db 41 , {0x1F, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x04}
JohnSchooling 0:514531f6b9db 42 , {0x10, 0x08, 0x04, 0x02, 0x19, 0x05, 0x05, 0x19}
JohnSchooling 0:514531f6b9db 43 , {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // Top right.
JohnSchooling 0:514531f6b9db 44
JohnSchooling 0:514531f6b9db 45 , {0x10, 0x10, 0x12, 0x11, 0x09, 0x04, 0x02, 0x01} // Bottom left.
JohnSchooling 0:514531f6b9db 46 , {0x04, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x1F}
JohnSchooling 0:514531f6b9db 47 , {0x01, 0x01, 0x09, 0x11, 0x12, 0x04, 0x08, 0x10}
JohnSchooling 0:514531f6b9db 48 , {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // Bottom right.
JohnSchooling 0:514531f6b9db 49 };
JohnSchooling 0:514531f6b9db 50 int face2[8][8] = {
JohnSchooling 0:514531f6b9db 51 {0x01, 0x06, 0x0C, 0x18, 0x30, 0x33, 0x36, 0x36} // Top left.
JohnSchooling 0:514531f6b9db 52 , {0x3F, 0x00, 0x00, 0x00, 0x00, 0x21, 0x33, 0x33}
JohnSchooling 0:514531f6b9db 53 , {0x20, 0x18, 0x0C, 0x06, 0x03, 0x33, 0x1B, 0x1B}
JohnSchooling 0:514531f6b9db 54 , {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // Top right.
JohnSchooling 0:514531f6b9db 55
JohnSchooling 0:514531f6b9db 56 , {0x33, 0x30, 0x33, 0x1B, 0x19, 0x0C, 0x06, 0x01} // Bottom left.
JohnSchooling 0:514531f6b9db 57 , {0x21, 0x00, 0x00, 0x00, 0x21, 0x3F, 0x00, 0x3F}
JohnSchooling 0:514531f6b9db 58 , {0x33, 0x03, 0x33, 0x36, 0x26, 0x0C, 0x18, 0x20}
JohnSchooling 0:514531f6b9db 59 , {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // Bottom right.
JohnSchooling 0:514531f6b9db 60 };
JohnSchooling 0:514531f6b9db 61
JohnSchooling 0:514531f6b9db 62 DigitalOut lcd_rs(p5);
JohnSchooling 0:514531f6b9db 63 DigitalOut lcd_rw(p6);
JohnSchooling 0:514531f6b9db 64 DigitalOut lcd_e(p7);
JohnSchooling 0:514531f6b9db 65 DigitalOut lcd_db0(p8);
JohnSchooling 0:514531f6b9db 66 DigitalOut lcd_db1(p9);
JohnSchooling 0:514531f6b9db 67 DigitalOut lcd_db2(p10);
JohnSchooling 0:514531f6b9db 68 DigitalOut lcd_db3(p11);
JohnSchooling 0:514531f6b9db 69 DigitalOut lcd_db4(p12);
JohnSchooling 0:514531f6b9db 70 DigitalOut lcd_db5(p13);
JohnSchooling 0:514531f6b9db 71 DigitalOut lcd_db6(p14);
JohnSchooling 0:514531f6b9db 72 DigitalOut lcd_db7(p15);
JohnSchooling 0:514531f6b9db 73
JohnSchooling 0:514531f6b9db 74
JohnSchooling 0:514531f6b9db 75 DigitalOut myled1(LED1);
JohnSchooling 0:514531f6b9db 76 DigitalOut myled2(LED2);
JohnSchooling 0:514531f6b9db 77 DigitalOut myled3(LED3);
JohnSchooling 0:514531f6b9db 78 DigitalOut myled4(LED4);
JohnSchooling 0:514531f6b9db 79
JohnSchooling 0:514531f6b9db 80
JohnSchooling 0:514531f6b9db 81 void lcd_write(int c, int rs) {
JohnSchooling 0:514531f6b9db 82 int old_lcd_rs = lcd_rs;
JohnSchooling 0:514531f6b9db 83 // Should check Busy Flag here.
JohnSchooling 0:514531f6b9db 84 lcd_rs = rs;
JohnSchooling 0:514531f6b9db 85 lcd_e = 1; // E must be on for min 480ns then drop to zero. Trigger is on falling signal.
JohnSchooling 0:514531f6b9db 86 lcd_db0 = c & 1;
JohnSchooling 0:514531f6b9db 87 lcd_db1 = c>>1 & 1;
JohnSchooling 0:514531f6b9db 88 lcd_db2 = c>>2 & 1;
JohnSchooling 0:514531f6b9db 89 lcd_db3 = c>>3 & 1;
JohnSchooling 0:514531f6b9db 90 lcd_db4 = c>>4 & 1;
JohnSchooling 0:514531f6b9db 91 lcd_db5 = c>>5 & 1;
JohnSchooling 0:514531f6b9db 92 lcd_db6 = c>>6 & 1;
JohnSchooling 0:514531f6b9db 93 lcd_db7 = c>>7 & 1;
JohnSchooling 0:514531f6b9db 94 // Tdsw Data Setup Width time at least 80ns. No need for delay on slow processor.
JohnSchooling 0:514531f6b9db 95 lcd_e = 0; // Strobe.
JohnSchooling 0:514531f6b9db 96 // Th Data Hold time at least 10ns. No need for delay on slow processor.
JohnSchooling 0:514531f6b9db 97 wait(0.000037); // Most instructions take 37us. May not need this delay if Busy Flag checked at top.
JohnSchooling 0:514531f6b9db 98 lcd_rs = old_lcd_rs;
JohnSchooling 0:514531f6b9db 99 }
JohnSchooling 0:514531f6b9db 100
JohnSchooling 0:514531f6b9db 101 void lcd_write_data(uint8_t c) {
JohnSchooling 0:514531f6b9db 102 lcd_write(c, LCD_RS_DATA); // Data
JohnSchooling 0:514531f6b9db 103 }
JohnSchooling 0:514531f6b9db 104 void lcd_write_inst(uint8_t c) {
JohnSchooling 0:514531f6b9db 105 lcd_write(c, LCD_RS_INST); // Instruction
JohnSchooling 0:514531f6b9db 106 }
JohnSchooling 0:514531f6b9db 107
JohnSchooling 0:514531f6b9db 108 void lcd_clear(void) {
JohnSchooling 0:514531f6b9db 109 lcd_write_inst(1); //
JohnSchooling 0:514531f6b9db 110 wait(0.00152); // clear takes 1.52 ms.
JohnSchooling 0:514531f6b9db 111 }
JohnSchooling 0:514531f6b9db 112 void lcd_home(void) {
JohnSchooling 0:514531f6b9db 113 lcd_write_inst(2); //
JohnSchooling 0:514531f6b9db 114 wait(0.00152); // home takes 1.52 ms.
JohnSchooling 0:514531f6b9db 115 }
JohnSchooling 0:514531f6b9db 116
JohnSchooling 0:514531f6b9db 117 void lcd_write_str(uint8_t *str, uint8_t x = 0, uint8_t y = 0) {
JohnSchooling 0:514531f6b9db 118 uint8_t *c = str;
JohnSchooling 0:514531f6b9db 119 lcd_write_inst(0x80 + y * 0x40 + x); // 1 A A A A A A A Set 7 bit DDRAM address in address counter
JohnSchooling 0:514531f6b9db 120 for (uint8_t i = 0; i < 80 && (*c); i++) { // Will never write more than 80 chars.
JohnSchooling 0:514531f6b9db 121 lcd_write_data(*c);
JohnSchooling 0:514531f6b9db 122 c++;
JohnSchooling 0:514531f6b9db 123 }
JohnSchooling 0:514531f6b9db 124 }
JohnSchooling 0:514531f6b9db 125
JohnSchooling 0:514531f6b9db 126 void scroll_face(void) {
JohnSchooling 0:514531f6b9db 127 int pict[8][8];
JohnSchooling 0:514531f6b9db 128 memcpy(pict, face2, sizeof(pict));
JohnSchooling 0:514531f6b9db 129 // Write the graphic characters to CGRAM.
JohnSchooling 0:514531f6b9db 130 lcd_write_inst(0x40); // 0 1 A A A A A A Set 6 bit CGRAM address in address counter
JohnSchooling 0:514531f6b9db 131 for (int i = 0; i < 64; i++) {
JohnSchooling 0:514531f6b9db 132 lcd_write_data((uint8_t)pict[i/8][i%8]);
JohnSchooling 0:514531f6b9db 133 }
JohnSchooling 0:514531f6b9db 134 // Display the graphic characters.
JohnSchooling 0:514531f6b9db 135 lcd_write_inst(0x80); // 1 A A A A A A A Set 7 bit DDRAM address in address counter
JohnSchooling 0:514531f6b9db 136 lcd_write_data(3); // Top right of graphic.
JohnSchooling 0:514531f6b9db 137 lcd_write_inst(0xC0); // 1 A A A A A A A Set 7 bit DDRAM address in address counter
JohnSchooling 0:514531f6b9db 138 lcd_write_data(7); // Bottom right of graphic.
JohnSchooling 0:514531f6b9db 139
JohnSchooling 0:514531f6b9db 140 for (int n = 0; n < 19; n++) {
JohnSchooling 0:514531f6b9db 141 for (int k = 0; k < 6; k++) { // 6 bit Smooth scrolling avoiding jump between characters on display.
JohnSchooling 0:514531f6b9db 142 // Write the graphic characters to CGRAM.
JohnSchooling 0:514531f6b9db 143 lcd_write_inst(0x40); // 0 1 A A A A A A Set 6 bit CGRAM address in address counter
JohnSchooling 0:514531f6b9db 144 for (int i = 63; i >= 0; i--) {
JohnSchooling 0:514531f6b9db 145 if (i/8 == 0 || i/8 == 4) {
JohnSchooling 1:f0561ba3d266 146 pict[i/8][i%8] |= ((pict[i/8 +3][i%8] &1) << 6); // Put right hand low bit into bit 6.
JohnSchooling 0:514531f6b9db 147 } else {
JohnSchooling 1:f0561ba3d266 148 pict[i/8][i%8] |= ((pict[i/8 -1][i%8] &1) << 6); // Put previous low bit into bit 6.
JohnSchooling 0:514531f6b9db 149 }
JohnSchooling 0:514531f6b9db 150 }
JohnSchooling 0:514531f6b9db 151 for (int i = 0; i < 64; i++) {
JohnSchooling 0:514531f6b9db 152 pict[i/8][i%8] >>= 1; // Scroll the character.
JohnSchooling 0:514531f6b9db 153 lcd_write_data((uint8_t)pict[i/8][i%8]); // Write to LCD.
JohnSchooling 0:514531f6b9db 154 }
JohnSchooling 0:514531f6b9db 155 wait(0.1);
JohnSchooling 0:514531f6b9db 156 }
JohnSchooling 0:514531f6b9db 157 if(n >= 3) {
JohnSchooling 0:514531f6b9db 158 // Graphic has moved on a whole character. Replace left characters with a space.
JohnSchooling 0:514531f6b9db 159 lcd_write_inst(0x80 + n - 3); // 1 A A A A A A A Set 7 bit DDRAM address in address counter
JohnSchooling 0:514531f6b9db 160 lcd_write_data(32);
JohnSchooling 0:514531f6b9db 161 lcd_write_inst(0xC0 + n - 3); // 1 A A A A A A A Set 7 bit DDRAM address in address counter
JohnSchooling 0:514531f6b9db 162 lcd_write_data(32);
JohnSchooling 0:514531f6b9db 163 }
JohnSchooling 0:514531f6b9db 164 // Set right side of graphic to correct characters.
JohnSchooling 0:514531f6b9db 165 lcd_write_inst(0x81 + n); // 1 A A A A A A A Set 7 bit DDRAM address in address counter
JohnSchooling 0:514531f6b9db 166 lcd_write_data(n%4);
JohnSchooling 0:514531f6b9db 167 lcd_write_inst(0xC1 + n); // 1 A A A A A A A Set 7 bit DDRAM address in address counter
JohnSchooling 0:514531f6b9db 168 lcd_write_data(n%4 + 4);
JohnSchooling 0:514531f6b9db 169 }
JohnSchooling 0:514531f6b9db 170 }
JohnSchooling 0:514531f6b9db 171
JohnSchooling 0:514531f6b9db 172 void scroll_bar(void) {
JohnSchooling 0:514531f6b9db 173
JohnSchooling 0:514531f6b9db 174 // Scrolling vertical bar to clear the screen.
JohnSchooling 0:514531f6b9db 175 // Bar is two lines (smoother scrolling and more visible than a single line).
JohnSchooling 0:514531f6b9db 176 // There are six combinations for each of the available five bits. Avoids jump between characters on display.
JohnSchooling 0:514531f6b9db 177 // Character number 7 is used for the graphic (0-5 are used by the face). Earlier version left face on screen.
JohnSchooling 0:514531f6b9db 178 for (int i = 0; i < 6 * 17; i++) { // 6 positions for each of 17 characters.
JohnSchooling 0:514531f6b9db 179 lcd_write_inst(0x40 + 7 * 8); // 0 1 A A A A A A Set 6 bit CGRAM address in address counter
JohnSchooling 0:514531f6b9db 180 for (int j = 0; j < 8; j++) {
JohnSchooling 0:514531f6b9db 181 lcd_write_data((3 << (5 - i%6)) >> 1); // Fill 8 bytes for vertical bar character in Character Generator RAM.
JohnSchooling 0:514531f6b9db 182 }
JohnSchooling 0:514531f6b9db 183 lcd_write_inst(0x80 + i / 6 - (i >= 6)); // 1 A A A A A A A Set 7 bit DDRAM address in address counter
JohnSchooling 0:514531f6b9db 184 if (i >= 6) lcd_write_data(0x20);
JohnSchooling 0:514531f6b9db 185 lcd_write_data(7); // Top row.
JohnSchooling 0:514531f6b9db 186 lcd_write_inst(0xC0 + i / 6 - (i >= 6)); // 1 A A A A A A A Set 7 bit DDRAM address in address counter
JohnSchooling 0:514531f6b9db 187 if (i >= 6) lcd_write_data(0x20);
JohnSchooling 0:514531f6b9db 188 lcd_write_data(7); // Bottom row.
JohnSchooling 0:514531f6b9db 189 wait(0.075);
JohnSchooling 0:514531f6b9db 190 }
JohnSchooling 0:514531f6b9db 191 }
JohnSchooling 0:514531f6b9db 192
JohnSchooling 0:514531f6b9db 193 int main() {
JohnSchooling 0:514531f6b9db 194
JohnSchooling 0:514531f6b9db 195 uint32_t a = 0; // Main PWM loop counter.
JohnSchooling 0:514531f6b9db 196 uint16_t b;
JohnSchooling 0:514531f6b9db 197 int16_t i;
JohnSchooling 0:514531f6b9db 198 uint16_t e4[] = {0, 20, 256}; // LED brightness.
JohnSchooling 0:514531f6b9db 199 uint8_t str[17]; // String for writing to the LCD display.
JohnSchooling 0:514531f6b9db 200
JohnSchooling 0:514531f6b9db 201 wait(0.040); // LCD initialisation takes 40ms.
JohnSchooling 0:514531f6b9db 202 lcd_clear();
JohnSchooling 0:514531f6b9db 203 lcd_write_inst(0x0C); // 0000 1DCB Display=1 Cursor=0 Blink=0
JohnSchooling 0:514531f6b9db 204 lcd_write_inst(0x38); // 001D NFxx Data interface 8 (4) bits, Number of lines 2 (1), Font 5x11 if 1 line (5x8)
JohnSchooling 0:514531f6b9db 205
JohnSchooling 0:514531f6b9db 206 lcd_write_str((uint8_t *)"Trinary", 4, 0);
JohnSchooling 0:514531f6b9db 207 lcd_write_str((uint8_t *)"Counter", 4, 1);
JohnSchooling 0:514531f6b9db 208
JohnSchooling 0:514531f6b9db 209 // Flash display off/on a couple of times.
JohnSchooling 0:514531f6b9db 210 for (int i = 0; i < 2; i++) {
JohnSchooling 0:514531f6b9db 211 wait(0.5);
JohnSchooling 0:514531f6b9db 212 lcd_write_inst(0x08); // 0000 1DCB Display=0 Cursor=0 Blink=0
JohnSchooling 0:514531f6b9db 213 wait(0.5);
JohnSchooling 0:514531f6b9db 214 lcd_write_inst(0x0C); // 0000 1DCB Display=1 Cursor=0 Blink=0
JohnSchooling 0:514531f6b9db 215 }
JohnSchooling 0:514531f6b9db 216
JohnSchooling 0:514531f6b9db 217 wait(1);
JohnSchooling 0:514531f6b9db 218 scroll_face();
JohnSchooling 0:514531f6b9db 219 //scroll_bar();
JohnSchooling 0:514531f6b9db 220
JohnSchooling 0:514531f6b9db 221 // Trinary counting.
JohnSchooling 0:514531f6b9db 222 // Use the mbed LEDs to display trinary values (using software PWM) to count from zero to 80 (trinary 2222).
JohnSchooling 0:514531f6b9db 223 // LED brightness: off = 0, half bright = 1, full on = 2.
JohnSchooling 0:514531f6b9db 224 i = 80; // Force next display value to be zero: (80 + 1) % 81.
JohnSchooling 0:514531f6b9db 225 while (1) {
JohnSchooling 0:514531f6b9db 226 if (a == 0) {
JohnSchooling 0:514531f6b9db 227 // Counter expired: display the next value.
JohnSchooling 0:514531f6b9db 228 i = (i + 1) % 81;
JohnSchooling 0:514531f6b9db 229 // Write decimal and trinary.
JohnSchooling 0:514531f6b9db 230 sprintf((char *)str, "dec %2d tri %d%d%d%d", i, (i / 27) % 3, (i / 9) % 3, (i / 3) % 3, i % 3);
JohnSchooling 0:514531f6b9db 231 lcd_write_str(str);
JohnSchooling 0:514531f6b9db 232 // Write hex and binary.
JohnSchooling 0:514531f6b9db 233 sprintf((char *)str, "0x%2.2X 0b0%d%d%d%d%d%d%d", i, i>>6&1, i>>5&1, i>>4&1, i>>3&1, i>>2&1, i>>1&1, i&1);
JohnSchooling 0:514531f6b9db 234 lcd_write_str(str, 0, 1);
JohnSchooling 0:514531f6b9db 235 }
JohnSchooling 0:514531f6b9db 236 b = a & 0xFF;
JohnSchooling 0:514531f6b9db 237 // PWM for mbed LEDs. e4 contains the brightness for trit values 0, 1 and 2.
JohnSchooling 0:514531f6b9db 238 myled4 = b < e4[ i % 3] ? 1 : 0;
JohnSchooling 0:514531f6b9db 239 myled3 = b < e4[(i / 3) % 3] ? 1 : 0;
JohnSchooling 0:514531f6b9db 240 myled2 = b < e4[(i / 9) % 3] ? 1 : 0;
JohnSchooling 0:514531f6b9db 241 myled1 = b < e4[(i / 27) % 3] ? 1 : 0;
JohnSchooling 0:514531f6b9db 242 a = (a + 1) & 0x7FFFF; // Loop counter.
JohnSchooling 0:514531f6b9db 243 }
JohnSchooling 0:514531f6b9db 244 }