Contains necessary classes and functions for ELEC351

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers displayMaster.cpp Source File

displayMaster.cpp

00001 #include "mbed.h"
00002 #include "displayMaster.hpp"
00003 
00004 ////////////////////////////////////////////////////////////////////////////////
00005 //                      INCOMPLETE - RUN OUT OF TIME TO DEBUG                 //
00006 ////////////////////////////////////////////////////////////////////////////////
00007 
00008 /* Instructions on using the 16x2 LCD panel are found here:
00009 [https://www.8051projects.net/lcd-interfacing/lcd-4-bit.php]                  */
00010 /* N.B. I did the code from scratch since I do not have the code from ELEC230 */
00011 /* N.B. This class contains blocking function so it goes into its own thread  */
00012 
00013 C_displayMaster::C_displayMaster(PinName D1, PinName D2, PinName D3 , PinName D4 , PinName RS , PinName RW, PinName EN)
00014     :   // Initialisation of the instance
00015     _commsBus(D1, D2, D3, D4),
00016     _registerSel(RS),
00017     _modeSel(RW),
00018     _enable(EN)
00019 {
00020     _registerSel    = INSTRUCTION;  // command mode
00021     _modeSel        = WRITE;        // write mode
00022 
00023     Thread::wait(20);               // Wait 20ms to ensure powered up
00024 
00025     for (int i=0; i<3; i++) {       // Three times
00026         _enable     = DISABLE;      // Invalidate signal
00027         _commsBus   = 0x03;         // Send command for powerup
00028         _enable     = ENABLE;       // Validate signal
00029         Thread::wait(20);           // Wait since BUSY flag is not yet available
00030     }
00031 
00032     _enable     = DISABLE;          // Invalidate signal
00033     _commsBus   = 0x03;             // Send command for 4 bit mode
00034     _enable     = ENABLE;           // Validate signal
00035     Thread::wait(20);               // Wait since BUSY flag is not yet available
00036 
00037     // BUSY flag is now available, Can use "writeChar"                        //
00038 
00039     writeChar(0x28, INSTRUCTION);   // 4-bit, 2 Line, 5x7 Dots
00040     writeChar(0x0C, INSTRUCTION);   // Display on Cursor off
00041     writeChar(0x04, INSTRUCTION);   // Entry mode - no increment & no display shift
00042     clear();                        // Clear display for writing (DDRAM cleared)
00043 
00044 //    writeChar(0b00100011, DATA);    // Write Test "#" symbol
00045 //    Thread::wait(1000);             // Wait 1 second
00046 //    clear();                        // Clear Test "#" symbol
00047 }
00048 
00049 
00050 //****************************************************************************//
00051 void C_displayMaster::writeChar(int Char, bool REGISTER)
00052 {
00053     _enable      = DISABLE;         // DISABLE at start
00054     _commsBus[3].output();          // Reconfigure pin as output (MSB)
00055     _registerSel = REGISTER;        // Chose register to comunicate with
00056     _modeSel     = WRITE;           // WRITE to register
00057 
00058     _commsBus    = (Char>>4);       // Top nibble
00059     _enable      = ENABLE;          // Validate signal
00060     _enable = DISABLE;              // Invalidate signal
00061     busyCheck();                    // Chek if clear to write more
00062 
00063     _commsBus    = (Char>>0);       // Bottom nibble
00064     _enable      = ENABLE;          // Validate signal
00065     _enable = DISABLE;              // Invalidate signal
00066     busyCheck();                    // Chek if clear to write more
00067 }
00068 
00069 
00070 void C_displayMaster::busyCheck()
00071 {
00072     _enable      = DISABLE;         // DISABLE at start
00073     _commsBus[3].input();           // Input to listen for BUSY flag (MSB)
00074     _registerSel = INSTRUCTION;     // Comunicate with INSTRUCTION register
00075     _modeSel     = READ;            // READ from register
00076     _enable      = ENABLE;          // Listen for BUSY flag
00077     while(_commsBus[3]) {
00078         _enable != _enable;         // Repeat read while BUSY flag is set
00079     }
00080     _enable      = DISABLE;         // Leave DISABLED upon exit
00081     _modeSel     = WRITE;           // Return to WRITE mode
00082     _commsBus[3].output();          // Reconfigure pin as output (MSB)
00083 }
00084 
00085 
00086 void C_displayMaster::calcDDRAM(int col, int row)
00087 {
00088     /* The following two IF statments create a continous display meaning that
00089     running of the right edge return you to the left edge and running of the
00090     bottom edge return you to the top row.                                    */
00091 
00092     if (col>16) {                   // If coloumn is outside of Right edge
00093         col =  1;                   // Go back to start of row
00094     } else if (col<1) {             // OR If coloumn is outside of Left edge
00095         col =  1;                   // Go back to start of row
00096     } else {                        // Othetwise
00097         col = col;                  // No change in col
00098     }
00099 
00100     if (row>2) {                    // If row is outside of Bottom edge
00101         row =  1;                   // Go back to top row
00102     } else if (row<1) {             // OR If row is outside of Top edge
00103         row =  1;                   // Go back to top row
00104     } else {                        // Othetwise
00105         row = row;                  // No change in row
00106     }
00107 
00108     _ADR = (1<<7)+((1<<6)*row-1)+col-1;   // Recalculate DDRAM address
00109 }
00110 
00111 
00112 void C_displayMaster::clear()
00113 {
00114     writeChar(0x01, INSTRUCTION);   // Clear display for writing (DDRAM cleared)
00115     _col = 1;                       // First coloumn
00116     _row = 1;                       // First row
00117     calcDDRAM(_col, _row);          // Get DDRAM address for writing next char
00118 }
00119 
00120 
00121 int C_displayMaster::_getc()
00122 {
00123     return -1;                      // Return Fail value since function has no purpose but is needed for character Stream
00124 }
00125 
00126 
00127 int C_displayMaster::_putc(int character)
00128 {
00129     if (character=='\n') {          // IF new line
00130         _row++;                     // Go to new row
00131         _col = 1;                   // Go to start of row
00132     } else if (character=='\r') {   // IF carridge return
00133         _col = 1;                   // Go to start of line
00134     } else {                        // ELSE
00135         
00136         calcDDRAM(_col, _row);          // Get cursor new address (N.B this function also creates a continous display. More details in function).
00137         writeChar(_ADR, INSTRUCTION);   // Set cursor to position
00138         writeChar(character, DATA);     // Write character
00139         
00140         _col++;                     // Increment cursor position
00141         if (_col>16) {              // IF end of row go to new row
00142             _row++;                 // Go to new row
00143             _col = 1;               // Go to start of row
00144         }
00145     }
00146     return character;               // Return what was written to indicate sucess
00147 }