Pages

Monday, January 14, 2013

MCP23008 IO Expander - LCD1602

I am also reading my old Arduino LCD1602 class, played around 2011 April.

/// *************************************************************************
/// LCD60.cpp
/// Function: Test LCD1602
/// Created: 2011apr07
/// Updated: 2011apr23hkt1455
/// Author: TL Fong
http://hk.myblog.yahoo.com/tlfong01-diy
/// Hardware Configuration:
/// - Intel Core i5 650 (3.2GHz, 4MB cache, 2 core 4 thread, 64 bit instruction)  
/// - Asus P7H55-M/USB3 4GB RAM (2010)
/// - Arduino Decimilla/Mega, Netduino
/// - LCD YJD1602A (5.0V)
/// Software Configuration:
/// - Chinese Windows 7 Home Premium OEM 32 bit (2009)
/// - Arduino IDE 0021 C++
/// - Visual C# 2010 Express
/// - .NET Micro Framework 4.1
/// - Netduino SDK 4.1
/// References:
/// - LongTech Optics LCM1602A-FL-YBW datasheet (2007)
/// - Hitachi HD44780U (LCD-II) datasheet rev0.0 (1998)
/// Copyright:
/// Creative Commons 3.0, Apache 2.0, Free software for DIY hobbists
/// *************************************************************************

#include "WProgram.h"
#include <LCD60.h>

const int POWER_RESET_INSTRUCTION_0X30 = 0x30;
const int POWER_RESET_INSTRUCTION_0X20 = 0x20;
const int EIGHT_BIT_TWO_LINE_FIVE_TIMES_TEN_DOT = 0x28;
const int CURSOR_ON_SHIFT_ON = 0x06;
const int DISPLAY_ON_CURSOR_ON_BLINK_ON = 0x0C;
const int CLEAR = 0x01;
const int HOME = 0x02;

const int INSTRUCTION_REGISTER = 0;
const int DATA_REGISTER = 1;
const int LOW_NIBBLE = 0;
const int HIGH_NIBBLE = 1;
const int NULL_CHARACTER = 0x00;

const int POWER_RESET_DELAY           = 5000;
const int VERY_LONG_INSTRUCTION_DELAY = 5000;
const int LONG_INSTRUCTION_DELAY      = 2000;
const int SHORT_INSTRUCTION_DELAY     =  100;

/// *************************************************************************
/// Mcu specific functions
/// *************************************************************************

void lcd60::setupMcu()
  {
  pinMode(_rsPin, OUTPUT);
  pinMode(_enablePin, OUTPUT);
  pinMode(_dataPin0, OUTPUT);
  pinMode(_dataPin1, OUTPUT);
  pinMode(_dataPin2, OUTPUT);
  pinMode(_dataPin3, OUTPUT);
  }

void lcd60::writeLcdPin(int pinId, int voltageLevel) 
  {
  if (voltageLevel == HIGH)
    digitalWrite(pinId, HIGH);
  else
    digitalWrite(pinId, LOW);
  }

void lcd60::powerResetDelay()
  {
    delayMicroseconds(POWER_RESET_DELAY);
  }

void lcd60::veryLongInstructionDelay()
  {
    delayMicroseconds(VERY_LONG_INSTRUCTION_DELAY);
  }

void lcd60::longInstructionDelay()
  {
  delayMicroseconds(LONG_INSTRUCTION_DELAY);
  }

void lcd60::shortInstructionDelay()
  {
  delayMicroseconds(SHORT_INSTRUCTION_DELAY);
  }

/// *************************************************************************
/// End of Arduino specific functions
/// *************************************************************************

lcd60::lcd60(int rsPin, int enablePin, int dataPin0, int dataPin1, int dataPin2, int dataPin3)
  {
  _rsPin = rsPin;
  _enablePin = enablePin;
  _dataPin0 = dataPin0;
  _dataPin1 = dataPin1;
  _dataPin2 = dataPin2;
  _dataPin3 = dataPin3;

  setupMcu();
  setupLcd();
  }

