library for driving character LCD in 4-bit mode (HD44780, ST7066U & compatible) supports 16x2, 20x2, 20x4 & 40x2 uses R/W pin for timing rather than delays

Dependents:   Ultrasonic

Committer:
wertyfrog
Date:
Wed Jul 11 22:08:08 2012 +0000
Revision:
0:173f8aaea8cc
Child:
1:ca430b27054d
[mbed] converted /AD7414_test/LCD40x2

Who changed what in which revision?

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