TextLCD_595 - this change module NewTextLCD Erik Kerger. It adds the ability to output a simple Russian text, as well as some additional features implemented chip HD44780. The test was carried out on the module module MT-16S2D. The display is connected via SPI bus through to the shift register 74595 (74HC595)
Fork of TextLCD_Rus by
TextLCD_595.cpp
00001 /* mbed TextLCD_595 Library, for a 4-bit LCD based on HD44780 00002 * Copyright (c) 2007-2010, sford, http://mbed.org 00003 * Changes by Erik Kerger 00004 * 00005 * 00006 * Changes by Bogomazyuk Vasiliy (Богомазюк Василий) 00007 * Модуль испытан на жидкокристаллическом модуле MT–16S2D 00008 * 00009 * 00010 * 00011 * Permission is hereby granted, free of charge, to any person obtaining a copy 00012 * of this software and associated documentation files (the "Software"), to deal 00013 * in the Software without restriction, including without limitation the rights 00014 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00015 * copies of the Software, and to permit persons to whom the Software is 00016 * furnished to do so, subject to the following conditions: 00017 * 00018 * The above copyright notice and this permission notice shall be included in 00019 * all copies or substantial portions of the Software. 00020 * 00021 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00022 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00023 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00024 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00025 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00026 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00027 * THE SOFTWARE. 00028 */ 00029 00030 #include "TextLCD_595.h" 00031 #include "mbed.h" 00032 00033 #include <string> 00034 00035 #define __nop1 wait_us(1) 00036 00037 const unsigned char utf_recode[] = 00038 { 00039 0x41,0xa0,0x42,0xa1,0xe0,0x45,0xa3,0xa4, 00040 0xa5,0xa6,0x4b,0xa7,0x4d,0x48,0x4f,0xa8, 00041 0x50,0x43,0x54,0xa9,0xaa,0x58,0xe1,0xab, 00042 0xac,0xe2,0xad,0xae,0x62,0xaf,0xb0,0xb1, 00043 0x61,0xb2,0xb3,0xb4,0xe3,0x65,0xb6,0xb7, 00044 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0x6f,0xbe, 00045 0x70,0x63,0xbf,0x79,0xe4,0x78,0xe5,0xc0, 00046 0xc1,0xe6,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7 00047 }; 00048 00049 int ConvertChar(int c) 00050 { 00051 int i=c; 00052 if ((c>=0xD090)and(c<=0xD0BF))i=utf_recode[c-0xD090]; 00053 if ((c>=0xD180)and(c<=0xD18F))i=utf_recode[c-0xD150]; 00054 if (c==0xD081) i=0xA2; 00055 if (c==0xD191) i=0xB5; 00056 return i; 00057 } 00058 00059 #define _BL 0x40 00060 #define _RS 0x10 00061 #define _E 0x20 00062 #define _D4 0x01 00063 #define _D5 0x02 00064 #define _D6 0x04 00065 #define _D7 0x08 00066 00067 TextLCD_595::TextLCD_595(SPI *spi, PinName CS, LCDType type) : 00068 _spi(spi), 00069 _cs(CS), 00070 _type(type) { 00071 _spi->format(8,0); 00072 _spi->frequency(1000000); 00073 00074 _cs = 0; 00075 _spi->write(0x0); 00076 _cs = 1; 00077 if (_type != LCDuser) 00078 setLCDparam(_type); // otherwise rows, colums, comdelay, adresses must be set before 00079 00080 wait(0.050f); // Wait 50ms to ensure powered up 00081 00082 // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus) 00083 // this sets controler into 8 bit mode, so we have a defined state 00084 for (int i=0; i<3; i++) { 00085 _cs = 0; 00086 _spi->write(_E); 00087 _cs = 1; 00088 __nop1; 00089 _cs = 0; 00090 _spi->write(_E|_D4|_D5); 00091 _cs = 1; 00092 __nop1; 00093 _cs = 0; 00094 _spi->write(_D4|_D5); 00095 _cs = 1; 00096 wait_us(LCDparam.delay); 00097 } 00098 _cs = 0; 00099 _spi->write(_E|_D4|_D5); 00100 _cs = 1; 00101 __nop1; 00102 _cs = 0; 00103 _spi->write(_E|_D5); 00104 _cs = 1; 00105 __nop1; 00106 _cs = 0; 00107 _spi->write(_D5); 00108 _cs = 1; 00109 wait_us(LCDparam.delay); 00110 _comm = _D5; 00111 00112 writeCommand(0x28); // Function set 4 Bit, 2Line, 5*7 00113 writeCommand(0x08); // Display off 00114 cls(); // clear display, reset _column and _row 00115 writeCommand(0x04); // cursor right, Display is not shifted 00116 _bl=_BL; // Backlight on 00117 writeCommand(0x0C); // Display on , Cursor off 00118 _setCursor=0x0; //Курсор выключен и не мигает 00119 } 00120 00121 void TextLCD_595::character(int column, int row, int c) { 00122 int a = 0x80 | (LCDparam.adresses[row & 3] + column); 00123 writeCommand(a); // set cursor address 00124 writeData(c); // write char 00125 } 00126 00127 void TextLCD_595::cls() { 00128 writeCommand(0x01); // cls, and set cursor to 0 00129 locate(0, 0); // set internal position 00130 wait_us(45 * LCDparam.delay); // CLS need much time 00131 } 00132 00133 void TextLCD_595::locate(int column, int row) { 00134 _column = column; // set position for next char 00135 _row = row; // note: cursor is not set yet 00136 } 00137 00138 00139 00140 int TextLCD_595::_putc(int value) { 00141 if (value == '\n') { 00142 _column = 0; 00143 _row++; 00144 if (_row >= LCDparam.rows) { 00145 _row = 0; 00146 } 00147 } else { 00148 character(_column, _row, value); 00149 _column++; 00150 if (_column >= LCDparam.columns) { 00151 _column = 0; 00152 _row++; 00153 if (_row >= LCDparam.rows) { 00154 _row = 0; 00155 } 00156 } 00157 } 00158 return value; 00159 } 00160 00161 // Dummy function - read not supported 00162 int TextLCD_595::_getc() { 00163 return -1; 00164 } 00165 00166 void TextLCD_595::writeByte(int value) { 00167 _cs = 0; 00168 _spi->write(_E|_bl|_comm); 00169 _cs = 1; 00170 __nop1; 00171 _comm = value >> 4; // higher nibble first 00172 _cs = 0; 00173 _spi->write(_E|_bl|_comm); 00174 _cs = 1; 00175 __nop1; 00176 _cs = 0; 00177 _spi->write(_bl|_comm); 00178 _cs = 1; 00179 __nop1; 00180 _cs = 0; 00181 _spi->write(_E|_bl|_comm); 00182 _cs = 1; 00183 __nop1; 00184 _comm = value & 0x0F; // then lower 00185 _cs = 0; 00186 _spi->write(_E|_bl|_comm); 00187 _cs = 1; 00188 __nop1; 00189 _cs = 0; 00190 _spi->write(_bl|_comm); 00191 _cs = 1; 00192 __nop1; 00193 } 00194 00195 void TextLCD_595::writeByteData(int value) { 00196 _cs = 0; 00197 _spi->write(_RS|_bl|_comm); 00198 _cs = 1; 00199 __nop1; 00200 _cs = 0; 00201 _spi->write(_E|_RS|_bl|_comm); 00202 _cs = 1; 00203 __nop1; 00204 _comm = value >> 4; // higher nibble first 00205 _cs = 0; 00206 _spi->write(_E|_RS|_bl|_comm); 00207 _cs = 1; 00208 __nop1; 00209 _cs = 0; 00210 _spi->write(_RS|_bl|_comm); 00211 _cs = 1; 00212 __nop1; 00213 _cs = 0; 00214 _spi->write(_E|_RS|_bl|_comm); 00215 _cs = 1; 00216 __nop1; 00217 _comm = value & 0x0F; // then lower 00218 _cs = 0; 00219 _spi->write(_E|_RS|_bl|_comm); 00220 _cs = 1; 00221 __nop1; 00222 _cs = 0; 00223 _spi->write(_RS|_bl|_comm); 00224 _cs = 1; 00225 wait_us(LCDparam.delay); 00226 _cs = 0; 00227 _spi->write(_bl|_comm); 00228 _cs = 1; 00229 __nop1; 00230 } 00231 00232 00233 void TextLCD_595::writeCommand(int command) { 00234 writeByte(command); 00235 wait_us(LCDparam.delay); 00236 } 00237 00238 00239 void TextLCD_595::writeData(int data) { 00240 writeByteData(data); 00241 wait_us(LCDparam.delay); 00242 } 00243 00244 00245 // set user defined char 00246 void TextLCD_595::writeCGRAM(int address, int pattern[8]){ 00247 int i; 00248 address = address & 7; //max 8 char 00249 for(i=0;i<8;i++){ 00250 writeCommand(0x40 | (address * 8) + i); 00251 writeData(pattern[i]); 00252 } 00253 } 00254 00255 void TextLCD_595::setLCDparam(LCDType _type){ 00256 switch (_type) { 00257 00258 case LCD16x2: 00259 case LCD16x2B: 00260 LCDparam.columns = 16; 00261 break; 00262 case LCD20x2: 00263 case LCD20x4: 00264 LCDparam.columns = 20; 00265 break; 00266 case LCD24x2: 00267 LCDparam.columns = 24; 00268 break; 00269 } 00270 if (_type == LCD20x4) 00271 LCDparam.rows = 4; 00272 else 00273 LCDparam.rows = 2; 00274 00275 LCDparam.adresses[0] = 0; 00276 00277 if (_type == LCD16x2B) 00278 LCDparam.adresses[1] = 40; 00279 else 00280 LCDparam.adresses[1] = 0x40; 00281 00282 if (_type == LCD20x4) { 00283 LCDparam.adresses[2] = 0x14; 00284 LCDparam.adresses[3] = 0x54;} 00285 else { 00286 LCDparam.adresses[2] = 0; 00287 LCDparam.adresses[3] = 0;} 00288 00289 LCDparam.delay = 50; // 50 us delays as default 00290 } 00291 00292 int TextLCD_595::putc_rus(int c) { 00293 return putc(ConvertChar(c)); 00294 } 00295 00296 void TextLCD_595::print_rus(const string rustext){ 00297 int len = rustext.length(); 00298 for (int i=0; i<len; i++) { 00299 uint16_t temp=uint8_t(rustext[i]); 00300 i++; 00301 temp=temp<<8|uint8_t(rustext[i]); 00302 putc(ConvertChar(temp)); 00303 }; 00304 } 00305 00306 00307 void TextLCD_595::ShiftLCD_Left() { 00308 writeCommand(0x18); 00309 } 00310 00311 void TextLCD_595::ShiftLCD_Right() { 00312 writeCommand(0x1C); 00313 } 00314 00315 void TextLCD_595::ShiftCursor_Left() { 00316 writeCommand(0x10); 00317 } 00318 00319 void TextLCD_595::ShiftCursor_Right() { 00320 writeCommand(0x14); 00321 } 00322 00323 00324 void TextLCD_595::home() { 00325 writeCommand(0x2); 00326 } 00327 00328 void TextLCD_595::on() { 00329 writeCommand(0xC|_setCursor); 00330 } 00331 00332 void TextLCD_595::off() { 00333 writeCommand(0x8|_setCursor); 00334 } 00335 00336 00337 void TextLCD_595::SetCursor(int modeCursor) { 00338 _setCursor=modeCursor; 00339 writeCommand(0xC|_setCursor); 00340 } 00341 00342 void TextLCD_595::CursorPosition(int column, int row) { //Устанавливаем позицию курсора 00343 writeCommand(0x80 | (LCDparam.adresses[row & 3] + column)); 00344 } 00345 00346 00347 void TextLCD_595::BackLightOn(){ 00348 _bl=_BL; 00349 _cs = 0; 00350 _spi->write(_bl|_comm); 00351 _cs = 1; 00352 __nop1; 00353 } 00354 00355 void TextLCD_595::BackLightOff(){ 00356 _bl=0; 00357 _cs = 0; 00358 _spi->write(_bl|_comm); 00359 _cs = 1; 00360 __nop1; 00361 }
Generated on Tue Jul 12 2022 19:17:21 by 1.7.2