Cant get my CFAH1602B to work

angus1357

New member
I hooked everything up according to spec. When the VDO isnt plugged into the circuit its 1V but at the same point when I plug in the VDO its 2.5V, no idea why this is happening so thats first on the list. Secondly I followed the flow chart at the end of the data sheet to initialize the LCD and im running in on a MEGA16 and the code is below...I'll take any help here I can get!

//enable?
PORTC.2=1;
delay_us(5);
PORTC.2=1;
delay_us(5);
PORTC.2=0;
delay_us(5);

while (1)
{
//initialize?
if (initial==0)
{
delay_ms(15);
PORTB=0x30;
delay_ms(4);
PORTB=0x30;
delay_us(100);
PORTB=0x30;
PORTB=0x3C;
PORTB=0x08;
PORTB=0x01;
PORTB=0x06;
initial=1;
};


//place characters
PORTC.0=1;
PORTB=0x13;
PORTB=0x23;
PORTB=0xA3;
PORTB=0x53;
PORTB=0x93;
PORTB=0x08;
PORTB=0x05;
PORTB=0xD4;

PORTC.0=0;
PORTB=0xC0;
PORTC.0=1;
PORTB=0x35;
PORTB=0x56;
PORTB=0x47;
PORTB=0xF3;
PORTB=0x02;
PORTB=0x02;

};
Looking for additional LCD resources? Check out our LCD blog for the latest developments in LCD technology.
 

CF Tech

Administrator
One immediate thing I see is that you do not toggle the "E" line after writing the data. Did you look at the code in CFAH_WinTest for a known-good initialization sequence?
 

angus1357

New member
no idea

I didnt see anywhere that I had to toggle the "E" bit after each letter. as for the initialization from the wintest...I put it in exactly the same and still all I have is 2 rows of squares. so in the initialization where it says, for example, "Write_LCD_Control_8(0x01,enable);" that means its sending the data bits a 1 and the enable high?
 

angus1357

New member
no idea

I didnt see anywhere that I had to toggle the "E" bit after each letter. as for the initialization from the wintest...I put it in exactly the same and still all I have is 2 rows of squares. so in the initialization where it says, for example, "Write_LCD_Control_8(0x01,enable);" that means its sending the data bits a 1 and the enable high?

This is what i've changed my code to:
if (initial==0)
{
delay_ms(20);
PORTB=0x38;
PORTC.2=1;
delay_ms(5);
PORTB= 0x38;
delay_ms(125);
PORTB=0x38;
delay_ms(1);
PORTB=0x38;
delay_ms(2);
PORTB=0x08;
delay_ms(2);
PORTB= 0x01;
delay_ms(2);
PORTB= 0x06;
delay_ms(2);
PORTB=0x0F;
delay_ms(2);
PORTB=0x01;
};

//place characters
PORTC.0=1;
PORTC.2=1;
delay_ms(1);
PORTB=0x01;
PORTC.2=0;
delay_ms(1);
 

CF Tech

Administrator
Here is the code from CFAH_WinTest:

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();
    }
  }
/////////////////////////////////////////////////////////////////////////////
Your code needs to look something like this:

Code:
/////////////////////////////////////////////////////////////////////////////
void Write_LCD_Control_8(ubyte data)
  {
  //Make register select 0, Make R/W 0=write
  OnRsL();        <<<< change this to the appropriate "port&=~mask" 
  OnRwL();        <<<< change this to the appropriate "port&=~mask" 
  //Write the data to the port.
  data_register=data; <<<< change this to the appropriate "port=data" 
  //Strobe enable
  Sleep(1);       <<<< change this to the your "delay" 
  OnE1H();        <<<< change this to the appropriate "port|=mask" 
  Sleep(1);       <<<< change this to the your "delay" 
  OnE1L();        <<<< change this to the appropriate "port&=~mask" 
  }
/////////////////////////////////////////////////////////////////////////////
void Write_LCD_Data_8(ubyte data)
  {
  //Make register select 1, Make R/W 0=write
  OnRsH();        <<<< change this to the appropriate "port|=mask" 
  OnRwL();        <<<< change this to the appropriate "port&=~mask" 
  //Write the data to the port.
  data_register=data; <<<< change this to the appropriate "port=data" 
  //Strobe enable
  Sleep(1);       <<<< change this to the your "delay" 
  OnE1H();        <<<< change this to the appropriate "port|=mask" 
  Sleep(1);       <<<< change this to the your "delay" 
  OnE1L();        <<<< change this to the appropriate "port&=~mask" 
  }
/////////////////////////////////////////////////////////////////////////////
The "enable" parameter is used because CFAH_WinTest supports 40x4 displays, which have two enable lines.

