interfacing PIC16f676 to CFAH8002A-YYH-JP

live2surf

New member
Initially I tagged my problem at the end of another thread but I would like more input so I decided to start a new thread.

My problem is this;

I have successfully interfaced my PIC16f676 to an Optrex DMC 50448N LCD using the built in LCD functions provided in PIC Basic Pro. I then found Crystalfontz's website and found their LCDs to be cheaper in volume then optrex so I decided to use them in my design. The problem is that when I got the Crystalfontz LCD CFAH0802-YYH-JP and dropped it into the circuit in place of the optrex it did not work. I thought that these type of LCDs, i.e. HD44780 or equivalent , were or should be interchangable. Is this not the case? Has anyone run into similiar issues and if so how were they resolved?

I am now trying to manually initialize the LCD and write data to it without using the builtin LCD functions. Here is my setup. I am using a 4-bit bus, the R/W line is hardwired low for write only, D7-D4 are wired to PORTC pins 3-0 respectively, enable is wired to PORTC bit 5, and RS bit is wired to PORTC bit 4. the PIC16f676 is a 14 pin chip and I have no spare I/O pins or any other pins for that matter available to change design it must work in this configuration or I will be forced back to Optrex LCDs.

I have spent several DAYS trying different combinations of the initalization sequence from the Cfontz datasheet to no avail. the closest I have come is to get the LCD initialized, I think!?, but cannot get characters to display. At the end of the initialization sequence I get either a cursor with a blinking square or a the last character before the square, a small o with two dots on top, in position one and then a cursor with a blinking square in position two. Then when I try to write data it looks like it wants to display but ll I get are squares appearing. Not only that but two at a time like it does not recognize that I am in 4-bit mode where it takes two writes to transfer the 8-bit character to the DDRAM. I am baffeled. Here is my code I am using to try this manual initialization and writing. I use very long pauses in there so I can see what the display looks like after each step. Any and all suggestions or comments are welcome. :D

TRISC = 0
'LCD INIT
PAUSE 2000

PORTC.4 = 0
PAUSEUS 1
PORTC.5 = 1
PAUSEUS 1
PORTC = %100011 'FIRST TIME
PAUSEUS 1
PORTC.5 = 0

PAUSE 100

PORTC.4 = 0
PAUSEUS 1
PORTC.5 = 1
PAUSEUS 1
PORTC = %100011 'SECOND TIME
PAUSEUS 1
PORTC.5 = 0

PAUSE 100

PORTC.4 = 0
PAUSEUS 1
PORTC.5 = 1
PAUSEUS 1
PORTC = %100011 'THIRD TIME
PAUSEUS 1
PORTC.5 = 0

PAUSE 1

PORTC.4 = 0
PAUSEUS 1
PORTC.5 = 1
PAUSEUS 1
PORTC = %100010 'FUNCTION SET (SET INTERFACE TO 4 BITS LONG)
PAUSEUS 1
PORTC.5 = 0

PAUSE 5000

PORTC.4 = 0
PAUSEUS 1
PORTC.5 = 1
PAUSEUS 1
PORTC = %100010 'FUNCTION SET (SET INTERFACE TO 4 BITS LONG)
PAUSEUS 1
PORTC.5 = 0

PAUSE 1

PORTC.4 = 0
PAUSEUS 1
PORTC.5 = 1
PAUSEUS 1
PORTC = %101000 'FUNCTION SET DISPLAY LINES = 2 FONT = 5X8
PAUSEUS 1
PORTC.5 = 0

PAUSE 1

PORTC.4 = 0
PAUSEUS 1
PORTC.5 = 1
PAUSEUS 1
PORTC = %100000 'DISPLAY ON
PAUSEUS 1
PORTC.5 = 0

PAUSE 1

PORTC.4 = 0
PAUSEUS 1
PORTC.5 = 1
PAUSEUS 1
PORTC = %101110
PAUSEUS 1
PORTC.5 = 0

