Contains necessary classes and functions for ELEC351
displayMaster/displayMaster.cpp
- Committer:
- Luka_Danilovic
- Date:
- 2018-01-09
- Revision:
- 7:92b4783af1d2
- Parent:
- 5:becb1545229d
File content as of revision 7:92b4783af1d2:
#include "mbed.h" #include "displayMaster.hpp" //////////////////////////////////////////////////////////////////////////////// // INCOMPLETE - RUN OUT OF TIME TO DEBUG // //////////////////////////////////////////////////////////////////////////////// /* Instructions on using the 16x2 LCD panel are found here: [https://www.8051projects.net/lcd-interfacing/lcd-4-bit.php] */ /* N.B. I did the code from scratch since I do not have the code from ELEC230 */ /* N.B. This class contains blocking function so it goes into its own thread */ C_displayMaster::C_displayMaster(PinName D1, PinName D2, PinName D3 , PinName D4 , PinName RS , PinName RW, PinName EN) : // Initialisation of the instance _commsBus(D1, D2, D3, D4), _registerSel(RS), _modeSel(RW), _enable(EN) { _registerSel = INSTRUCTION; // command mode _modeSel = WRITE; // write mode Thread::wait(20); // Wait 20ms to ensure powered up for (int i=0; i<3; i++) { // Three times _enable = DISABLE; // Invalidate signal _commsBus = 0x03; // Send command for powerup _enable = ENABLE; // Validate signal Thread::wait(20); // Wait since BUSY flag is not yet available } _enable = DISABLE; // Invalidate signal _commsBus = 0x03; // Send command for 4 bit mode _enable = ENABLE; // Validate signal Thread::wait(20); // Wait since BUSY flag is not yet available // BUSY flag is now available, Can use "writeChar" // writeChar(0x28, INSTRUCTION); // 4-bit, 2 Line, 5x7 Dots writeChar(0x0C, INSTRUCTION); // Display on Cursor off writeChar(0x04, INSTRUCTION); // Entry mode - no increment & no display shift clear(); // Clear display for writing (DDRAM cleared) // writeChar(0b00100011, DATA); // Write Test "#" symbol // Thread::wait(1000); // Wait 1 second // clear(); // Clear Test "#" symbol } //****************************************************************************// void C_displayMaster::writeChar(int Char, bool REGISTER) { _enable = DISABLE; // DISABLE at start _commsBus[3].output(); // Reconfigure pin as output (MSB) _registerSel = REGISTER; // Chose register to comunicate with _modeSel = WRITE; // WRITE to register _commsBus = (Char>>4); // Top nibble _enable = ENABLE; // Validate signal _enable = DISABLE; // Invalidate signal busyCheck(); // Chek if clear to write more _commsBus = (Char>>0); // Bottom nibble _enable = ENABLE; // Validate signal _enable = DISABLE; // Invalidate signal busyCheck(); // Chek if clear to write more } void C_displayMaster::busyCheck() { _enable = DISABLE; // DISABLE at start _commsBus[3].input(); // Input to listen for BUSY flag (MSB) _registerSel = INSTRUCTION; // Comunicate with INSTRUCTION register _modeSel = READ; // READ from register _enable = ENABLE; // Listen for BUSY flag while(_commsBus[3]) { _enable != _enable; // Repeat read while BUSY flag is set } _enable = DISABLE; // Leave DISABLED upon exit _modeSel = WRITE; // Return to WRITE mode _commsBus[3].output(); // Reconfigure pin as output (MSB) } void C_displayMaster::calcDDRAM(int col, int row) { /* The following two IF statments create a continous display meaning that running of the right edge return you to the left edge and running of the bottom edge return you to the top row. */ if (col>16) { // If coloumn is outside of Right edge col = 1; // Go back to start of row } else if (col<1) { // OR If coloumn is outside of Left edge col = 1; // Go back to start of row } else { // Othetwise col = col; // No change in col } if (row>2) { // If row is outside of Bottom edge row = 1; // Go back to top row } else if (row<1) { // OR If row is outside of Top edge row = 1; // Go back to top row } else { // Othetwise row = row; // No change in row } _ADR = (1<<7)+((1<<6)*row-1)+col-1; // Recalculate DDRAM address } void C_displayMaster::clear() { writeChar(0x01, INSTRUCTION); // Clear display for writing (DDRAM cleared) _col = 1; // First coloumn _row = 1; // First row calcDDRAM(_col, _row); // Get DDRAM address for writing next char } int C_displayMaster::_getc() { return -1; // Return Fail value since function has no purpose but is needed for character Stream } int C_displayMaster::_putc(int character) { if (character=='\n') { // IF new line _row++; // Go to new row _col = 1; // Go to start of row } else if (character=='\r') { // IF carridge return _col = 1; // Go to start of line } else { // ELSE calcDDRAM(_col, _row); // Get cursor new address (N.B this function also creates a continous display. More details in function). writeChar(_ADR, INSTRUCTION); // Set cursor to position writeChar(character, DATA); // Write character _col++; // Increment cursor position if (_col>16) { // IF end of row go to new row _row++; // Go to new row _col = 1; // Go to start of row } } return character; // Return what was written to indicate sucess }