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.
Fork of LCD_nonblocking_demo by
LCD_nonblocking.cpp
00001 /* mbed TextLCD Library, for a 4-bit LCD based on HD44780 00002 * Copyright (c) 2007-2010, sford, http://mbed.org 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy 00005 * of this software and associated documentation files (the "Software"), to deal 00006 * in the Software without restriction, including without limitation the rights 00007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00008 * copies of the Software, and to permit persons to whom the Software is 00009 * furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included in 00012 * all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00020 * THE SOFTWARE. 00021 */ 00022 00023 #include "LCD_nonblocking.h" 00024 #include "mbed.h" 00025 00026 00027 00028 00029 00030 TextLCD::TextLCD(PinName rs, PinName e, PinName d4, PinName d5, 00031 PinName d6, PinName d7, LCDType type) : busy(0),_rs(rs), 00032 _e(e), _d(d4, d5, d6, d7), 00033 _type(type) , _column(0),_row(0), 00034 _head(0), _tail(0) {} 00035 void TextLCD::init() 00036 { 00037 00038 busy=1; 00039 _rs = 1; 00040 _d = 0; 00041 wait_us(1); 00042 _e = 0; 00043 _rs = 0; // command mode 00044 timer.attach_us(this,&TextLCD::init2,15000); 00045 } 00046 void TextLCD::init2() 00047 { 00048 _rs = 0; 00049 _d = 0x3; 00050 _e = 1; 00051 wait_us(1); 00052 _e = 0; 00053 timer.attach_us(this,&TextLCD::init2b,4100); 00054 } 00055 void TextLCD::init2b() 00056 { 00057 00058 _d = 0x3; 00059 _e = 1; 00060 wait_us(1); 00061 _e = 0; 00062 timer.attach_us(this,&TextLCD::init3,4100); 00063 } 00064 void TextLCD::init3() 00065 { 00066 _d = 0x3; 00067 _e = 1; 00068 wait_us(1); 00069 _e = 0; 00070 timer.attach_us(this,&TextLCD::init4,1000); 00071 } 00072 void TextLCD::init4() 00073 { 00074 _d = 0x2; 00075 _e = 1; 00076 wait_us(1); 00077 _e = 0; 00078 timer.attach_us(this,&TextLCD::init5,60); 00079 } 00080 void TextLCD::init5() 00081 { 00082 00083 writeByte(0x28); // Function set 001 BW N F - - 00084 timer.attach_us(this,&TextLCD::init6,60); 00085 } 00086 void TextLCD::init6() 00087 { 00088 writeByte(0x0C); 00089 timer.attach_us(this,&TextLCD::init7,60); 00090 } 00091 void TextLCD::init7() 00092 { 00093 writeByte(0x6); // Cursor Direction and Display Shift : 0000 01 CD S (CD 0-left, 1-right S(hift) 0-no, 1-yes 00094 timer.attach_us(this,&TextLCD::init8,60); 00095 } 00096 void TextLCD::init8() 00097 { 00098 writeByte(0x01); // cls, and set cursor to 0 00099 // This command takes 1.64 ms 00100 locate(0, 0); 00101 timer.attach_us(this,&TextLCD::locate_cb,1640); 00102 } 00103 /* 00104 void TextLCD::character(int column, int row, int c) 00105 { 00106 int a = address(column, row); 00107 writeCommand(a); 00108 writeData(c); 00109 } 00110 */ 00111 void TextLCD::cls() 00112 { 00113 busy=1; 00114 writeByte(0x01); // cls, and set cursor to 0 00115 // This command takes 1.64 ms 00116 locate(0, 0); 00117 timer.attach_us(this,&TextLCD::locate_cb,1640); 00118 } 00119 00120 void TextLCD::locate(int column, int row) 00121 { 00122 _column = column; 00123 _row = row; 00124 } 00125 /* this is the general buffered-write callback for writing text to the display 00126 * it normally chains to itself unless a newline occurs in which case it chains to 00127 * locate_cb 00128 * or the buffer runs out in which case it clears busy and does not chain 00129 */ 00130 00131 void TextLCD::callback() 00132 { 00133 if (_tail<_head) { 00134 int value=_queue[_tail++]; 00135 if (value == '\n') { 00136 _column = 0; 00137 _row++; 00138 if (_row >= rows()) { 00139 _row = 0; 00140 } 00141 locate_cb(); // newline isn't printed so go straight to "locate" code 00142 } else { 00143 _rs = 1; // data mode 00144 writeByte(value); 00145 _column++; 00146 if (_column >= columns()) { //if we've reached the end of line then chain to "locate" 00147 //otherwise go back to callback 00148 _column = 0; 00149 _row++; 00150 if (_row >= rows()) { 00151 _row = 0; 00152 } 00153 timer.attach_us(this,&TextLCD::locate_cb,60); 00154 } else { 00155 timer.attach_us(this,&TextLCD::callback,60); 00156 } 00157 00158 } 00159 00160 } else { //if we've run out of text then clear flag 00161 _head=_tail=0; 00162 busy=0; 00163 } 00164 } 00165 00166 void TextLCD::locate_cb() 00167 { 00168 int a = address(_column, _row); 00169 _rs=0; 00170 writeByte(a); 00171 timer.attach_us(this,&TextLCD::callback,60); 00172 } 00173 00174 00175 int TextLCD::_putc(int value) 00176 { 00177 if (_head<40) { 00178 _queue[_head++]=value; 00179 }; 00180 if (busy==0) { 00181 busy=1; 00182 locate_cb(); // set cursor position before text 00183 /* 00184 int a = address(_column, _row); 00185 _rs=0; 00186 writeByte(a); 00187 timer.attach_us(this,&TextLCD::callback,60); 00188 */ 00189 }; 00190 return value; 00191 } 00192 00193 /*{ 00194 if (value == '\n') { 00195 _column = 0; 00196 _row++; 00197 if (_row >= rows()) { 00198 _row = 0; 00199 } 00200 } else { 00201 character(_column, _row, value); 00202 _column++; 00203 if (_column >= columns()) { 00204 _column = 0; 00205 _row++; 00206 if (_row >= rows()) { 00207 _row = 0; 00208 } 00209 } 00210 } 00211 return value; 00212 } 00213 */ 00214 int TextLCD::_getc() 00215 { 00216 return -1; 00217 } 00218 00219 void TextLCD::writeByte(int value) 00220 { 00221 _d = value >> 4; 00222 _e = 1; 00223 wait_us(1); 00224 _e = 0; 00225 _d = value >> 0; 00226 wait_us(2); 00227 _e = 1; 00228 wait_us(1); // most instructions take 40us 00229 _e = 0; 00230 } 00231 00232 void TextLCD::writeCommand(int command) 00233 { 00234 _rs = 0; //command mode 00235 wait_us(50); // most instructions take 40us 00236 writeByte(command); 00237 } 00238 00239 void TextLCD::writeData(int data) 00240 { 00241 _rs = 1; // data mode 00242 wait_us(50); // most instructions take 40us 00243 writeByte(data); 00244 } 00245 00246 int TextLCD::address(int column, int row) 00247 { 00248 switch (_type) { 00249 case LCD20x4: 00250 switch (row) { 00251 case 0: 00252 return 0x80 + column; 00253 case 1: 00254 return 0xc0 + column; 00255 case 2: 00256 return 0x94 + column; 00257 case 3: 00258 return 0xd4 + column; 00259 } 00260 case LCD16x2B: 00261 return 0x80 + (row * 40) + column; 00262 case LCD16x2: 00263 case LCD20x2: 00264 default: 00265 return 0x80 + (row * 0x40) + column; 00266 } 00267 } 00268 00269 int TextLCD::columns() 00270 { 00271 switch (_type) { 00272 case LCD20x4: 00273 case LCD20x2: 00274 return 20; 00275 case LCD16x2: 00276 case LCD16x2B: 00277 default: 00278 return 16; 00279 } 00280 } 00281 00282 int TextLCD::rows() 00283 { 00284 switch (_type) { 00285 case LCD20x4: 00286 return 4; 00287 case LCD16x2: 00288 case LCD16x2B: 00289 case LCD20x2: 00290 default: 00291 return 2; 00292 } 00293 }
Generated on Thu Jul 14 2022 06:25:34 by
1.7.2