Once you have those coded, your init should look something like this:
Code:
/////////////////////////////////////////////////////////////////////////////
void Init_LCD_8(void)
  {
  //This sequence is from the initialization on page 45 of the HD44780U
  //data sheet.
  Sleep(40);
  Write_LCD_Control_8(0x38);
  //Yes, the data sheet says write it twice.
  Sleep(5);
  Write_LCD_Control_8(0x38);
  //Yes, the data sheet says write it three times.
  Sleep(125);
  Write_LCD_Control_8(0x38);
  //Yes, the data sheet says write it four times, but at least this one counts.
  //038h is Function set:
  //8 bit,
  //2 line
  //F = (5x8)
  Sleep(1);
  Write_LCD_Control_8(0x38);
  //"Display off"
  Sleep(2);
  Write_LCD_Control_8(0x08);
  //"Display clear"
  Sleep(2);
  Write_LCD_Control_8(0x01);
  //006h is Entry mode set, increment, no shift
  Sleep(2);
  Write_LCD_Control_8(0x06);
  //Display on, cursor on, blinking
  Sleep(2);
  Write_LCD_Control_8(0x0F);
  //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_8(0x01);
  //End of initialzation put something on the display
  Write_LCD_Data_8('A');
  Write_LCD_Data_8('V');
  Write_LCD_Data_8('R');
  Write_LCD_Data_8(' ');
  Write_LCD_Data_8('R');
  Write_LCD_Data_8('A');
  Write_LCD_Data_8('W');
  Write_LCD_Data_8('K');
  Write_LCD_Data_8('S');
  Write_LCD_Data_8('!');
  }
/////////////////////////////////////////////////////////////////////////////
 

angus1357

New member
This is what I have

The code below is what I got out of that code you left earlier. The screen itself is blank on the top row, and squares on the bottom row, but will still not display the number Im uploading, can you tell me what i've done wrong here?

/*********************************************
This program was produced by the
CodeWizardAVR V1.23.8c Standard
Automatic Program Generator
© Copyright 1998-2003 HP InfoTech s.r.l.
http://www.hpinfotech.ro
e-mail:eek:ffice@hpinfotech.ro

Project :
Version :
Date : 6/3/2004
Author : Andrew Henseleit
Company :
Comments:


Chip type : ATmega16L
Program type : Application
Clock frequency : 6.000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 256
*********************************************/

#include <mega16.h>
#include <delay.h>

//PORTC.0 = RS
//PORTC.1 = RW
//PORTC.2 = E
//PORTB = D0 - D7
// Declare your global variables here

void write_lcd_control(int data)
{
PORTC.0=0;
PORTC.1=0;
PORTB=data;
delay_ms(1);
PORTC.2=1;
delay_ms(1);
PORTC.2=0;
}

void init_lcd(void)
{
delay_ms(40);
write_lcd_control(0x38);
delay_ms(5);
write_lcd_control(0x38);
delay_ms(125);
write_lcd_control(0x38);
delay_ms(1);
write_lcd_control(0x38);
delay_ms(2);
write_lcd_control(0x08);
delay_ms(2);
write_lcd_control(0x01);
delay_ms(2);
write_lcd_control(0x06);
delay_ms(2);
write_lcd_control(0x0F);
delay_ms(2);
write_lcd_control(0x01);
}

void tog_enable(void)
{
PORTC.2=1;
delay_ms(1);
PORTC.2=0;
}

void write_lcd(int data)
{
PORTC.0=1;
PORTB=data;
tog_enable();
}

(PORT INITS HERE)

while (1)
{
write_lcd(0x01);

};
 

CF Tech

Administrator
Well, your void tog_enable(void) needs anoher delay:

void tog_enable(void)
{
PORTC.2=1;
delay_ms(1);
PORTC.2=0;
delay_ms(1);
}

Why even have a tog_enable() when it is only called from one place?

And writing a 0x01 is not going to be exciting. Try a 0x41 instead.

Why not just use something like the "LCD library for HD44870 based LCD's" on this page:

http://homepage.sunrise.ch/mysunrise/pfleury/avr-software.html#libs

Google more:
http://www.google.com/search?hl=en&lr=&ie=UTF-8&q=avr+hd44780++library
 

angus1357

New member
Fixed, kind of

Alright, you've gotten me this far!! i can display numbers and the display is functional...the last problem is this... WHen i display letters (only tried capital letters) I get the japanese character set. the value for the letter is correct but why the wrong character set?
 

CF Tech

Administrator
Probably one of your data bits is mixed up. Like PC.5 on the AVR is hooked to D[2] on the LCD.
 
Top