Dependents:   FBRDash1 FBRDash-tom FBRDash

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TextLCD.cpp Source File

TextLCD.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 "TextLCD.h"
00024 #include "mbed.h"
00025 
00026 TextLCD::TextLCD(PinName rs, PinName rw, PinName e, PinName d0, PinName d1,
00027                  PinName d2, PinName d3, LCDType type) : _rs(rs), _rw(rw),
00028         _e(e), _d(d0, d1, d2, d3), _type(type) {
00029     _rs = 0;            // command mode
00030     _rw = 0;
00031     _e  = 0;            
00032     _d.output();        // data out
00033 
00034     wait(0.05);        // Wait 50ms to ensure powered up
00035 
00036     // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus)
00037     for (int i=0; i<3; i++) {
00038         _e = 1;
00039         __nop();
00040         _d = 0x3;
00041         __nop();
00042         _e = 0;
00043         wait(0.004f); // 4ms
00044        }
00045     _e = 1;
00046     __nop();
00047     _d = 0x2;           // 4 Bit mode
00048     __nop(); 
00049     _e = 0;
00050     
00051     writeCommand(0x28); // Function set 4 Bit, 2Line, 5*7
00052     writeCommand(0x08); // Display off
00053     writeCommand(0x01); // clear Display
00054     writeCommand(0x04); // cursor right, Display is not shifted
00055     writeCommand(0x0C); // Display on , Cursor off 
00056 }
00057 
00058 void TextLCD::character(int column, int row, int c) {
00059     int a = address(column, row);
00060     writeCommand(a);
00061     writeData(c);
00062 }
00063 
00064 void TextLCD::cls() {
00065     writeCommand(0x01); // cls, and set cursor to 0
00066     locate(0, 0);
00067 }
00068 
00069 void TextLCD::locate(int column, int row) {
00070     _column = column;
00071     _row = row;
00072 }
00073 
00074 
00075 
00076 int TextLCD::_putc(int value) {
00077     if (value == '\n') {
00078         _column = 0;
00079         _row++;
00080         if (_row >= rows()) {
00081             _row = 0;
00082         }
00083     } else {
00084         character(_column, _row, value);
00085         _column++;
00086         if (_column >= columns()) {
00087             _column = 0;
00088             _row++;
00089             if (_row >= rows()) {
00090                 _row = 0;
00091             }
00092         }
00093     }
00094     return value;
00095 }
00096 
00097 int TextLCD::_getc() {
00098     int a = address(_column, _row);
00099     writeCommand(a);
00100     return (readData());
00101 }
00102 
00103 void TextLCD::writeByte(int value) {
00104     _e = 1;
00105     __nop();    
00106     _d = value >> 4;
00107     __nop();
00108     _e = 0;
00109     __nop();
00110     _e = 1;
00111     __nop();
00112     _d = value >> 0;
00113     __nop();
00114     _e = 0;
00115 }
00116 
00117 void TextLCD::writeCommand(int command) {
00118     waitBusy();  // check if display is ready 
00119     _rs = 0;
00120     writeByte(command);
00121 }
00122 
00123 int TextLCD::readData(){
00124     int input;
00125     waitBusy();
00126     _rw = 1;
00127     _rs = 1;
00128     __nop();
00129     _d.input();  // switch Data port to input
00130     _e = 1;
00131     __nop();
00132     input = _d.read() << 4; // high nibble
00133     _e = 0;
00134     __nop();
00135     _e = 1;
00136     __nop();
00137     input = input | _d.read(); // low nibble
00138     _e = 0;   
00139     return (input);
00140 }
00141 
00142  void TextLCD::waitBusy(){
00143     int input;
00144     _rw = 1;
00145     _rs = 0;
00146     __nop();
00147     _d.input();      // switch Data port to input
00148     do{ 
00149         _e = 1;
00150         __nop();
00151         input = _d.read();              
00152         _e = 0;
00153         __nop();
00154         _e = 1;
00155         __nop();
00156         _e = 0;
00157        }while((0x8 & input) == 0x8);  // wait until display is ready
00158     _rw = 0;
00159     _d.output();      // switch port back to output  
00160  }
00161 
00162 void TextLCD::writeData(int data) {
00163     waitBusy();
00164     _rs = 1;
00165     writeByte(data);
00166 }
00167 
00168 
00169 // set user defined char 
00170 void  TextLCD::writeCGRAM(int address, int pattern[8]){
00171     int i;
00172     address = address & 0x07;  //max 8 char
00173     for(i=0;i<8;i++){
00174         waitBusy();  // check if display is ready 
00175         _rs = 0;
00176         writeByte(0x40 + address * 8 + i);
00177         writeData(pattern[i]);
00178         }
00179 }   
00180         
00181 
00182 int TextLCD::address(int column, int row) {
00183     switch (_type) {
00184         case LCD20x4:
00185             switch (row) {
00186                 case 0:
00187                     return 0x80 + column;
00188                 case 1:
00189                     return 0xc0 + column;
00190                 case 2:
00191                     return 0x94 + column;
00192                 case 3:
00193                     return 0xd4 + column;
00194             }
00195         case LCD16x2B:
00196             return 0x80 + (row * 40) + column;
00197         case LCD16x2:
00198         case LCD20x2:
00199         default:
00200             return 0x80 + (row * 0x40) + column;
00201     }
00202 }
00203 
00204 int TextLCD::columns() {
00205     switch (_type) {
00206         case LCD20x4:
00207         case LCD20x2:
00208             return 20;
00209         case LCD16x2:
00210         case LCD16x2B:
00211         default:
00212             return 16;
00213     }
00214 }
00215 
00216 int TextLCD::rows() {
00217     switch (_type) {
00218         case LCD20x4:
00219             return 4;
00220         case LCD16x2:
00221         case LCD16x2B:
00222         case LCD20x2:
00223         default:
00224             return 2;
00225     }
00226 }