Contains necessary classes and functions for ELEC351
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Tue Jul 12 2022 18:37:11 by
1.7.2