A basic basic basic driver for 2x16 HD44780 based displays using the four wire interface.

Dependents:   lcdLibraryTest generado_final

Revision:
0:0db835052212
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lcd.cpp	Fri Nov 08 07:03:35 2013 +0000
@@ -0,0 +1,215 @@
+#include "lcd.h"
+
+//Public Methods
+//////////////////////////////////////////////////////////////////////////////////////////
+
+lcd::lcd(PinName _rs, PinName _rw, PinName _e, PinName _db4, PinName _db5, PinName _db6, PinName _db7):
+    registerSelect(_rs), readWrite(_rw), enable(_e), dataBus(_db4, _db5, _db6, _db7) {
+   
+    currentMode = klcdReadMode;
+    setMode(klcdWriteMode);
+     
+    //wait for more than 15ms after Vcc rises to 4.5v
+    wait_ms(20);
+    
+    //function set (interface is 8 bits long)
+    writeNibble(klcdInstructionRegister, 0x3);
+    
+    //wait for more than 4.1ms
+    wait_ms(4.5);
+    
+    //function set(interface is 8 bits long)
+    writeNibble(klcdInstructionRegister, 0x3);
+    
+    //wait for more than 100us
+    wait_us(150);
+    
+    //function set (interface is 8 bits long)
+    writeNibble(klcdInstructionRegister, 0x3);
+    wait_us(90);
+    
+    //function set (interface is 4 bits long)
+    writeNibble(klcdInstructionRegister, 0x2);
+    wait_us(90);
+        
+    //function set (interface is 4 bits long) set display lines and character font
+    //      2 lines, 5x8 character font (1 0 0 0)
+    writeByte(klcdInstructionRegister, 0x28, false);
+    wait_us(90);
+      
+    //display off
+    writeByte(klcdInstructionRegister, 0x08, false);
+    wait_us(90);
+        
+    //display clear
+    writeByte(klcdInstructionRegister, 0x01, false);
+    wait_ms(2.0);
+       
+    //entry mode set
+    writeByte(klcdInstructionRegister, 0x0C, false);   
+    wait_us(90);
+   
+    //clear display, and turn on
+    writeByte(klcdInstructionRegister, 0x01);
+    writeByte(klcdInstructionRegister, 0x0C);
+    
+    //turn shifting off
+    writeByte(klcdInstructionRegister, 0x04);
+    
+    row = 0;
+    column = 0;
+    
+}
+
+void lcd::clear() {
+    //clear screen -> 0 0 (0 0 0 0 0 0 0 1)
+    writeByte(klcdInstructionRegister, 0x01);
+    locate(0, 0);
+}
+
+void lcd::locate(int _row, int _column) {
+    row = _row;
+    column = _column;
+}
+
+void lcd::locateCharacter(int _row, int _column, int _char) {
+    //set DDRAM address -> 0 0 (1 a a a a a a a)
+    //write DDRAM -> 1 0 (d d d d d d d d);
+    writeByte(klcdInstructionRegister, 0x80 + (_row * 0x40) + _column);
+    writeByte(klcdDataRegister, _char);
+}
+
+void lcd::defineCharacter(int _char, int _charData[8]) {
+    if(_char < 0 || _char > 7) return;
+    //write CGRAM address 0 0 (0 1 a a a a a a)
+    //  first three bits are character (0-7)
+    //  second three bits are the row in the character
+    writeByte(klcdInstructionRegister, 0x40 + (_char << 3));
+    for(int row = 0; row < 8; row++) {
+        //write CGRAM data 1 0 (d d d d d d d d)
+        writeByte(klcdDataRegister, _charData[row]);
+    }
+}
+
+//Protected Methods
+//////////////////////////////////////////////////////////////////////////////////////////
+void lcd::setMode(int _mode) {
+    //since changing the databus mode takes time only do it
+    //  if we're not in the mode already, this might be
+    //  fuzzy science (read, not actually accurate), but it
+    //  can't hurt
+    if(_mode != currentMode) {
+        readWrite = _mode;
+        currentMode = _mode;
+        switch(_mode) {
+            case klcdWriteMode: {
+                dataBus.output();
+                break;
+            }
+            case klcdReadMode: {
+                dataBus.input();
+                break;
+            }
+        }
+    }
+}
+
+void lcd::waitUntilNotBusy() {
+    setMode(klcdReadMode);
+    registerSelect = klcdInstructionRegister;
+    wait_us(5);
+    enable = klcdEnableHigh;
+    wait_us(0.5);
+    while(dataBus.read() >> 3) {};
+    enable = klcdEnableLow;
+    wait_us(0.6);
+    readNibble(klcdInstructionRegister);
+    return;
+}
+
+void lcd::writeByte(int _reg, int _byte, bool _wait) {
+    //write the most significant four bytes first
+    writeNibble(_reg, _byte >> 4);
+    writeNibble(_reg, _byte);
+    if(_wait) {
+        waitUntilNotBusy();
+    }
+}
+
+//this is useless at the moment, not sure how I want to structure
+//  reading bytes with the four wire interface, as one read is
+//  technically reading the busy flag and internal address counter,
+//  another is actually reading bytes from CGRAM or DDRAM (which isn't
+//  all that useful actually)
+int lcd::readNibble(int _reg) {
+    setMode(klcdReadMode);
+    registerSelect = _reg;
+    
+    //wait more than 60ns for address set up, then bring enable high
+    wait_us(0.1);
+    enable = klcdEnableHigh;
+    //wait for the enable pulse width to elapse (450ns), by which time the data
+    //  should be present on the bus, then bring enable low, and wait
+    //  till the end of the enable cycle
+    wait_us(0.5);
+    int nibble = dataBus.read();
+    enable = klcdEnableLow;
+    wait_us(0.6);
+    return nibble;
+}
+
+//write a four bit nibble onto the bus with correct delays
+void lcd::writeNibble(int _reg, int _nibble) {
+    setMode(klcdWriteMode);
+    registerSelect = _reg;
+    
+    dataBus = _nibble;
+    //wait for more than 60ns for address set up, then bring enable high
+    wait_us(0.1);
+    enable = klcdEnableHigh;
+    //wait for more than 450ns for enable pulse width, then bring enable low
+    wait_us(0.5);
+    enable = klcdEnableLow;
+    //wait for more than 550ns for the completion of the enable cycle
+    wait_us(0.6);
+}
+
+
+//Stream Implementation
+//////////////////////////////////////////////////////////////////////////////////////
+int lcd::_putc(int _char) {
+    if(_char == '\n') {
+        column = 0;
+        row = (++row % 2);
+    } else {
+        locateCharacter(row, column, _char);
+        column++;
+    }    
+    return _char;
+}
+
+//not respoinding to getc (yet, this would require reading out of the 
+// DDRAM of the display, or caching
+int lcd::_getc() {
+    return -1;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+