void lcd60::setupLcd()
  {
  disableWritePulse();
   
  powerResetDelay();

  writeNibble(POWER_RESET_INSTRUCTION_0X30, HIGH_NIBBLE, INSTRUCTION_REGISTER); 
  veryLongInstructionDelay();    

  writeNibble(POWER_RESET_INSTRUCTION_0X30, HIGH_NIBBLE, INSTRUCTION_REGISTER);
   
  writeNibble(POWER_RESET_INSTRUCTION_0X30, HIGH_NIBBLE, INSTRUCTION_REGISTER);
 
  writeNibble(POWER_RESET_INSTRUCTION_0X20, HIGH_NIBBLE, INSTRUCTION_REGISTER);
 
  writeDataByte(EIGHT_BIT_TWO_LINE_FIVE_TIMES_TEN_DOT, INSTRUCTION_REGISTER);

  writeDataByte(DISPLAY_ON_CURSOR_ON_BLINK_ON, INSTRUCTION_REGISTER);
 
  writeDataByte(CURSOR_ON_SHIFT_ON, INSTRUCTION_REGISTER);
 
  writeDataByte(CLEAR, INSTRUCTION_REGISTER);

  writeDataByte(HOME, INSTRUCTION_REGISTER);
  }

 void lcd60::selectInstructionRegister()
   {
   writeLcdPin(_rsPin, LOW);
   }

 void lcd60::selectDataRegister()
   {
   writeLcdPin(_rsPin, HIGH);
   }

  void lcd60::disableWritePulse()
    {
    writeLcdPin(_enablePin, LOW);
 }

  void lcd60::enableWritePulse()
    {
 writeLcdPin(_enablePin, HIGH);
    writeLcdPin(_enablePin, LOW);
 }


void lcd60::writeNibble(int dataByte, int nibblePosition, int registerType)
  {
  switch (registerType)
    {
    case INSTRUCTION_REGISTER:
   selectInstructionRegister();
      break;
    case DATA_REGISTER:
   selectDataRegister();
      break;
    }     
   
  disableWritePulse();

  int dataPin[5] = {_dataPin0, _dataPin1, _dataPin2, _dataPin3};
  if (nibblePosition == HIGH_NIBBLE)
 {
     for (int i = 0; i < 4; i++)  // write high nibble
      {
      writeLcdPin(dataPin[i], (dataByte >> (i + 4)) & 0x01);     
      }
    }
  if (nibblePosition == LOW_NIBBLE)
 {
     for (int i = 0; i < 4; i++)  // write high nibble
      {
      writeLcdPin(dataPin[i], (dataByte >> i) & 0x01);     
      }
    }
 
  enableWritePulse();

  longInstructionDelay();
  } 


void lcd60:: writeDataByte(int dataByte, int registerType)
  {
  writeNibble(dataByte, HIGH_NIBBLE, registerType); 
  writeNibble(dataByte, LOW_NIBBLE, registerType); 
  }


void lcd60::cursor(int row, int column)
  {
  switch (row)
    {
    case 1:
      writeDataByte(0x80 | (0x00 + (column - 1)), INSTRUCTION_REGISTER); 
      break;  
    case 2:
      writeDataByte(0x80 | (0x40 + (column - 1)), INSTRUCTION_REGISTER);    
      break;
    case 3:
      writeDataByte(0x80 | (0x14 + (column - 1)), INSTRUCTION_REGISTER); 
      break;  
    case 4:
      writeDataByte(0x80 | (0x54 + (column - 1)), INSTRUCTION_REGISTER);    
      break;
    default:
      break;
    }    
  }

void lcd60:: clear()
  {
  writeDataByte(CLEAR, INSTRUCTION_REGISTER);
  veryLongInstructionDelay();
  }

void lcd60::home()
  {
  writeDataByte(HOME, INSTRUCTION_REGISTER);
  veryLongInstructionDelay();
  }

void lcd60::printChar(char xchar)
  {
  writeDataByte(xchar, DATA_REGISTER);
  }

void lcd60::printLine(String str)
  {
  for (int i = 0; i < str.length(); i++)
    {
    printChar(str.charAt(i));
    }
  }  

/// *************************************************************************
/// LCD60.cpp
/// *************************************************************************

/// *************************************************************************
/// testLCD60_2011apr2301.pde
/// 2011apr23hkt1453
/// *************************************************************************
#include "LCD60.h"

#define LINE_01 "Hello World 010"
#define LINE_02 "2011apr23hkt1512"

// *** Arduino to LCD1602 pins assignment 01 ***  
#define RS_PIN     38
#define ENABLE_PIN 39
#define DATA_PIN_0 40
#define DATA_PIN_1 41
#define DATA_PIN_2 42
#define DATA_PIN_3 43

// *** Arduino to LCD1602 pins assignment 02 ***  
/*
#define RS_PIN     38
#define ENABLE_PIN 39
#define DATA_PIN_0 44
#define DATA_PIN_1 45
#define DATA_PIN_2 46
#define DATA_PIN_3 47
*/

void test()
  {
  lcd60 lcd(RS_PIN, ENABLE_PIN, DATA_PIN_0, DATA_PIN_1, DATA_PIN_2, DATA_PIN_3);
  lcd.clear();
  lcd.printLine(LINE_01); 
  lcd.cursor(2, 1);
  lcd.printLine(LINE_02); 
  while (true) { };
  }

void setup()
  {
  }
 
void loop()
  {
  test();
  }

// *** End of testLCD060 ***
.END

No comments:

Post a Comment