LCD 2x16 WINSTAR WH1602A with LPC1769 - something wrong

cancel
Showing results for 
Search instead for 
Did you mean: 

LCD 2x16 WINSTAR WH1602A with LPC1769 - something wrong

239 Views
NXP Employee
NXP Employee
Content originally posted in LPCWare by teslabox on Mon Oct 13 06:37:30 MST 2014
Hi everyone!

I try to communicate with my LCD display according to HD44780 but probably I do something wrong way.
I write C code step by step according the algorithm on page 42:
https://www.sparkfun.com/datasheets/LCD/HD44780.pdf
When I turn on the Vcc one line is lighting.
When I run uC with program this line disapears - so it can be good sign but there is no cursor or any char.

#include "LPC17xx.h"
#include <cr_section_macros.h>
#include <NXP/crp.h>

__CRP const unsigned int CRP_WORD = CRP_NO_CRP; // CRP - Code Read Protection; brak ochrony odczytu kodu

/* Pinout description:
 *
 * Cinfigure lines:
 * pin 4 - RS - GPIO P0.0 (Register Select: 0 - Instruction Register, 1 - Data Register)
 * pin 5 - RW - GPIO P0.1 (Read or Write: 0 - Write to the LCD, 1 - Read from the LCD)
 * pin 6 - EN - GPIO P0.2 (Enable/Clock: Data is latched on falling edge)
 *
 * Data bits lines (only MSB nibble) of 4 bits transmission:
 * pin 11 - DB4 - GPIO P2.0 (bit 0 - LSb)
 * pin 12 - DB5 - GPIO P2.1 (bit 1)
 * pin 13 - DB6 - GPIO P2.2 (bit 2)
 * pin 14 - DB7 - GPIO P2.3 (bit 3 - MSb)
 *
 */

void Timer0_MicroSeconds2 (uint32_t NanoSeconds);// Measured on oscilloscope - 1.0 us, work properly with ABP 100 MHz
void Timer0_MiliSeconds2 (uint32_t MiliSeconds);// Measured on oscilloscope - 1.0 ms, work properly with ABP 100 MHz

// Function of setting GPIO as outputs and RW and EN lines low
void SetPorts (void)
{
// Set all lines as GPIO output
LPC_GPIO2->FIODIR = ((1<<3)|(1<<2)|(1<<1)|(1<<0));// DATA lines - D0, D1, D2, D3 (4 bits)
LPC_GPIO0->FIODIR = ((1<<2)|(1<<1)|(1<<0));// Configure lines - RS, RW, EN (3 bits)
LPC_GPIO0->FIOCLR = (1<<1);// RW line on the GND all the time - only Write to the LCD
LPC_GPIO0->FIOCLR = (1<<2);// EN line low for start as a default state
Timer0_MiliSeconds2 (10);// Delay 10 ms for stable lines
}

// Function of dividing byte on MSB and LSB and send them to the HD44780
void SentLCD (uint8_t Byte)
{
// Send first nibble of the byte - MSB (b7-b4)
// Bus timing values according to Hitachi HD44780 user manual set - Write Operation Figure 25 on page 26
LPC_GPIO0->FIOSET = (1<<2);// Enable = 1
Timer0_MicroSeconds2 (1);// Delay 1 us (delay 150 ns at least)
LPC_GPIO2->FIOSET = ((Byte & 0xF0) >> 4);// Byte MSB shifted to LSB place and set on the data lines DB4-DB7
Timer0_MicroSeconds2 (1);// Delay 1 us (delay 80 ns at least)
LPC_GPIO0->FIOCLR = (1<<2);// Enable = 0
Timer0_MicroSeconds2 (2);// Delay 2 us (delay 250 ns at least)
// Untill here the MSB (4-bits) were sent to the LCD/HD44780
// The cycle of EN line was HI-2 us and LO-2 us so whole cycle took 2 us

// Send second nibble of byte - LSB
// Bus timing values according to Hitachi HD44780 user manual set - Write Operation Figure 25 on page 26
LPC_GPIO0->FIOSET = (1<<2);// Enable=1
Timer0_MicroSeconds2 (1);// Delay 1 us (delay 150 ns at least)
LPC_GPIO2->FIOSET = (Byte & 0x0F);// Byte LSB set on the data lines DB4-DB7
Timer0_MicroSeconds2 (1);// Delay 1 us (delay 80 ns at least)
LPC_GPIO0->FIOCLR = (1<<2);// Enable = 0
Timer0_MicroSeconds2 (2);// Delay 2 us (delay 250 ns at least)
// Until here the LSB (4-bits) were sent
// The cycle of EN line was HI-2 us and LO-2 us so whole cycle took again 2 us

// Whole byte sending (MSB + LSB) took 8 us together
}

// Function of the LCD setting and write them to the HD44780
void SetLCD (uint8_t Byte)
{
// Now writing data to the Instruction Register so line RS goes low
LPC_GPIO0->FIOCLR = (1<<0);// RS = 0
Timer0_MicroSeconds2 (1);// Delay 1 us (delay 80 ns at least)
//Now when RS line is low configure byte can be send
SentLCD (Byte);// Write data to the HD44780
// Let give 1 ms delay
Timer0_MiliSeconds2 (1);
}

