// lcdTest.cpp - test harness for CFAH1601A lcd
boolean USING_RW = true; // RW is connected but is always held low
#define RS 7 // LCD pin 4
#define RW 6 // LCD pin 5
#define Enable 5 // LCD pin 6
uint8_t DB[] = {9,10,11,12}; //these pins are wired to DB4~7 on display (lcd pins 11-14)
/**************** LCD controller chip interface functions *************/
//pulse the Enable pin high
//This clocks whatever command or data is on upper 4 bits into the LCD controller.
void pulseEnablePin(){
digitalWrite(Enable,LOW);
delayMicroseconds(3);
digitalWrite(Enable,HIGH);
delayMicroseconds(3);
digitalWrite(Enable,LOW);
delayMicroseconds(40);
}
//push a nibble of data through the the LCD's DB4~7 pins, clocking with the Enable pin.
//We don't care what RS and RW are, here.
void pushNibble(uint8_t value){
uint8_t val_nibble= value & 0x0F; //clean the value. (unnecessary)
for (uint8_t i = DB[0]; i <= DB[3]; i++) {
digitalWrite(i,val_nibble & 01);
val_nibble >>= 1;
}
pulseEnablePin();
}
//push a byte of data through the LCD's DB4~7 pins, in two steps, clocking each with the enable pin.
void pushByte(uint8_t value){
uint8_t val_lower = value & 0x0F;
uint8_t val_upper = value >> 4;
pushNibble(val_upper);
pushNibble(val_lower);
}
void commandWriteNibble(uint8_t nibble) {
digitalWrite(RS, LOW);
if (USING_RW) { digitalWrite(RW, LOW); }
pushNibble(nibble);
}
void commandWrite(uint8_t value) {
digitalWrite(RS, LOW);
if (USING_RW){
digitalWrite(RW, LOW);
}
pushByte(value);
}
/**************** end of LCD controller chip low level interface functions *************/
// function to initialise the interface, called once from main
void setup() {
pinMode(Enable,OUTPUT); // set pins connected to LCD as outputs
pinMode(RS,OUTPUT);
pinMode(DB[0],OUTPUT);
pinMode(DB[1],OUTPUT);
pinMode(DB[2],OUTPUT);
pinMode(DB[3],OUTPUT);
if (USING_RW) {
pinMode(RW,OUTPUT);
digitalWrite(RW, LOW); // set RW low (it will never be set high in this code)
}
delay(50);
commandWriteNibble(0x03); // Function set
delay(5); // note output pins are connected to the LCD most significant 4 bits
commandWriteNibble(0x03); // so this should be the same as writing 0x30 to the byte !
delay(125);
commandWriteNibble(0x03);
delay(5);
commandWriteNibble(0x02); // set controller to 4 bit mode
delay(1);
#define ONE_LINE // if not defined, lcd initialized for two lines, but nothing is displayed!!!
#ifdef ONE_LINE
commandWrite(0x20 ); // one line , 4 bit ----- this displays left 8 chars only
delayMicroseconds(60);
#else
commandWrite(0x28 ); // two line , 4 bit >>>> this displays nothing !!!!!
delayMicroseconds(60);
#endif
commandWrite(0x0C); // turn display on, cursor off, no blinking
delayMicroseconds(60);
commandWrite(0x01); // clear display
delay(3);
commandWrite(0x06); // entry mode set
delay(1);
}
//print the given character at the current cursor position.
void print(char value) {
//set the RS pin to show we're writing data
digitalWrite(RS, HIGH);
pushByte(value);
}
//print the given string to the LCD at the current cursor position.
void printIn(char* msg) {
uint8_t i;
for (i = 0; i < strlen(msg); i++){
print(msg[i]);
}
}
// function to position the curson on the first or second line at the ram address given in x
void cursorTo(uint8_t line_num, uint8_t x){
switch (line_num){
case 1: commandWrite(0x80 + x); break;
case 2: commandWrite(0xc0 + x); break; // add 0x40 hex to addr if line 2
}
}
// after setup() initialises the LCD, this functon is called to repeatedly send chars to the lcd
void loop() {
commandWrite(0x01); // clear display
delay(3);
cursorTo(1,0) ; // first line, first char position
printIn("hello >8"); // a string of 16 printable chars - this works ok
delay(1000);
commandWrite(0x01); // clear display
delay(2);
cursorTo(1,0x40); // first line, address 0x40
printIn("...world"); // BUG: nothing displayed on LCD
delay(1000);
commandWrite(0x01); // clear display
delay(2);
cursorTo(2,0); // logical line 2, this should add 40 hex to the cursor position
printIn("<8 more?"); // BUG: nothing displayed on LCD
delay(1000);
/*
for(int i = 0; i < 80; i++ ){
cursorTo(1,i);
print(i + 'A');
}
delay( 1000);
*/
}