Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
TextLCD.cpp
00001 /* mbed TextLCD Library 00002 * Copyright (c) 2007-2009 sford 00003 * Released under the MIT License: http://mbed.org/license/mit 00004 * 00005 * Modified by Ned Konz to provide better support for 4-line LCDs and ones with other controller chips. 00006 */ 00007 00008 #include "TextLCD.h" 00009 #include "mbed.h" 00010 00011 /* 00012 * useful info found at http://www.a-netz.de/lcd.en.php 00013 * 00014 * Initialisation 00015 * ============== 00016 * 00017 * After attaching the supply voltage/after a reset, the display needs to be brought in to a defined state 00018 * 00019 * - wait approximately 15 ms so the display is ready to execute commands 00020 * - Execute the command 0x30 ("Display Settings") three times (wait 1,64ms after each command, the busy flag cannot be queried now). 00021 * - The display is in 8 bit mode, so if you have only connected 4 data pins you should only transmit the higher nibble of each command. 00022 * - If you want to use the 4 bit mode, now you can execute the command to switch over to this mode now. 00023 * - Execute the "clear display" command 00024 * 00025 * Timing 00026 * ====== 00027 * 00028 * Nearly all commands transmitted to the display need 40us for execution. 00029 * Exceptions are the commands "Clear Display and Reset" and "Set Cursor to Start Position" 00030 * These commands need 1.64ms for execution. These timings are valid for all displays working with an 00031 * internal clock of 250kHz. But I do not know any displays that use other frequencies. Any time you 00032 * can use the busy flag to test if the display is ready to accept the next command. 00033 * 00034 * _e is kept low except when being used. 00035 * _rw is kept 0 (write) apart from actions that use it differently 00036 * _rs is set by the data/command writes 00037 */ 00038 00039 TextLCD::TextLCD(PinName rs, PinName rw, PinName e, PinName d0, PinName d1, 00040 PinName d2, PinName d3, uint16_t rows, uint16_t cols) : _rw(rw), _rs(rs), 00041 _e(e), _d(d0, d1, d2, d3), _rows(rows), _columns(cols) { 00042 00043 _rw = 0; 00044 wait_us(1); // min. 100nsec delay 00045 _e = 0; 00046 _rs = 0; // command mode 00047 _d.output(); 00048 00049 reset(); 00050 cls(); 00051 } 00052 00053 void TextLCD::reset() { 00054 wait_ms(15); 00055 // e is low at this point, as is rw. 00056 // 2. Send 0x3 and wait 150 ms (will stay in 8-bit mode if already there) 00057 writeHalfByte(0x3); 00058 wait_ms(5); 00059 // 3. Send 0x3 and wait 150 ms (will go to 8-bit mode if was in 4-bit without any garbage nibble) 00060 writeHalfByte(0x3); 00061 wait_ms(5); 00062 // 4. Send 0x3 and wait 250 ms (will go to 8-bit mode even if garbage nibble was previously received) 00063 writeHalfByte(0x3); 00064 wait_ms(5); 00065 // 5. Send 0x2 and wait 200 ms (should go to 4-bit mode now) 00066 writeHalfByte(0x2); 00067 wait_ms(5); 00068 // 7. Send LCD setup sequence (eg 0x2, 0x8 (=0x28), 0x0, 0x8 (=0x08), etc.) 00069 writeCommand(0x28); // Function set 001 BW N F - - 00070 wait_ms(15); 00071 00072 writeCommand(0x08); // display off, cursor invisible 00073 wait_ms(15); 00074 00075 writeCommand(0x01); 00076 wait_ms(15); // 1.64ms command 00077 00078 writeCommand(0x0C); // display enabled, cursor invisible 00079 wait_ms(15); 00080 00081 writeCommand(0x6); // Cursor Direction and Display Shift : 0000 01 CD S (CD 0-left, 1-right S(hift) 0-no, 1-yes 00082 wait_ms(15); 00083 00084 locate(0,0); 00085 } 00086 00087 // memory starts at 0x80, and is 0x40 chars long per row 00088 // However, rows 2 and 3 of 4-line displays are actually adjacent to rows 0 and 1. 00089 // 16x4 displays are addressed the same way as 20x4 ones. 00090 00091 void TextLCD::character(uint16_t column, uint16_t row, int c) { 00092 int address; 00093 address = 0x80 + ((row & ~2) * 0x40) + column; 00094 if (row > 1) 00095 address += 20; 00096 writeCommand(address); 00097 writeData(c); 00098 } 00099 00100 void TextLCD::writeHalfByte(uint16_t value) { 00101 _e = 1; 00102 wait_us(1); 00103 _d = value & 0x0F; // send data on bus 00104 wait_us(1); // setup time 00105 _e = 0; // strobe 00106 wait_us(1); // hold time 00107 } 00108 00109 void TextLCD::writeByte(uint16_t value) { 00110 writeHalfByte(value>>4); 00111 writeHalfByte(value); 00112 } 00113 00114 void TextLCD::writeCommand(uint16_t command) { 00115 _rs = 0; 00116 writeByte(command); 00117 waitUntilDone(); 00118 } 00119 00120 void TextLCD::writeData(uint16_t data) { 00121 _rs = 1; 00122 writeByte(data); 00123 waitUntilDone(); 00124 } 00125 00126 void TextLCD::cls() { 00127 writeCommand(0x01); 00128 wait_us(2000); // 1.64ms command 00129 locate(0,0); 00130 } 00131 00132 // This should be changed to use readAddressAndBusy() when that works. 00133 void TextLCD::waitUntilDone() { 00134 wait_us(60); 00135 } 00136 00137 // Return the busy/address byte. 00138 // The busy flag is the high bit. 00139 // Not yet working reliably. 00140 uint16_t TextLCD::readAddressAndBusy() { 00141 _d.input(); 00142 _rw = 1; 00143 wait_us(1); 00144 _e = 1; 00145 wait_us(1); 00146 _e = 0; 00147 00148 uint16_t retval = _d.read() << 4; 00149 00150 wait_us(1); 00151 _e = 1; 00152 wait_us(1); 00153 _e = 0; 00154 00155 retval |= _d.read(); 00156 _rw = 0; 00157 00158 _d.output(); 00159 return retval; 00160 } 00161
Generated on Thu Jul 14 2022 21:44:21 by
1.7.2