// lcd.c - Explorer 16 with PIC32MX360F512L
// functions for the PC1602-J lcd display 8-bit mode
//
// see http://www.repairfaq.org/filipg/LINK/F_LCD_progr.html
#include "hardware.h"
#include "timer.h"
#include "lcd.h"
// LCD display ports etc
#define LCDdata LATE // data port
#define LCDdataEnable TRISE
#define RS LATBbits.LATB15 // RS bit in LCDstatus
#define RW LATDbits.LATD5 // read/write bit in LCDstatus
#define E LATDbits.LATD4 // enable bit in LCDstatus
#define Eenable TRISDbits.TRISD4
#define ERSenable TRISDbits.TRISD5
#define RWenable TRISBbits.TRISB15
void lcd_delay() { mSecDelay(1); } // if LCD does not work make this longer
// Write a byte to the LCD
// may have to adjust delays to suit the processor and clock
void lcdByte(int n)
{
lcd_delay();
LCDdata=n;
lcd_delay();
E=1; // take clock E high
lcd_delay();
E=0;
lcd_delay();
}
// Write a Control Command to the LCD
// This is written as two nibbles
void lcdCmd(int c)
{
RS=0; // Take RS pin low for command
lcdByte(c); // Makeup Lower Nibble
}
// write a data byte to LCD
int lcdPutchar(int d)
{
// printf("%c", d);
RS=1; // Take RS pin high for data
lcdByte(d); // Makeup Lower Nibble
return 1;
}
// Initialise the LCD in 4bit Mode
void lcdInit()
{
E=0; // take E low
RS=0; // Take RS pin low for command
RW=0; // Take RS pin low for command
// set RS, RW and E bits as output
Eenable =0;
ERSenable =0;
RWenable =0;
LCDdataEnable &= 0x0; // set bits 0-3 output for data
lcdByte(0x3); // This put the LCD into Soft Reset
lcdByte(0x3);
lcdByte(0x3);
lcdByte(0x2);
lcd_delay();
// lcdCmd(0x28); // 2 line, 4 bit mode
lcdCmd(0x38); // 2 line, 8 bit mode
lcd_delay();
lcdCmd(0x6); // increment cursor after each write
lcd_delay();
lcdCmd(0x1); // clear display
lcd_delay();
lcdCmd(0x2); // home
lcd_delay();
lcdCmd(0xF); // turn disply on
lcd_delay();
}
// move to line (1 or 2) at position >= 1
void lcdCursor(unsigned char line,unsigned char position)
{
switch (line)
{
case 1:lcdCmd (0x80 + position -1 );lcdCmd (0x80 + position -1 ); break;
case 2:lcdCmd (0xc0 + position -1 ); lcdCmd (0xc0 + position -1 ); break;
default : break;
}
lcd_delay();
}
void lcdString(unsigned char line, unsigned char position, unsigned char *string)
{
lcdCursor(line,position);
while (*string)
lcdPutchar(*string++);
}
void lcdStringAtCursor(unsigned char *string)
{
while (*string)
lcdPutchar(*string++);
}
void lcdClear(void)
{
lcdCmd(0x01);
}
void lcdHome(void)
{
lcdCmd(0x02);
}
// clear line 1 or line 2
void lcdClearLine(unsigned char line)
{
unsigned char i;
lcdCursor(line,1);
for (i=0; i<16; i++) lcdPutchar(' ');
lcdCursor(line,1);
}