Modified TextLCD lib. The RW signal is also connected to a IO pin. This enable to read out the display memory and the busy flag. The timing is switched from delays to wait for the busy flag. Added writeCGRAM function to define user chars 0-7.

Fork of TextLCD by Peter Drescher

Committer:
dreschpe
Date:
Tue Dec 14 16:47:47 2010 +0000
Revision:
4:a7c74d4c6911
Parent:
0:2ceba7f90dd4
0.2 change small delays to __nop();

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dreschpe 0:2ceba7f90dd4 1 /* mbed TextLCD Library, for a 4-bit LCD based on HD44780
dreschpe 0:2ceba7f90dd4 2 * Copyright (c) 2007-2010, sford, http://mbed.org
dreschpe 0:2ceba7f90dd4 3 *
dreschpe 0:2ceba7f90dd4 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
dreschpe 0:2ceba7f90dd4 5 * of this software and associated documentation files (the "Software"), to deal
dreschpe 0:2ceba7f90dd4 6 * in the Software without restriction, including without limitation the rights
dreschpe 0:2ceba7f90dd4 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
dreschpe 0:2ceba7f90dd4 8 * copies of the Software, and to permit persons to whom the Software is
dreschpe 0:2ceba7f90dd4 9 * furnished to do so, subject to the following conditions:
dreschpe 0:2ceba7f90dd4 10 *
dreschpe 0:2ceba7f90dd4 11 * The above copyright notice and this permission notice shall be included in
dreschpe 0:2ceba7f90dd4 12 * all copies or substantial portions of the Software.
dreschpe 0:2ceba7f90dd4 13 *
dreschpe 0:2ceba7f90dd4 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
dreschpe 0:2ceba7f90dd4 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
dreschpe 0:2ceba7f90dd4 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
dreschpe 0:2ceba7f90dd4 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
dreschpe 0:2ceba7f90dd4 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
dreschpe 0:2ceba7f90dd4 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
dreschpe 0:2ceba7f90dd4 20 * THE SOFTWARE.
dreschpe 0:2ceba7f90dd4 21 */
dreschpe 0:2ceba7f90dd4 22
dreschpe 0:2ceba7f90dd4 23 #include "TextLCD.h"
dreschpe 0:2ceba7f90dd4 24 #include "mbed.h"
dreschpe 0:2ceba7f90dd4 25
dreschpe 0:2ceba7f90dd4 26 TextLCD::TextLCD(PinName rs, PinName rw, PinName e, PinName d0, PinName d1,
dreschpe 0:2ceba7f90dd4 27 PinName d2, PinName d3, LCDType type) : _rs(rs), _rw(rw),
dreschpe 0:2ceba7f90dd4 28 _e(e), _d(d0, d1, d2, d3), _type(type) {
dreschpe 0:2ceba7f90dd4 29 _rs = 0; // command mode
dreschpe 0:2ceba7f90dd4 30 _rw = 0;
dreschpe 0:2ceba7f90dd4 31 _e = 0;
dreschpe 0:2ceba7f90dd4 32 _d.output(); // data out
dreschpe 0:2ceba7f90dd4 33
dreschpe 0:2ceba7f90dd4 34 wait(0.05); // Wait 50ms to ensure powered up
dreschpe 0:2ceba7f90dd4 35
dreschpe 0:2ceba7f90dd4 36 // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus)
dreschpe 0:2ceba7f90dd4 37 for (int i=0; i<3; i++) {
dreschpe 0:2ceba7f90dd4 38 _e = 1;
dreschpe 4:a7c74d4c6911 39 __nop();
dreschpe 0:2ceba7f90dd4 40 _d = 0x3;
dreschpe 4:a7c74d4c6911 41 __nop();
dreschpe 0:2ceba7f90dd4 42 _e = 0;
dreschpe 0:2ceba7f90dd4 43 wait(0.004f); // 4ms
dreschpe 0:2ceba7f90dd4 44 }
dreschpe 0:2ceba7f90dd4 45 _e = 1;
dreschpe 4:a7c74d4c6911 46 __nop();
dreschpe 0:2ceba7f90dd4 47 _d = 0x2; // 4 Bit mode
dreschpe 4:a7c74d4c6911 48 __nop();
dreschpe 0:2ceba7f90dd4 49 _e = 0;
dreschpe 0:2ceba7f90dd4 50
dreschpe 0:2ceba7f90dd4 51 writeCommand(0x28); // Function set 4 Bit, 2Line, 5*7
dreschpe 0:2ceba7f90dd4 52 writeCommand(0x08); // Display off
dreschpe 0:2ceba7f90dd4 53 writeCommand(0x01); // clear Display
dreschpe 0:2ceba7f90dd4 54 writeCommand(0x04); // cursor right, Display is not shifted
dreschpe 0:2ceba7f90dd4 55 writeCommand(0x0C); // Display on , Cursor off
dreschpe 0:2ceba7f90dd4 56 }
dreschpe 0:2ceba7f90dd4 57
dreschpe 0:2ceba7f90dd4 58 void TextLCD::character(int column, int row, int c) {
dreschpe 0:2ceba7f90dd4 59 int a = address(column, row);
dreschpe 0:2ceba7f90dd4 60 writeCommand(a);
dreschpe 0:2ceba7f90dd4 61 writeData(c);
dreschpe 0:2ceba7f90dd4 62 }
dreschpe 0:2ceba7f90dd4 63
dreschpe 0:2ceba7f90dd4 64 void TextLCD::cls() {
dreschpe 0:2ceba7f90dd4 65 writeCommand(0x01); // cls, and set cursor to 0
dreschpe 0:2ceba7f90dd4 66 locate(0, 0);
dreschpe 0:2ceba7f90dd4 67 }
dreschpe 0:2ceba7f90dd4 68
dreschpe 0:2ceba7f90dd4 69 void TextLCD::locate(int column, int row) {
dreschpe 0:2ceba7f90dd4 70 _column = column;
dreschpe 0:2ceba7f90dd4 71 _row = row;
dreschpe 0:2ceba7f90dd4 72 }
dreschpe 0:2ceba7f90dd4 73
dreschpe 0:2ceba7f90dd4 74
dreschpe 0:2ceba7f90dd4 75
dreschpe 0:2ceba7f90dd4 76 int TextLCD::_putc(int value) {
dreschpe 0:2ceba7f90dd4 77 if (value == '\n') {
dreschpe 0:2ceba7f90dd4 78 _column = 0;
dreschpe 0:2ceba7f90dd4 79 _row++;
dreschpe 0:2ceba7f90dd4 80 if (_row >= rows()) {
dreschpe 0:2ceba7f90dd4 81 _row = 0;
dreschpe 0:2ceba7f90dd4 82 }
dreschpe 0:2ceba7f90dd4 83 } else {
dreschpe 0:2ceba7f90dd4 84 character(_column, _row, value);
dreschpe 0:2ceba7f90dd4 85 _column++;
dreschpe 0:2ceba7f90dd4 86 if (_column >= columns()) {
dreschpe 0:2ceba7f90dd4 87 _column = 0;
dreschpe 0:2ceba7f90dd4 88 _row++;
dreschpe 0:2ceba7f90dd4 89 if (_row >= rows()) {
dreschpe 0:2ceba7f90dd4 90 _row = 0;
dreschpe 0:2ceba7f90dd4 91 }
dreschpe 0:2ceba7f90dd4 92 }
dreschpe 0:2ceba7f90dd4 93 }
dreschpe 0:2ceba7f90dd4 94 return value;
dreschpe 0:2ceba7f90dd4 95 }
dreschpe 0:2ceba7f90dd4 96
dreschpe 0:2ceba7f90dd4 97 int TextLCD::_getc() {
dreschpe 0:2ceba7f90dd4 98 int a = address(_column, _row);
dreschpe 0:2ceba7f90dd4 99 writeCommand(a);
dreschpe 0:2ceba7f90dd4 100 return (readData());
dreschpe 0:2ceba7f90dd4 101 }
dreschpe 0:2ceba7f90dd4 102
dreschpe 0:2ceba7f90dd4 103 void TextLCD::writeByte(int value) {
dreschpe 0:2ceba7f90dd4 104 _e = 1;
dreschpe 4:a7c74d4c6911 105 __nop();
dreschpe 0:2ceba7f90dd4 106 _d = value >> 4;
dreschpe 4:a7c74d4c6911 107 __nop();
dreschpe 0:2ceba7f90dd4 108 _e = 0;
dreschpe 4:a7c74d4c6911 109 __nop();
dreschpe 0:2ceba7f90dd4 110 _e = 1;
dreschpe 4:a7c74d4c6911 111 __nop();
dreschpe 0:2ceba7f90dd4 112 _d = value >> 0;
dreschpe 4:a7c74d4c6911 113 __nop();
dreschpe 0:2ceba7f90dd4 114 _e = 0;
dreschpe 0:2ceba7f90dd4 115 }
dreschpe 0:2ceba7f90dd4 116
dreschpe 0:2ceba7f90dd4 117 void TextLCD::writeCommand(int command) {
dreschpe 0:2ceba7f90dd4 118 waitBusy(); // check if display is ready
dreschpe 0:2ceba7f90dd4 119 _rs = 0;
dreschpe 0:2ceba7f90dd4 120 writeByte(command);
dreschpe 0:2ceba7f90dd4 121 }
dreschpe 0:2ceba7f90dd4 122
dreschpe 0:2ceba7f90dd4 123 int TextLCD::readData(){
dreschpe 0:2ceba7f90dd4 124 int input;
dreschpe 0:2ceba7f90dd4 125 waitBusy();
dreschpe 0:2ceba7f90dd4 126 _rw = 1;
dreschpe 0:2ceba7f90dd4 127 _rs = 1;
dreschpe 4:a7c74d4c6911 128 __nop();
dreschpe 0:2ceba7f90dd4 129 _d.input(); // switch Data port to input
dreschpe 0:2ceba7f90dd4 130 _e = 1;
dreschpe 4:a7c74d4c6911 131 __nop();
dreschpe 0:2ceba7f90dd4 132 input = _d.read() << 4; // high nibble
dreschpe 0:2ceba7f90dd4 133 _e = 0;
dreschpe 4:a7c74d4c6911 134 __nop();
dreschpe 0:2ceba7f90dd4 135 _e = 1;
dreschpe 4:a7c74d4c6911 136 __nop();
dreschpe 0:2ceba7f90dd4 137 input = input | _d.read(); // low nibble
dreschpe 0:2ceba7f90dd4 138 _e = 0;
dreschpe 0:2ceba7f90dd4 139 return (input);
dreschpe 0:2ceba7f90dd4 140 }
dreschpe 0:2ceba7f90dd4 141
dreschpe 0:2ceba7f90dd4 142 void TextLCD::waitBusy(){
dreschpe 0:2ceba7f90dd4 143 int input;
dreschpe 0:2ceba7f90dd4 144 _rw = 1;
dreschpe 0:2ceba7f90dd4 145 _rs = 0;
dreschpe 4:a7c74d4c6911 146 __nop();
dreschpe 0:2ceba7f90dd4 147 _d.input(); // switch Data port to input
dreschpe 0:2ceba7f90dd4 148 do{
dreschpe 0:2ceba7f90dd4 149 _e = 1;
dreschpe 4:a7c74d4c6911 150 __nop();
dreschpe 0:2ceba7f90dd4 151 input = _d.read();
dreschpe 0:2ceba7f90dd4 152 _e = 0;
dreschpe 4:a7c74d4c6911 153 __nop();
dreschpe 0:2ceba7f90dd4 154 _e = 1;
dreschpe 4:a7c74d4c6911 155 __nop();
dreschpe 0:2ceba7f90dd4 156 _e = 0;
dreschpe 0:2ceba7f90dd4 157 }while((0x8 & input) == 0x8); // wait until display is ready
dreschpe 0:2ceba7f90dd4 158 _rw = 0;
dreschpe 0:2ceba7f90dd4 159 _d.output(); // switch port back to output
dreschpe 0:2ceba7f90dd4 160 }
dreschpe 0:2ceba7f90dd4 161
dreschpe 0:2ceba7f90dd4 162 void TextLCD::writeData(int data) {
dreschpe 0:2ceba7f90dd4 163 waitBusy();
dreschpe 0:2ceba7f90dd4 164 _rs = 1;
dreschpe 0:2ceba7f90dd4 165 writeByte(data);
dreschpe 0:2ceba7f90dd4 166 }
dreschpe 0:2ceba7f90dd4 167
dreschpe 0:2ceba7f90dd4 168
dreschpe 0:2ceba7f90dd4 169 // set user defined char
dreschpe 0:2ceba7f90dd4 170 void TextLCD::writeCGRAM(int address, int pattern[8]){
dreschpe 0:2ceba7f90dd4 171 int i;
dreschpe 0:2ceba7f90dd4 172 address = address & 0x07; //max 8 char
dreschpe 0:2ceba7f90dd4 173 for(i=0;i<8;i++){
dreschpe 0:2ceba7f90dd4 174 waitBusy(); // check if display is ready
dreschpe 0:2ceba7f90dd4 175 _rs = 0;
dreschpe 0:2ceba7f90dd4 176 writeByte(0x40 + address * 8 + i);
dreschpe 0:2ceba7f90dd4 177 writeData(pattern[i]);
dreschpe 0:2ceba7f90dd4 178 }
dreschpe 0:2ceba7f90dd4 179 }
dreschpe 0:2ceba7f90dd4 180
dreschpe 0:2ceba7f90dd4 181
dreschpe 0:2ceba7f90dd4 182 int TextLCD::address(int column, int row) {
dreschpe 0:2ceba7f90dd4 183 switch (_type) {
dreschpe 0:2ceba7f90dd4 184 case LCD20x4:
dreschpe 0:2ceba7f90dd4 185 switch (row) {
dreschpe 0:2ceba7f90dd4 186 case 0:
dreschpe 0:2ceba7f90dd4 187 return 0x80 + column;
dreschpe 0:2ceba7f90dd4 188 case 1:
dreschpe 0:2ceba7f90dd4 189 return 0xc0 + column;
dreschpe 0:2ceba7f90dd4 190 case 2:
dreschpe 0:2ceba7f90dd4 191 return 0x94 + column;
dreschpe 0:2ceba7f90dd4 192 case 3:
dreschpe 0:2ceba7f90dd4 193 return 0xd4 + column;
dreschpe 0:2ceba7f90dd4 194 }
dreschpe 0:2ceba7f90dd4 195 case LCD16x2B:
dreschpe 0:2ceba7f90dd4 196 return 0x80 + (row * 40) + column;
dreschpe 0:2ceba7f90dd4 197 case LCD16x2:
dreschpe 0:2ceba7f90dd4 198 case LCD20x2:
dreschpe 0:2ceba7f90dd4 199 default:
dreschpe 0:2ceba7f90dd4 200 return 0x80 + (row * 0x40) + column;
dreschpe 0:2ceba7f90dd4 201 }
dreschpe 0:2ceba7f90dd4 202 }
dreschpe 0:2ceba7f90dd4 203
dreschpe 0:2ceba7f90dd4 204 int TextLCD::columns() {
dreschpe 0:2ceba7f90dd4 205 switch (_type) {
dreschpe 0:2ceba7f90dd4 206 case LCD20x4:
dreschpe 0:2ceba7f90dd4 207 case LCD20x2:
dreschpe 0:2ceba7f90dd4 208 return 20;
dreschpe 0:2ceba7f90dd4 209 case LCD16x2:
dreschpe 0:2ceba7f90dd4 210 case LCD16x2B:
dreschpe 0:2ceba7f90dd4 211 default:
dreschpe 0:2ceba7f90dd4 212 return 16;
dreschpe 0:2ceba7f90dd4 213 }
dreschpe 0:2ceba7f90dd4 214 }
dreschpe 0:2ceba7f90dd4 215
dreschpe 0:2ceba7f90dd4 216 int TextLCD::rows() {
dreschpe 0:2ceba7f90dd4 217 switch (_type) {
dreschpe 0:2ceba7f90dd4 218 case LCD20x4:
dreschpe 0:2ceba7f90dd4 219 return 4;
dreschpe 0:2ceba7f90dd4 220 case LCD16x2:
dreschpe 0:2ceba7f90dd4 221 case LCD16x2B:
dreschpe 0:2ceba7f90dd4 222 case LCD20x2:
dreschpe 0:2ceba7f90dd4 223 default:
dreschpe 0:2ceba7f90dd4 224 return 2;
dreschpe 0:2ceba7f90dd4 225 }
dreschpe 0:2ceba7f90dd4 226 }