Trung Nguyen
/
FINAL_PROJECT_4180
asdasdasd
Fork of FINAL_PROJECT_4180 by
Diff: cryst_lcd.cpp
- Revision:
- 12:5cb9ffad1ad7
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cryst_lcd.cpp Fri May 06 13:10:20 2016 +0000 @@ -0,0 +1,247 @@ +/** + * Driver for LCD devices based on the HD44780 controller + */ + +/* Description + +LCD SIZES SUPPORTED: +1-line displays: 8x1, 16x1, 20x1, 24x1, 32x1, 40x1 +2-line displays: 16x2, 20x2, 24x2, 32x2, 40x2 +4-line displays: 16x4, 20x4, 40x4 + +SUPPORTED PLATFORM: mbed +*/ + + +#include "cryst_lcd.h" + +Cryst_LCD::Cryst_LCD(PinName rs, PinName en, PinName db4, PinName db5, + PinName db6, PinName db7, LCDSize size) + : _rs(rs), _en(en), _data(db4, db5, db6, db7) +{ + _size = size; + _row = 0; + _col = 0; + _displayStatus = 0x0C; + init(); +} + + +void Cryst_LCD::cls() +{ + writeCommand(0x01, false); + wait_ms(2); + locate(0, 0); +} + +void Cryst_LCD::locate(int row, int col) +{ + _row = 0; + _col = col; + + if (row < getMaxRows()) { + _row = row; + } + + if (_col >= getMaxCols()) { + _col = 0; + if (_row < getMaxRows() - 1) + _row++; + else _row = 0; + } + + int addr = getAddress(_row, _col); + addr |= 0x80; + writeCommand(addr); +} + +void Cryst_LCD::display_off() { + _displayStatus &= 0x0B; + writeCommand(_displayStatus); +} + +void Cryst_LCD::display_on() { + _displayStatus |= 0x04; + writeCommand(_displayStatus); +} + +void Cryst_LCD::cursor_on() { + _displayStatus |= 0x02; + writeCommand(_displayStatus); +} + +void Cryst_LCD::cursor_off() { + _displayStatus &= 0x0D; + writeCommand(_displayStatus); +} + +void Cryst_LCD::cursor_blink() { + _displayStatus |= 0x01; + writeCommand(_displayStatus); +} + +void Cryst_LCD::cursor_no_blink() { + _displayStatus &= 0x0E; + writeCommand(_displayStatus); +} + +void Cryst_LCD::clear_line() { + int lineWidth = getMaxCols(); + + for (int i = 0; i < lineWidth - 1; i++) { + locate(_row, i); + printf(" "); + } + + locate(_row, 0); +} + +void Cryst_LCD::reset() +{ + _rs = 0; + wait_ms(15); // wait approximately 15 ms + writeNibble(0x3); // write config data + wait_ms(5); // wait approximately 4.1 ms + writeNibble(0x3); // write config data again + wait_us(100); // wait approximately 100 us +} + +void Cryst_LCD::init() +{ + reset(); + + // Function set + if (getMaxRows() <= 1) { // 1-line display + // (DF = 0, N = 0, F = 0) + // 4-bit mode, 1-line display, 5x8 font size + writeCommand(0x20); + } else { // Multi-line display + // (DF = 0, N = 1, F = 0) + // 4-bit mode, 2-line display, 5x8 font size + writeCommand(0x28); + } + + // Entry Mode + // (I/D = 1, S = 0) + // DDRAM autoincrement, No display shifts + writeCommand(0x06); + + // Display Control + // (D = 1, C = 0, B = 0) + // Display ON, cursor OFF, No cursor blinking + writeCommand(_displayStatus); + + // Clear Display + cls(); +} + +int Cryst_LCD::getAddress(int row, int col) +{ + int rowStartAddr[4] = {0x00, 0x40, 0x14, 0x54}; + int tempRow = 0, tempCol = 0; + if (row < getMaxRows()) tempRow = row; + if (col < getMaxCols()) tempCol = col; + return rowStartAddr[tempRow] + tempCol; +} + +// Default wait time is 40 us +void Cryst_LCD::writeData(int ch, bool use_default_timing) +{ + _rs = 1; + writeNibble((ch >> 4) & 0x0F); + writeNibble(ch & 0x0F); + + if (use_default_timing) + wait_us(40); +} + +// Default wait time is 40 us +void Cryst_LCD::writeCommand(int cmd, bool use_default_timing) +{ + _rs = 0; + writeNibble((cmd >> 4) & 0x0F); + writeNibble(cmd & 0x0F); + + if (use_default_timing) + wait_us(40); +} + +void Cryst_LCD::writeNibble(int nib) +{ + _data = nib & 0xF; + wait_us(1); + _en = 1; + wait_us(1); + _en = 0; + wait_us(1); +} + +void Cryst_LCD::getMaxDimensions(int* rowCount, int* colCount) { + switch(_size) { + // 1-line displays + case LCD8x1: *rowCount = 1; *colCount = 8; break; + case LCD16x1: *rowCount = 1; *colCount = 16; break; + case LCD20x1: *rowCount = 1; *colCount = 20; break; + case LCD24x1: *rowCount = 1; *colCount = 24; break; + case LCD32x1: *rowCount = 1; *colCount = 32; break; + case LCD40x1: *rowCount = 1; *colCount = 40; break; + + // 2-line displays + case LCD16x2: *rowCount = 2; *colCount = 16; break; + case LCD20x2: *rowCount = 2; *colCount = 20; break; + case LCD24x2: *rowCount = 2; *colCount = 24; break; + case LCD32x2: *rowCount = 2; *colCount = 32; break; + case LCD40x2: *rowCount = 2; *colCount = 40; break; + + // 4-line displays + case LCD16x4: *rowCount = 4; *colCount = 16; break; + case LCD20x4: *rowCount = 4; *colCount = 20; break; + case LCD40x4: *rowCount = 4; *colCount = 40; break; + + default: *rowCount = 0; *colCount = 0; break; + } +} + +int Cryst_LCD::getMaxRows() +{ + int rowCount = 0; + int colCount = 0; + getMaxDimensions(&rowCount, &colCount); + return rowCount; +} + +int Cryst_LCD::getMaxCols() +{ + int rowCount = 0; + int colCount = 0; + getMaxDimensions(&rowCount, &colCount); + return colCount; +} + +int Cryst_LCD::_putc(int ch) +{ + if (ch == '\n') { + locate(_row + 1, 0); + } + + else if (ch == '\t') { + locate(_row, _col + 3); + } + + else if (ch == '\r') { + locate(_row, 0); + } + + else { + locate(_row, _col); + writeData(ch); + locate(_row, _col + 1); + } + + return ch; +} + +int Cryst_LCD::_getc() +{ + return -5; +} \ No newline at end of file