// lcd.c - functions for the PC1602-J lcd display 4-bit mode
//
// see http://www.repairfaq.org/filipg/LINK/F_LCD_progr.html
#include "hardware.h"
#include "lcd.h"
#include <libpic30.h> // for __delay_us FCY must be defined!
// LCD display ports etc
#define LCDdata LATE // data port
#define LCDstatus LATEbits // control/status port
#define RS LATE4 // RS bit in LCDstatus
#define RW LATE5 // read/write bit in LCDstatus
#define E LATE6 // enable bit in LCDstatus
//void lcd_delay() { __delay_us(800); }//mSecDelay(1); } // if LCD does not work make this longer
// Write a nibble to the LCD
// may have to adjust delays to suit the processor and clock
void lcdNibble(int n)
{
int lcd=LCDdata;
// lcd_delay();
__delay_us(800);
LCDdata = (lcd&0xfff0) | ((n & 0x0f)); // send out lower Nibble
//lcd_delay();
// __delay_us(1);
Nop(); // Wait E Pulse width time (min 230ns)
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
LCDstatus.E=1; // take clock E high
// __delay_us(1);
Nop(); // Wait E Pulse width time (min 230ns)
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
Nop();
//lcd_delay();
LCDstatus.E=0;
__delay_us(800);
//lcd_delay();
}
// Write a Control Command to the LCD
// This is written as two nibbles
void lcdCmd(int c)
{
LCDstatus.RS=0; // Take RS pin low for command
lcdNibble(c >>4); // Makeup Upper Nibble
lcdNibble(c); // Makeup Lower Nibble
}
// write a data byte to LCD
int lcdPutchar(int d)
{
// printf("%c", d);
LCDstatus.RS=1; // Take RS pin high for data
lcdNibble(d >>4); // Makeup Upper Nibble
lcdNibble(d); // Makeup Lower Nibble
return 1;
}
// Initialise the LCD in 4bit Mode
void lcdInit()
{
// TRISEbits.TRISE4=0; // set RS and E bits output
//TRISDbits.TRISD1=0; // set RS and E bits output
TRISE &= 0x0; // set bits 0-3 output for data
TRISE |= 0x80;
LCDstatus.RS=0; // Take RS pin low for command
LCDstatus.RW=0; // Take RS pin low for WRITE
lcdNibble(0x3); // This put the LCD into Soft Reset
lcdNibble(0x3);
lcdNibble(0x3);
lcdNibble(0x2);
lcdCmd(0x28); // 2 line, 4 bit mode
lcdCmd(0x6); // increment cursor after each write
lcdCmd(0x1); // clear display
lcdCmd(0x2); // home
lcdCmd(0xF); // turn disply on
}
// move to line (1 or 2) at position >= 1
void lcdCursor(unsigned char line,unsigned char position)
{
#define lcd_line_1 0x00 // LCD RAM address for the 1st line
#define lcd_line_2 0x40 // LCD RAM address for the 2nd line
#define lcd_line_3 0x14 // LCD RAM address for the 3rd line
#define lcd_line_4 0x54 // LCD RAM address for the 4th line
char lineAddress[]={0x00, 0x40, 0x14, 0x54 };
lcdCmd ((0x80 | lineAddress[line-1]) + position -1 );
/* 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, char *string)
{
lcdCursor(line,position);
while (*string)
lcdPutchar(*string++);
}
// display string on line starting at position 1, clear rest of line
void lcdStringOnLine(unsigned char line, char *string)
{
lcdCursor(line,1);
int i=0;
for(i=0; (i<20) && (*string); i++, string++)
lcdPutchar(*string);
while(i++<20)
lcdPutchar(' ');
}
void lcdStringAtCursor(char *string)
{
//printf("lcdStringAtCursor %s\n", 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<20; i++) lcdPutchar(' ');
lcdCursor(line,1);
}
void LCDtest(void)
{
//mSecElapsed(const int counter, const int reset, const long unsigned int delay);
mSecElapsed(2,3,0);
int count=0;
while(!mSecElapsed(2, 0, 10000))
{ lcdString(2,1, "Mechatronics trainer"); ; count++; }
printf("LCD count X %d\n", count);
}