Interfacing PIC with LCD (Details Inside!)

Status
Not open for further replies.

jegues

Member level 3
Joined
May 29, 2011
Messages
58
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,915
The PIC being used is: PIC16F877A

LCD beind used is:
NHD‐0216KZ‐FSW‐GBW


The objective is to get the LCD to display the following message,

"Bananas $0.49/lb"
- for 5 seconds, followed by,

"WOW!" - which is centered on the display and blinking at a rate of once per second for 3 seconds (i.e. 500ms on 500ms off).

I'm having trouble finding information on the correct procedure to use the LCD, and a large portion of the code used in my program has been provided by our instructor.

I have a feeling that before I attempt to, writeString("Hello World!"), to the LCD I must first set the display line and place the cursor accordingly which I don't know how to do. We have been given an incomplete function called setDisplayLine(), but I'm not entirely sure in what sense it is incomplete, nor what the codes being passed to the command function represent.

Then again, I'm not even sure if that is the correct procedure to follow.

Does anyone know?

I've been looking for a data sheet, but all I've been able to find is pinouts which I already have.

See below for my code. (I appologize as the indentation is ruined when I paste it into the forum)

Thanks for the help!

Code:
#include <htc.h>
#include <string.h>
#include "ProcessorConfiguration.h"
#include "FunctionPrototypes.h"
#include "Definitions.h"

void main(void){

	portInit();
	LCDInit();
	writeString("Hello World!");
	
}

static void interrupt isr(void){

}

//May be moved to its own .c file later

void LCDInit(void){
	E = 0; 
	delay(15); //Wait >15 msec after power is applied 
	initCommand(0x30); //command 0x30 = Wake up 
	delay(5); //must wait 5ms, busy flag not available 
	initCommand(0x30); //command 0x30 = Wake up #2 
	delay(160); //must wait 160us, busy flag not available 
	initCommand(0x30); //command 0x30 = Wake up #3 
	delay(160); //must wait 160us, busy flag not available 
	command(0x38); //Function set: 8-bit/2-line 
	command(0x10); //Cursor shift mode, S/C to the Left 
	command(0x0C); //1DCB: Display ON; Cursor OFF; Blink OFF 
	command(0x06); //Entry mode: Inc cursor and display shift off 
	clearDisplay(); 
	returnHome(); 

}

void initCommand(char theCommand){ //Cannot Utilize BF
	LCDCOMMAND = theCommand; //put command on PORTD 
	RS = RS_COMMAND; // Select Command Register 
	RWn = WRITE; // Write Mode 
	E = 1; 
	E = 0; //Clock enable: falling edge 
}

void command(char theCommand) { 
	waitForNotBusy(); 
	LCDCOMMAND = theCommand; //put command on PORTD 
	RS = RS_COMMAND; // Select Command Register 
	RWn = WRITE; // Write Mode 
	E = 1; 
	E = 0; //Clock enable: falling edge 
}

void clearDisplay(void) { 
	waitForNotBusy(); 
	command(0x01); //Clear Display 
}

void returnHome(void) { 
	waitForNotBusy(); 
	command(0x02); //Return Home 
}

void waitForNotBusy(void) { 
	unsigned char BF; 

	RS = RS_COMMAND; // Select Command Register 
	RWn = READ; // Read Mode 
	BF = 0b10000000; 
	TRISD = 0b11111111; 
	delay(1); // Wait at least 80 μs before reading BF 

	while(BF==0b10000000){ 
		E = 1; 
		BF = LCDDATA & 0b10000000; 
		E = 0; //Clock enable: falling edge 
	}
	TRISD = 0b00000000; 
}

void delay(unsigned char loops) {
	unsigned char i;
	loops += 69;
	for(i=0; i<loops;i++){}
}

//End of block pasted from LCDInitialization.c

void setDisplayLine(unsigned char line, unsigned char position) { //This function is incomplete.
	switch(line) { 
		case 1:command(0b01000000); 
		break; 
		case 2:command(0b11000000);
		break; 
	} 
}

void writeChar(char theData) { 
	waitForNotBusy(); 
	LCDDATA = theData; //put data on PORTD 
	RS = RS_DATA; // Select Data Register 
	RWn = WRITE; // Write Mode 
	E = 1; //enable pulse width >= 300ns 
	E = 0; //Clock enable: falling edge 
}

void writeString(char *theString) { 
	unsigned char i; 
	for(i = 0; i < strlen(theString); i++) { 
		waitForNotBusy(); 
		LCDDATA = theString[i]; // Put data on PORTD 
		RS = RS_DATA; // Select Data Register 
		RWn = WRITE; // Write Mode 
		E = 1; // Enable pulse width >= 300ns 
		E = 0; // Clock enable: falling edge 
	} 
}

And the code for portInit(),

Code:
#include <htc.h>

void portInit(void){
//Configure for Digital IO
PCFG3 = 0;
PCFG2 = 1;
PCFG1 = 1;

TRISE0 = 0;
TRISE1 = 0;
TRISE2 = 0;
TRISD = 0b00000000; //Configure PORTD for output

INTCON = 0; //Disable interrupts.
}
 

Most LCD's have a common command set, here is a link to some info.

HD44780 Commands

For formatting
Your editor should have an option to use TABS or Spaces.
If you convert the tabs to spaces, your indentation will be ok.
 

hello,

this example is in C18, for a 2x16 car LCD
but you can transpose easily...
LCD_Cde(unsigned char cmd) ~ command(char theCommand)

Code:
#define LCD_L1home()    LCD_Cde(0x80)
#define LCD_L2home()    LCD_Cde(0xC0)
#define LCD_Clear()     LCD_Cde(0x01)
#define LCD_ReturnHome() LCD_Cde(0x02)

void LCD_Pos(char L,char posX)
{
 char x;
 if (L==1) x=0x80+posX;
 if (L==2) x=0xC0+posX;
 LCD_Cde(x);
}
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…