Cursor problem with CFAG12864J-TMI-T

godoyedson

New member
I have some Crystalfontz display model CFAG12864J-TMI-T and I have some problems to put the cursor in right position. When I write sequencial characters they´re write in right position but when I send the command 0x80, 0xA0 or increments of this the characters are write in wrong position or they´re not showed in display.
I´m using ARM processor (LCP2368) and I don´t know how to resolve the problem. All technical manual have the same not clear information.

Thanks for any help

Eng. Edson Godoy
Looking for additional LCD resources? Check out our LCD blog for the latest developments in LCD technology.
 

godoyedson

New member
Code with problem

The code with problem is the following

Code:
#include <LPC23xx.H>            

#define EN_LCD    0x00000100			
#define RW_LCD    0x04000000			 
#define RS_LCD    0x02000000			 
#define PINS_CTRL 0x06000100			 
#define PINS_DATA 0x000000FF			 
#define RESET_LCD 0x10000000

#define LCD_E(x)              ((x) ? (FIO2SET = EN_LCD)  : (FIO2CLR = EN_LCD) )

#define LCD_RW(x)             ((x) ? (FIO3SET = RW_LCD) : (FIO3CLR = RW_LCD))

#define LCD_RS(x)             ((x) ? (FIO3SET = RS_LCD) : (FIO3CLR = RS_LCD))

#define LCD_RESET(x)          ((x) ? (FIO4SET = RESET_LCD) : (FIO4CLR = RESET_LCD))

#define LCD_DATA_IN           (FIO2PIN & 0xFF)

#define LCD_DATA_OUT(x)       FIO2CLR = PINS_DATA; FIO2SET = (x & 0xFF)	

#define LCD_ALL_DIR_OUT       FIO2DIR  =  (PINS_CTRL | PINS_DATA)

#define LCD_DATA_DIR_IN       FIO2DIR &= ~PINS_DATA

#define LCD_DATA_DIR_OUT      FIO2DIR |=  PINS_DATA

void delay (long cnt)
{
  cnt <<= DELAY_2N;

  while (cnt--);
}


void lcd_write(unsigned char c)
{
     LCD_DATA_OUT(c);
	 delay(1000);
	 LCD_RW(0);
	 delay(1000);
	 LCD_E(1);
	 delay(1000);
	 LCD_E(0);
	 delay(1000);
} 

void lcd_write_cmd (unsigned char c)
{
  delay(1000);
  LCD_RS(0);
  lcd_write(c);
} 

void lcd_write_data (unsigned char c)
{
  delay(1000);
  LCD_RS(1);
  delay(1000);
  lcd_write(c);
} 

void lcd_putchar (char c)
{ 
  lcd_write_data (c);
} 

void lcd_init (void)
{ 
  LCD_ALL_DIR_OUT;
  LCD_RESET(0);       
  delay(400000);
  LCD_RESET(1);
  delay(15000);
  LCD_RS(0);	
  delay(5000);
  LCD_RW(1);
  delay(5000);
  lcd_write(0x30);
  delay(5000);
  lcd_write(0x30);
  delay(5000);
  lcd_write(0x0C);
  delay(5000);
  lcd_write(0x01);
  delay(5000);
  lcd_write(0x03);
  delay(5000);
  lcd_write(0x30);
  delay(5000);
}


void set_cursor (unsigned char column, unsigned char line)
{
unsigned char address;
  switch(line){
     case 0:
	    address = 0x80 + column;
	 break;
	 case 1:
	    address = 0xA0 + column;
	 break;
	 case 2:
	    address = 0x90 + column;
	 break;
	 case 3:
	    address = 0xB0 + column;
	 break;
  }
  lcd_write_cmd(address);             
}


void lcd_clear (void)
{
  lcd_write_cmd(0x01);                 
}


void lcd_print (unsigned char const *string)
{
  while (*string)  {
    lcd_putchar (*string++);
  }
}
Thanks

Edson Godoy
 
I do not have this display, so my ability to help is limited since I cannot test any code. You are right, the data sheet is not easy to understand, I and am not sure if I understand it myself. This looks like a difficult instruction set.
... when I send the command 0x80, 0xA0 or increments of this the characters are write in wrong position or they´re not showed in display...
The display can only show 2 lines of text at once, so I assume that if your cursor address is in the range 0x80 to 0x9F (the first two lines), then the text should show. I think if you set the cursor to 0xA0 to 0xBF, then the data will enter into memory, but those line will not display. I am guessing that it is necessary to change to extended mode (function set, RE=1) and use the scroll commands (scroll select, SR=1 and set scroll address) to show the other two lines, but I am not sure. You should try to experiment and see what the effect is.

What is the unit of time in your "delay()" function? Your delays in the init section are all the same between lcd writes, but the data sheet calls for different times (see comments).
Otherwise, your code seems to be OK, except a couple of things that should not cause a problem.
Code:
void lcd_init (void)
{ 
  LCD_ALL_DIR_OUT;
  LCD_RESET(0);       
  delay(400000);  [B]// more than 40 mS[/B]
  LCD_RESET(1);
  delay(15000);
  LCD_RS(0);	
  delay(5000);  [B]// not necessary[/B]
[B]  LCD_RW(1);[/B]  // why is this here?
  delay(5000);  [B]// not necessary[/B]
  lcd_write(0x30);
  delay(5000);  [B]// more than 100 uS[/B]
  lcd_write(0x30);
  delay(5000);  [B]// more than 37 uS[/B]
  lcd_write(0x0C);
  delay(5000);  [B]// more than 100 uS[/B]
  lcd_write(0x01);
  delay(5000);  [B]// more than 10 mS[/B]
  lcd_write(0x03);
  delay(5000);
[B]  lcd_write(0x30);[/B]  // why is this here?
  delay(5000);
}
Sorry I can't be more helpful.
 
Top