// Function of sending data (chars) to the LCD
void DataLCD (uint8_t Data)
{
// Now writing to the Data Register so line RS goes high
LPC_GPIO0->FIOSET = (1<<0);// RS = 1
Timer0_MicroSeconds2 (1);// Delay 1us
SentLCD (Data);// Send data to the LCD
}

void StaticTxtLCD (char * s)
{
while (*s)
{
DataLCD (*s);
s++;
}
}

// Function of initializing the LDC
void InitLCD (void)
{
// Reset Function
// Initializing by Internal Reset Circuit
// Hitachi HD44780 user manual, page 23

// Set proper GPIOs for LDC lines
SetPorts ();
// Delay 50 ms for stable lines
Timer0_MiliSeconds2 (50);

// Now writing to the Setting Register so RS line goes low
LPC_GPIO0->FIOCLR = (1<<0);// RS = 0
Timer0_MicroSeconds2 (1);// Delay 1 us (delay 80 ns at least)
// Set EN line low as a default value for next steps
LPC_GPIO0->FIOCLR = (1<<2);// Enable=0
Timer0_MiliSeconds2 (10);// Delay 10 ms for stable

// Temporary variable for 'for' loop below only
uint8_t i = 0;

// Triple set DB4-DB7 (bits 4-7) as value 0x03 according to HD44780 user manual
for (i = 0; i < 3; i++)
{
LPC_GPIO0->FIOSET = (1<<2);// Enable = 1
Timer0_MicroSeconds2 (1);// Delay 1 us for EN line proper working
LPC_GPIO2->FIOSET = (0x03); // Set Data lines as 0x03 value
Timer0_MicroSeconds2 (1);// Delay 1 us for EN line proper working
LPC_GPIO0->FIOCLR = (1<<2);// Enable = 0
Timer0_MiliSeconds2 (5);// Delay 5ms (should be 4.1 ms at least)
}

Timer0_MiliSeconds2 (50);

// Main settings of the LCD
SetLCD (0x28);// 4-bit transmission, 2 or 4 lines LCD, char 5x8 dots
Timer0_MiliSeconds2 (5);
SetLCD (0x08);// Display Off, Cursor Off, Cursor Toggle Off
Timer0_MiliSeconds2 (5);
SetLCD (0x01);// Clear display
Timer0_MiliSeconds2 (5);
SetLCD (0x06);// Shift characters right (not left), Cursor is moving and window LCD is non-moving
Timer0_MiliSeconds2 (5);
SetLCD (0x0F);// Display On, Cursor On, Cursor Toggle On
Timer0_MiliSeconds2 (5);

Timer0_MiliSeconds2 (50);

}
// Main program
int main (void)
{
// Set the Timer0 for proper delays timing
LPC_SC->PCONP |= (1<<1); // Set Power On for Timer0
LPC_SC->PCLKSEL0 |= (1<<2); // Timer0 CLK = APB = 100 MHz (Divider = 1)
LPC_SC->PCLKSEL0 &=~(1<<3); // Timer0 CLK = APB = 100 MHz (Divider = 1)

// Set GPIO P0.22 as output - there is a LED diode for toggle
LPC_GPIO1->FIODIR = ((1<<30)|(1<<31));
LPC_GPIO1->FIOCLR = ((1<<30)|(1<<31));

InitLCD ();
DataLCD (36);

for (;;)
{
LPC_GPIO1->FIOSET = ((1<<30)|(1<<31));
Timer0_MiliSeconds2 (100);
LPC_GPIO1->FIOCLR = ((1<<30)|(1<<31));
Timer0_MiliSeconds2 (100);
}

return (0);
}

void Timer0_MicroSeconds2 (uint32_t MicroSeconds)
{
LPC_TIM0->TCR = 0x02;/* reset timer */
LPC_TIM0->PR  = 0x00;/* set prescaler to zero */
LPC_TIM0->MR0 = MicroSeconds;
LPC_TIM0->IR  = 0xff;/* reset all interrrupts */
LPC_TIM0->MCR = 0x04;/* stop timer on match */
LPC_TIM0->TCR = 0x01;/* start timer */

/* wait until delay time has elapsed */
while (LPC_TIM0->TCR & 0x01);
}

void Timer0_MiliSeconds2 (uint32_t MiliSeconds)
{
LPC_TIM0->TCR = 0x02;/* reset timer */
LPC_TIM0->PR  = 0x00;/* set prescaler to zero */
LPC_TIM0->MR0 = MiliSeconds*100000;
LPC_TIM0->IR  = 0xff;/* reset all interrrupts */
LPC_TIM0->MCR = 0x04;/* stop timer on match */
LPC_TIM0->TCR = 0x01;/* start timer */

/* wait until delay time has elapsed */
while (LPC_TIM0->TCR & 0x01);
}


What's wrong? I followed this code many times but I can't find the bug.
Labels (1)
0 Kudos
1 Reply

62 Views
NXP Employee
NXP Employee
Content originally posted in LPCWare by IanB on Tue Oct 14 14:32:07 MST 2014
It may not be software at all.
Have you adjusted the contrast pot?
0 Kudos