Help initializing CFAG160160B.

NRW898

New member
I purchased the CFAG160160B and I'm trying to initialize the LCD. I've seen the various example code and have read the different posts, but none of it is in my programming language (PICBasic Pro for Microship PICs). I would like to know what the proper sequence is for the control lines. For example, when to make CS active and does enable need to be pulsed or just made high while writing to the controller. The datasheet explains how to setup the display control instructions, but it is seriously lacking in information on when and how to use the control lines. I've been fighting this thing for a couple days now. Any help would be greatly appreciated.
Looking for additional LCD resources? Check out our LCD blog for the latest developments in LCD technology.
 
CS can be tied active permanently, unless you have more than one device on the data bus. The E(nable) signal is a pulse, which is taken high, then low. The transition from high to low is what clocks the data into the display controller.
The datasheet ... is seriously lacking in information on when and how to use the control lines.
There is a timing diagram in section 10 of the data sheet ( for the YYH, I don't know what model you have).

It would be useful for you to learn a little bit of C language to help you use the sample code. It is pretty easy to see the general flow of the code, especially if the code is commented. I presume you found some of my posts regarding the 160B, like this one https://forum.crystalfontz.com/showthread.php?t=4465.
 

CF Tech

Administrator
Things to check:

1: Make sure Vo (Pin 4) is at the correct voltage. It should be at about -12.4 volts (negative) for this display. There is a negative voltage output on pin 20 to help with this. Connect one end of a 10K pot to Vcc (+5v) connect the other end to Vee (pin 20) and connect the wiper to Vo (pin 4)

2: You can follow the initialization code from this thread:

https://forum.crystalfontz.com/showthread.php?t=3257

We do not have any BASIC code to follow, you might need to get someone to give you a hand interpreting the C example.

Here are the bits you need (from CFAG_WinTestDlg.cpp). First the port control macros:
Code:
#define DATA_ADDR (port_data_address)
#define CONT_ADDR (port_control_address)
  
//inverted at the port
#define SCLR_CS (DlPortWritePortUchar(CONT_ADDR,(control|=0x02)));(Sleep(20))
#define CLR_CS (DlPortWritePortUchar(CONT_ADDR,(control|=0x02)))
#define SET_CS (DlPortWritePortUchar(CONT_ADDR,(control&=~0x02)))
  
//straight at the port
#define SET_RS (DlPortWritePortUchar(CONT_ADDR,(control|=0x04)))
#define CLR_RS (DlPortWritePortUchar(CONT_ADDR,(control&=~0x04)))

//inverted at the port
#define CLR_RES  (DlPortWritePortUchar(CONT_ADDR,(control|=0x08)))
#define SET_RES  (DlPortWritePortUchar(CONT_ADDR,(control&=~0x08)))

//inverted at the port
#define CLR_E (DlPortWritePortUchar(CONT_ADDR,(control|=0x01)))
#define SET_E (DlPortWritePortUchar(CONT_ADDR,(control&=~0x01)));(Delay())


#define SDATA(x) (DlPortWritePortUchar(DATA_ADDR,(x)));(Sleep(20))
#define DATA(x) (DlPortWritePortUchar(DATA_ADDR,(x)));(Delay())

void COM_W(ubyte data)
  {
  DATA(data);
  SET_RS;
  CLR_CS;
  //R/W is hardwired low
  Sleep(10);
  SET_E;
  Sleep(10);
  CLR_E;
  Sleep(10);
  SET_CS;
  }
void DATA_W(ubyte data)
  {
  DATA(data);
  CLR_RS;
  CLR_CS;
  //R/W is hardwired low
  Sleep(10);
  SET_E;
  Sleep(10);
  CLR_E;
  Sleep(10);
  SET_CS;
  }

void CP_COMMAND(ubyte comm_reg, ubyte data_reg)
  {
  COM_W(comm_reg);
  DATA_W(data_reg);
  }
Sleep() is a mS delay routine.

You will also need the initialization sequence:
Code:
void CCFAG_WinTestDlg::OnInitialize() 
  {
  /* deleted win specific stuff */

  ubyte
    i;
  i=0;

  //Idle the control lines & reset the display
  CLR_RES;
  CLR_E;
  CLR_RS;
  SET_CS;
  DATA(0);
  Sleep(10);
  SET_RES;
  Sleep(10);

  //MOV     COMM_REG,#00H           ;Command code--Mode control
  //MOV     DATA_REG,#32H           ;Set 00110010
  //LCALL   CP_COMMAND              ;Command complete
  CP_COMMAND(0x00,0x32);

  //MOV     COMM_REG,#01H           ;Character pitch setting
  //MOV     DATA_REG,#77H           ;Set 10010111
  //LCALL   CP_COMMAND              ;Command complete
  CP_COMMAND(0x01,0x77);

  //MOV     COMM_REG,#02H           ;Character number setting
  //MOV     DATA_REG,#19            ;160/8=20 Char in one line
  //LCALL   CP_COMMAND              ;Command complete
  CP_COMMAND(0x02,19);

  //MOV     COMM_REG,#03H           ;Display duty setting
  //MOV     DATA_REG,#MaxRow_1      ;Set 1/160 duty
  //LCALL   CP_COMMAND              ;Command complete
  CP_COMMAND(0x03,159);

  //MOV     COMM_REG,#08H           ;Display low address setting
  //MOV     DATA_REG,#00H           ;Low address start from 00H
  //LCALL   CP_COMMAND              ;Command complete
  CP_COMMAND(0x08,0x00);

  //MOV     COMM_REG,#09H           ;Display high address setting
  //MOV     DATA_REG,#00H           ;High address start from 00
  //LCALL   CP_COMMAND              ;Command complete
  CP_COMMAND(0x09,0x00);

  //FULLON:
  //MOV     COMM_REG,#0AH           ;Cursor low address setting
  //MOV     DATA_REG,#00H           ;Low address start from 00H
  //LCALL   CP_COMMAND              ;Command complete
  CP_COMMAND(0x0A,0x00);

  //MOV     COMM_REG,#0BH           ;Cursor high address setting
  //MOV     DATA_REG,#00H           ;High address start from 00
  //LCALL   CP_COMMAND              ;Command complete
  CP_COMMAND(0x0B,0x00);

  int
    row,col;
  CLR_CS;
  //Send data command
  DATA(0x0C);
  SET_RS;
  //R/W is hardwired low
  SET_E;
  CLR_E;
  CLR_RS;
  for(row=0;row<=159;row++)
    for(col=0;col<=19;col++)
      {
      DATA(cfag240128[row][col]);
      //R/W is hardwired low
      SET_E;
      CLR_E;
      }
  SET_CS;
  }
Hopefully that will give you a start. Please post back with status :)
 