PAUSE 1

PORTC.4 = 0
PAUSEUS 1
PORTC.5 = 1
PAUSEUS 1
PORTC = %100000 'DISPLAY CLEAR
PAUSEUS 1
PORTC.5 = 0

PAUSE 1

PORTC.4 = 0
PAUSEUS 1
PORTC.5 = 1
PAUSEUS 1
PORTC = %100001
PAUSEUS 1
PORTC.5 = 0

PAUSE 1

PORTC.4 = 0
PAUSEUS 1
PORTC.5 = 1
PAUSEUS 1
PORTC = %100000 'ENTRY MODE SET
PAUSEUS 1
PORTC.5 = 0

PAUSE 1

PORTC.4 = 0
PAUSEUS 1
PORTC.5 = 1
PAUSEUS 1
PORTC = %100110
PAUSEUS 1
PORTC.5 = 0

PAUSE 5000

PORTC.4 = 0
PAUSEUS 1
PORTC.5 = 1
PAUSEUS 1
PORTC = %100000 'CLEAR DISPLAY
PAUSEUS 1
PORTC.5 = 0

PAUSE 1

PORTC.4 = 0
PAUSEUS 1
PORTC.5 = 1
PAUSEUS 1
PORTC = %100001
PAUSEUS 1
PORTC.5 = 0

PAUSE 5000


'WRITE DATA TO DDRAM
MAIN:

PORTC.4 = 1
PAUSEUS 1
PORTC.5 = 1
PAUSEUS 1
PORTC = %110011 'SEND UPPER NIBBLE
PAUSEUS 1
PORTC.5 = 0
PAUSEUS 1
PORTC.5 = 1
PAUSEUS 1
PORTC = %110011 'SEND LOWER NIBBLE
PAUSEUS 1
PORTC.5 = 0

PAUSE 5000

GOTO MAIN
Looking for additional LCD resources? Check out our LCD blog for the latest developments in LCD technology.
 
Yes, it seems that any HD44780 compatible display should behave the same. Your code looks correct, and I don't know why its not working. My only suggestion is to put the enable strobe after the data is output. I know the data sheet shows that this is not necessary, but I have always done it this way, and I've never had problems with character displays. Like this:
Code:
PORTC.4 = 0
PAUSEUS 1
PORTC = %000011 'FIRST TIME
PORTC.5 = 1
PAUSEUS 1
PORTC.5 = 0
Do you have a scope, such that you could look at the data vs. control signal timing, and verify what is happening?

Afterthought: try tying the display inputs D0~D3 low. Again, it shouldn't matter, but I've heard of it curing problems. Also, I think you don't need to do CLEAR DISPLAY twice, but no big deal.
 

CF Tech

Administrator
If you carefully port this:
Code:
/////////////////////////////////////////////////////////////////////////////
void CCFAH_WinTestDlg::Write_LCD_Control_8(ubyte data,ubyte enable)
  {
  //Make register select 0, Make R/W 0=write
  OnRsL();
  OnRwL();
  //Write the data to the port.
  data_register=data;	
  Update_Buttons_From_Data_Register();
  //Strobe enable
  Sleep(1);
  if(enable)
    {
    OnE1H();
    Sleep(1);
    OnE1L();
    }
  else
    {
    OnE0H();
    Sleep(1);
    OnE0L();
    }
  }
/////////////////////////////////////////////////////////////////////////////
void CCFAH_WinTestDlg::Write_LCD_Data_8(ubyte data,ubyte enable)
  {
  //Make register select 1, Make R/W 0=write
  OnRsH();
  OnRwL();
  //Write the data to the port.
  data_register=data;	
  Update_Buttons_From_Data_Register();
  //Strobe enable
  Sleep(1);
  if(enable)
    {
    OnE1H();
    Sleep(1);
    OnE1L();
    }
  else
    {
    OnE0H();
    Sleep(1);
    OnE0L();
    }
  }
