Baseline for testing
LCD.cpp
- Committer:
- foxbrianr
- Date:
- 2019-09-17
- Revision:
- 2:73721d9e0056
- Parent:
- 1:0f1dffc6103a
File content as of revision 2:73721d9e0056:
/************************************************************************** * @file LCD.cpp * @brief Base class for wrapping the interface with the New Haven 40x4 * LCD monitor. * @version: V1.0 * @date: 9/17/2019 * * @note * Copyright (C) 2019 E3 Design. All rights reserved. * * @par * E3 Designers LLC is supplying this software for use with Cortex-M3 LPC1768 * processor based microcontroller for the ESCM 2000 Monitor and Display. * * * @par * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. * ******************************************************************************/ #include "mbed.h" #include "LCD.h" #include <stdio.h> #include <ctype.h> #define WAIT_TIME 100 #define wait_ms(x) ThisThread::sleep_for(x) /*****************************************************************************/ LCD::LCD(): LCD_E1(p17), LCD_E2(p18), LCD_RS(p19), LCD_RW(p20), //LCD_D4(p24), //LCD_D5(p23), //LCD_D6(p22), //LCD_D7(p21), //bus constructor is the reverse order of the pins in the byte order. // d0 - d7 LCD_DATA( p24, p23, p22, p21) { LCD_DATA.output(); LCD_DATA.mode(OpenDrain); LCD_E1.mode(OpenDrain); LCD_E2.mode(OpenDrain); LCD_RS.mode(OpenDrain); LCD_RW.mode(OpenDrain); isOutput=1; } /*****************************************************************************/ LCD::~LCD() { } /*****************************************************************************/ void LCD::command1(char i) //Top half of the display { LCD_DATA.output(); LCD_DATA = i; LCD_RW = 0; LCD_RS = 0; LCD_E1 = 1; wait_us(40); // wait 40 us for most commands LCD_E1 = 0; //printf("C1:%x\n\r", i); } /*****************************************************************************/ void LCD::command2(char i) //Bottom half of the display { LCD_DATA.output(); LCD_DATA = i; LCD_RW = 0; LCD_RS = 0; LCD_E2 = 1; wait_us(40); // wait 40 us for most commands LCD_E2 = 0; //printf("C2:%x\n\r", i); } /*****************************************************************************/ void LCD::writedata1(char i) //Top half of the display {; LCD_DATA.output(); LCD_DATA = i; LCD_RW = 0; LCD_RS = 1; LCD_E1 = 1; wait_us(40); // wait 40 us for most commands LCD_E1 = 0; } /*****************************************************************************/ void LCD::writedata2(char i) //Bottom half of the display { LCD_DATA.output(); LCD_DATA = i; LCD_RW = 0; LCD_RS = 1; LCD_E2 = 1; wait_us(40); // wait 40 us for most commands LCD_E2 = 0; } /*****************************************************************************/ void LCD::nextline1(){ writeCommand(0xc0,1,0); //set DDRAM address to 40 (line 2) } /*****************************************************************************/ void LCD::nextline2(){ writeCommand(0xc0,0,1); //set DDRAM address to 40 (line 4) } /*****************************************************************************/ void LCD::display(char *show){ //show character data on display char datum; int i; for (i=0;i<40;i++){ datum=*show; //point to 1st line data writeData(datum,1,0); //write to 1st line ++show; //next letter } nextline1(); //move address to line 2 for (i=0;i<40;i++){ datum=*show; writeData(datum,1,0); //write to 2nd line ++show; } for (i=0;i<40;i++){ datum=*show; writeData(datum,0,1); //write to 3rd line ++show; } nextline2(); //move address to line 4 for (i=0;i<40;i++){ datum=*show; writeData(datum,0,1); //write to 4th line ++show; } } /*****************************************************************************/ void LCD::writeByte1(int value) { // ------------------------------------------------- LCD_DATA.output(); LCD_DATA = value >> 4; LCD_RW = 0; LCD_E1 = 1; wait_ms(2); // wait 40 us for most commands __nop(); LCD_E1 = 0; // ------------------------------------------------- wait_ms(1); // wait 40 us for most commands // ------------------------------------------------- LCD_DATA = value >> 0; LCD_E1 = 1; wait_ms(2); // wait 40 us for most commands __nop(); LCD_E1 = 0; //printf("x1:%x\n\r", value); } /*****************************************************************************/ void LCD::writeByte2(int value) { // ------------------------------------------------- LCD_DATA.output(); LCD_DATA = value >> 4; LCD_RW = 0; LCD_E2 = 1; wait_ms(2); // wait 40 us for most commands __nop(); LCD_E2 = 0; // ------------------------------------------------- wait_ms(1); // wait 40 us for most commands // ------------------------------------------------- LCD_DATA = value >> 0; LCD_E2 = 1; wait_ms(2); // wait 40 us for most commands __nop(); LCD_E2 = 0; //printf("x2:%x\n\r", value); } /************************************************************************/ void LCD::init(void) { wait_ms(100); LCD_E1 = 0; LCD_E2 = 0; for (int i=0; i<3; i++) { command1(0x3);//Wake up command2(0x3); wait_ms(1); // wait 40 us for most commands } command1(0x2);// Set 4 bit mode command2(0x2); wait_ms(1); // wait 40 us for most commands LCD_RW = 0; LCD_RS = 0; writeCommand(0x2C,1,1); //Turn on display writeCommand(LCD_setDisplayOff,1,1); //Turn on display //writeCommand2(LCD_setDisplayOff); writeCommand(LCD_clearDisplay,1,1); //Clear display //writeCommand2(LCD_clearDisplay); writeCommand(LCD_entryModeSet,1,1); //Entry mode cursor increment //writeCommand2(LCD_entryModeSet); writeCommand(LCD_setDisplayOn,1,1); //Turn on display; no cursor //writeCommand2(LCD_setDisplayOn); LCD_E1 = 0; LCD_E2 = 0; } /*****************************************************************************/ void LCD::locate(int row, int column) { _row = row; _column = column; } /*****************************************************************************/ void LCD::cls(){ clear(1,1); wait_ms(2); //fprintf(stdout,"C1:\n\r"); } /*****************************************************************************/ void LCD::clear() { locate(0,0);write(" "); locate(1,0);write(" "); locate(2,0);write(" "); locate(3,0);write(" "); } /*****************************************************************************/ void LCD::clear(int e1, int e2 ){ waitBusy(); writeCommand(LCD_clearDisplay,e1,e2); _row = 0; _column = 0; } /*****************************************************************************/ int LCD::isBusy1(void) { volatile int input = 0; volatile int hi = 0; volatile int lo = 0; int result = 0; LCD_RW = 1; __nop(); LCD_RS = 0; LCD_DATA.input(); // switch port back to output LCD_E1 = 1; __nop(); lo = LCD_DATA.read() ; // read low bit LCD_E1 = 0; wait_ms(1); LCD_E1 = 1; hi = LCD_DATA.read() ; // read high bit __nop(); LCD_E1 = 0; if ((0x8 & lo)) // wait until display is ready { result = 1; } result =0; LCD_RW = 0; LCD_DATA.output(); // switch port back to output //fprintf(stdout,"isBusy1? = 0x%02x 0x%02x \n\r", lo,hi ); return result; } /*****************************************************************************/ int LCD::isBusy2(void) { volatile int input = 0; volatile int hi = 0; volatile int lo = 0; int result = 0; LCD_RW = 1; __nop(); LCD_RS = 0; LCD_DATA.input(); // switch port back to output LCD_E2 = 1; __nop(); lo = LCD_DATA.read() >> 0; // read low bit LCD_E2 = 0; __nop(); LCD_E2 = 1; hi = LCD_DATA.read() >> 4; // read high bit __nop(); LCD_E2 = 0; if ((0x8 & lo)) // wait until display is ready { result = 1; } LCD_RW = 0; LCD_DATA.output(); // switch port back to output //fprintf(stdout,"isBusy2? = 0x%02x 0x%02x \n\r", lo,hi ); return result; } /*****************************************************************************/ int LCD::isBusy(int e1, int e2) { int input = 0; int result = 0; if (e1) { result=isBusy1(); } if (e2 && result==0) { result=isBusy2(); } return result; } /*****************************************************************************/ void LCD::waitBusy() { unsigned char statusBit; statusBit = isBusy(1,1); //int i=0; while (statusBit) { fprintf(stdout,"!"); statusBit = isBusy(1,1); wait_us(1); } } /*****************************************************************************/ void LCD::writeData(char value, int e1, int e2 ){ int hi=( value & 0xF0 ) >> 4; int lo=( value & 0x0F ) >> 0; LCD_DATA.output(); if(e1) { LCD_DATA = hi; LCD_E1 = 1; wait_us(WAIT_TIME); // wait 40 us for most commands LCD_E1 = 0; wait_us(WAIT_TIME); // wait 40 us for most commands LCD_DATA = lo; LCD_E1 = 1; wait_us(WAIT_TIME); // wait 40 us for most commands LCD_E1 = 0; } if(e2) { LCD_DATA = hi; LCD_E2= 1; wait_us(WAIT_TIME); // wait 40 us for most commands LCD_E2= 0; wait_us(WAIT_TIME); // wait 40 us for most commands LCD_DATA = lo; LCD_E2= 1; wait_us(WAIT_TIME); // wait 40 us for most commands LCD_E2= 0; } } /*****************************************************************************/ void LCD::writeCommand(char value, int e1, int e2){ waitBusy(); LCD_RS = 0; writeData(value,e1,e2); } /*****************************************************************************/ void LCD::writeChar(char value, int e1, int e2){ //waitBusy(); LCD_RS = 1; writeData(value,e1,e2); } /*****************************************************************************/ void LCD::putc(const char c) { character(_row, _column, c); } /*****************************************************************************/ void LCD::printf(const char *message, ...) { char buffer[128]; va_list argptr; va_start(argptr, message); vsprintf( buffer, message, argptr); write (buffer); va_end(argptr); } /*****************************************************************************/ void LCD::write(const char* text) { //_row = 0; //_column = 0; int characterAmount =0; for(int i = 0; text[i] != '\0'; i++) { if (!isprint(text[i])) { fprintf(stdout,"^%02x : %s ", text[i],text); } characterAmount++; } if (characterAmount > 40 - _column ) { fprintf(stdout,"OVERFLOW+(%d+%d) %d: [%s] \n\r",_row, _column, characterAmount, text); characterAmount = 40 - _column ; } for (int i = 0; i < characterAmount && i < rows() * columns(); i++){ if (isprint(text[i])) character(_row, _column, text[i]); wait_us(1); } } /*****************************************************************************/ void LCD::writeLine(int line, const char* text ) { _row = line; _column = 1; int characterAmount =strlen(text); int i=0; locate(_row,_column); while(i < columns()-1) { if ( i < characterAmount ) putc( text[i]); else putc ( ' '); i++; } } /*****************************************************************************/ void LCD::writeCharacter(const char c, int row, int column) { locate(row, column); character(_row, _column, c); } /*****************************************************************************/ void LCD::writeCharacters(const char* text, int row, int column) { locate(row, column); int characterAmount =0; for(int i = 0; text[i] != '\0'; i++) characterAmount++; for (int i = 0; i < characterAmount && i < columns() - column; i++){ character(_row, _column, text[i]); } } /*****************************************************************************/ int LCD::address(int row, int column){ int a=0x80; if(row < rows() && column < columns()) { switch (row){ case 0: case 1: a = 0x80 + (row * 0x40) + column; break; case 2: case 3: a = 0x80 + ((row-2) * 0x40) + column; break; default: break; } } return a; } /*****************************************************************************/ void LCD::character(int row, int column, char c) { uint8_t a = address(row, column); if(row<2){ writeCommand(a,1,0); writeChar(c,1,0); } else { writeCommand(a,0,1); writeChar(c,0,1); } //Update position if(_column < columns()) _column++; if (_column >= columns()){ #if 1 if (_row == 0){ _column = 0; _row++; } else{ _row = 0; _column = 0; } #endif } } /*****************************************************************************/ void LCD::setCursorMode( int mode ) { if (mode) { if(_row < 2) writeCommand(LCD_setDisplayBlink,1,0); else writeCommand(LCD_setDisplayBlink,0,1); } else { writeCommand(LCD_setDisplayOn,1,1); } }