NRW898

New member
Thank you cosmicvoid for the input. CF Tech, I see the flow in the initialization code. The port control macros are basically subroutines being called to execute the instruction right?
 

CF Tech

Administrator
CLR_E just moves the "E" pin low. SET_E moves it high. Other pins have similar macros.

"DATA" puts a byte of data on the LCD's D0-D7 pins.

I think everything else is built up from there.
 

NRW898

New member
Yes, thank you. I think I'm getting close now. My next question is how to write character data to the LCD. Is it just like the initialization steps?

Is this the proper sequence:
Code:
PORTB = %00001100   ' Write instruction out on data lines
high PORTC.3             ' RS = instruction
low PORTC.2              ' CS active
pause 1                     ' 1ms wait
high PORTC.1             ' Enable on
PAUSE 1                   ' 1ms wait
LOW PORTC.1            ' Enable off 
pause 1                    ' 1ms wait   
high PORTC.2            ' CS not active

PORTB = %00110000  ' Data to send "0" to display
low PORTC.3             ' RS = data
low PORTC.2             ' CS active
PAUSE 1                  ' 1ms wait 
high PORTC.1           ' Enable on
PAUSE 1                  ' 1ms wait
LOW PORTC.1          ' Enable off 
pause 1                  ' 1ms wait
high PORTC.2           ' CS not active
 

NRW898

New member
Now the -12.4V required on Vo is referenced to what? Vdd and my 20k pot are connected to +5V. Vee is connected to the other end of the pot. Vo is connected to the wiper. I read about +2V from Vo to ground. When adjusting the pot I can get half the LCD to display the pixels in a smeary looking pattern.
 

CF Tech

Administrator
The -12.4 should be what Vo reads, compared to Ground (Vss). That will give a Vlcd of 17.4 volts, assuming a Vdd of 5v.
 

CF Support

Administrator
I think there might be an issue with the LCD itself -- can you send an email to support (at) crystalfontz (dot) com so we can get a support ticket started?
 
Top