/////////////////////////////////////////////////////////////////////////////
void CCFAH_WinTestDlg::Write_LCD_Control_4(ubyte data,ubyte enable)
  {
  //Make register select 0, Make R/W 0=write
  OnRsL();
  OnRwL();
  //Apply the high 4 bits of data to the high four bits of the port.
  data_register=data&0xF0;
  Update_Buttons_From_Data_Register();
  //Strobe enable to clock in the high nibble.
  Sleep(1);
  if(enable)
    {
    OnE1H();
    Sleep(1);
    OnE1L();
    }
  else
    {
    OnE0H();
    Sleep(1);
    OnE0L();
    }
  //Apply the low 4 bits of data to the high four bits of the port.
  data_register=(data<<4)&0xF0;
  Update_Buttons_From_Data_Register();
  //Strobe enable to clock in the low nibble.
  Sleep(1);
  if(enable)
    {
    OnE1H();
    Sleep(1);
    OnE1L();
    }
  else
    {
    OnE0H();
    Sleep(1);
    OnE0L();
    }
  }
/////////////////////////////////////////////////////////////////////////////
void CCFAH_WinTestDlg::Write_LCD_Data_4(ubyte data,ubyte enable)
  {
  //Make register select 1, Make R/W 0=write
  OnRsH();
  OnRwL();
  //Apply the high 4 bits of data to the high four bits of the port.
  data_register=data&0xF0;
  Update_Buttons_From_Data_Register();
  //Strobe enable to clock in the high nibble.
  Sleep(1);
  if(enable)
    {
    OnE1H();
    Sleep(1);
    OnE1L();
    }
  else
    {
    OnE0H();
    Sleep(1);
    OnE0L();
    }
  //Apply the low 4 bits of data to the high four bits of the port.
  data_register=(data<<4)&0xF0;
  Update_Buttons_From_Data_Register();
  //Strobe enable to clock in the low nibble.
  Sleep(1);
  if(enable)
    {
    OnE1H();
    Sleep(1);
    OnE1L();
    }
  else
    {
    OnE0H();
    Sleep(1);
    OnE0L();
    }
  }
/////////////////////////////////////////////////////////////////////////////
void CCFAH_WinTestDlg::Init_LCD_4(ubyte enable)
  {
  //It is not an error that the first writes are "8-bit", see the HD44780
  //data sheet.
  //This sequence is from the initialization on page 46 of the HD44780U
  //data sheet.
  Sleep(40);
  Write_LCD_Control_8(0x30,enable);
  //Yes, the data sheet says write it twice.
  Sleep(5);
  Write_LCD_Control_8(0x30,enable);
  //Yes, the data sheet says write it three times.
  Sleep(125);
  Write_LCD_Control_8(0x30,enable);
  //Yes, the data sheet says write it four times, but at least this one counts.
  //020h is Function set:
  //4 bit,
  //2 line
  //F = (5x8)
  Sleep(1);
  //This is last 8-bit write, which is an instruction to put the LCD into 4-bit mode.
  Write_LCD_Control_8(0x20,enable);
  //Here is the 4-bit instruction to set the font and number of lines.
  Write_LCD_Control_4(0x28,enable);
  //"Display off"
  Sleep(2);
  Write_LCD_Control_4(0x08,enable);
  //"Display clear"
  Sleep(2);
  Write_LCD_Control_4(0x01,enable);
  //006h is Entry mode set, increment, no shift
	Sleep(2);
  Write_LCD_Control_4(0x06,enable);
  //Display on, cursor on, blinking
	Sleep(2);
  Write_LCD_Control_4(0x0F,enable);
  //Clear the display again. This seems to fix a power-up problem
  //where the display shows "{{{{{" in a couple of places.
	Sleep(2);
  Write_LCD_Control_4(0x01,enable);
  }
/////////////////////////////////////////////////////////////////////////////
From "CFAH_WinTestDlg.cpp" in CFAH_WinTest, it should work for pretty much any display.
 
Top