LCD 20x4 HD44780 Controller

Thread Starter

Nektarios

Joined Feb 19, 2015
2
Hello!

I would like to ask your help with my lcd-program!
I have searched enough to find a code from a lcd library for a LCD 20x4, but i couldnt to adjust it to my Project.
I use 4-bit Logic for the lcd-data. I program an atmega32 with avrstudio4.

The functions which i use are:

Code:
/************************************************
 LCD CONNECTIONS
*************************************************/
#define LCD   PORTC   //Port PC0-PC3 are connected to D4-D7
#define RS  PORTC5
#define RW  PORTC6
#define E  PORTC7   //Position of enable
#define SET(x)  (LCD|=(1<<x))
#define RESET(x) (LCD&=(~(1<<x)))

Code:
void LCDByte(uint8_t c,uint8_t isdata)
{
//Sends a byte to the LCD in 4bit mode
//cmd=0 for data
//cmd=1 for command
uint8_t hn,ln;  //Nibbles
uint8_t temp;
hn=c>>4;  //hn had the 4 most significal bits of c
ln=(c & 0x0F);  //hn had the 4 less significal bits of c
if(isdata==0)
  RESET(RS);  //if is comand
else
  SET(RS);  //if is data
_delay_us(0.500);  //tAS
//Send high nibble
SET(E);
temp=(LCD & 0XF0)|(hn);
LCD=temp;
_delay_us(1);  //tEH
//Now data lines are stable pull E low for transmission
RESET(E);
_delay_us(1);
//Send the lower nibble
SET(E);
temp=(LCD & 0XF0)|(ln);
LCD=temp;
_delay_us(1);  //tEH
//SEND
RESET(E);
_delay_ms(2);  //tEL
}
//***************************
void InitLCD()
{
//After power on Wait for LCD to Initialize
_delay_ms(30);
//Set IO Ports
DDRC=0xFF;  //<<<<<<<<<<<<<<<<<!!!!!!!!!!!!!!!!must set the correct port
LCD=0X00;
//Set 4-bit mode
_delay_us(1);  //tAS
SET(E);
LCD|=(0b00000010);  // 4 bits interface data length
_delay_us(1);
RESET(E);
_delay_us(1);
//Wait for LCD to execute the Functionset Command
_delay_ms(10);  //[B] Forgot this delay
//Now the LCD is in 4-bit mode
LCDByte(0b00001111,0); //Display On
LCDByte(0b00101000,0); //function set 4-bit,2 line 5x7 dot format
}
Code:
void LCDGotoXY(uint8_t x,uint8_t y)
{ 
  if(x<40)
  {
  switch(y)
  {
  // Line 1
  case 0: x|=0x80; break;  //1000 0000 
  // Line 2
  case 1: x|=0xC0; break;  //1100 0000 
  // Line 3
  case 2: x|=0x94; break;  //1001 0100
  // Line 4
  case 3: x|=0xD4; break;  //1101 0100
  }
  //LCDCmd(x);
  LCDByte(x,0);
  }
 
}

Code:
void LCDWriteString(const char *msg)
{
 while(*msg!='\0')
 {
 //Custom Char Support
 if(*msg=='%')
 {
 msg++;
 int8_t cc=*msg-'0';
 if(cc>=0 && cc<=7)
 {
 LCDData(cc);
 }
 else
 {
 LCDData('%');
 LCDData(*msg);
 }
 }
 else
 {
 LCDData(*msg);
 }
 msg++;
 }
}

So my problem is, that if i put the values 0x80-0xc0-0x94-0xd4 in the function LCDGotoXY() the Lines 3&4 dont work ok!
After the 4th character (line3 & line4) the display has problem.

I had also used the
0x00
0x40
0x14
0x54
but still not working for my code!


Can someone, who knows how to calculate correct these values (and i can use these functions), help me!!

thanks in advance!



(sorry for my bad english) :) :)
 

MrChips

Joined Oct 2, 2009
30,618
Don't OR your x values. Use ADD.

Code:
void LCDGotoXY(uint8_t x,uint8_t y)
{
if(x<40)
{
switch(y)
{
// Line 1
case 0: x +=0x80; break; //1000 0000
// Line 2
case 1: x +=0xC0; break; //1100 0000
// Line 3
case 2: x +=0x94; break; //1001 0100
// Line 4
case 3: x +=0xD4; break; //1101 0100
}
//LCDCmd(x);
LCDByte(x,0);
}

}
 

Thread Starter

Nektarios

Joined Feb 19, 2015
2
MrChips you are right!
Now it is fine!!
Thank you, thank you very much!!!

I present the full code together in case someone else has the same problem!!


file=lcd.h
Code:
#define F_CPU 16000000L
#include <avr/io.h>
#include <util/delay.h>

#ifndef _LCD_H
 #define _LCD_H
/************************************************
 LCD CONNECTIONS
*************************************************/
#define LCD   PORTC   //Port PC0-PC3 are connected to D4-D7
#define RS  PORTC5
#define RW  PORTC6
#define E  PORTC7   //Position of enable
#define SET(x)  (LCD|=(1<<x))
#define RESET(x) (LCD&=(~(1<<x)))
//The prototyping is necessary for the definiton of LCDWriteStringXY()
void LCDGotoXY(uint8_t x,uint8_t y);
void LCDWriteString(const char *msg);


//**********************LCD*****************************
void LCDByte(uint8_t c,uint8_t isdata)
{
 //Sends a byte to the LCD in 4bit mode
 //cmd=0 for data
 //cmd=1 for command
 uint8_t hn,ln; //Nibbles
 uint8_t temp;
 hn=c>>4; //hn had the 4 most significal bits of c
 ln=(c & 0x0F); //hn had the 4 less significal bits of c
 if(isdata==0)
 RESET(RS); //if is comand
 else
 SET(RS);  //if is data
 _delay_us(0.500); //tAS
 //Send high nibble
 SET(E);
 temp=(LCD & 0XF0)|(hn);
 LCD=temp;
 _delay_us(1); //tEH
 //Now data lines are stable pull E low for transmission
 RESET(E);
 _delay_us(1);
 //Send the lower nibble
 SET(E);
 temp=(LCD & 0XF0)|(ln);
 LCD=temp;
 _delay_us(1); //tEH
 //SEND
 RESET(E);
 _delay_ms(2); //tEL
}
//***************************
void InitLCD()
{
 //After power on Wait for LCD to Initialize
 _delay_ms(30);
 //Set IO Ports
 DDRC=0xFF;  //<<<<<<<<<<<<<<<<<!!!!!!!!!!!!!!!!must set the correct port
 LCD=0X00;
 //Set 4-bit mode
 _delay_us(1); //tAS
 SET(E);
 LCD|=(0b00000010);  // 4 bits interface data length
 _delay_us(1);
 RESET(E);
 _delay_us(1);
 
 //Wait for LCD to execute the Functionset Command
 _delay_ms(10);  //[B] Forgot this delay
 //Now the LCD is in 4-bit mode
 LCDByte(0b00001111,0); //Display On
 LCDByte(0b00101000,0); //function set 4-bit,2 line 5x7 dot format
}

//***************************
void LCDGotoXY(uint8_t x,uint8_t y)
{  
  if(x<40)
  {
  switch(y)
  {
 // Line 1
 case 0: x +=0x80; break; //1000 0000
 // Line 2
 case 1: x +=0xC0; break; //1100 0000
 // Line 3
 case 2: x +=0x94; break; //1001 0100
 // Line 4
 case 3: x +=0xD4; break; //1101 0100
  }
  //LCDCmd(0x80|x); //(x);
  LCDByte(x,0);
  }
  
}
//***************************
void LCDWriteString(const char *msg)
{
 while(*msg!='\0')
 {
 //Custom Char Support
 if(*msg=='%')
 {
 msg++;
 int8_t cc=*msg-'0';
 if(cc>=0 && cc<=7)
 {
 LCDData(cc);
 }
 else
 {
 LCDData('%');
 LCDData(*msg);
 }
 }
 else
 {
 LCDData(*msg);
 }
 msg++;
 }
}
//***************************
void LCDWriteStringXY(const char *msg, uint8_t x, uint8_t y)
{ 
 //Call the function for the cursor movement
 LCDGotoXY(x,y);
 //Call the function for write the message
 LCDWriteString(msg);
}
//***************************
void LCDWriteInt(int val)
{
  if(val<0)
  {
   LCDByte('-',1);
   val=(-val);
  }
  char str[5]={0,0,0,0,0};
  int i=4,j=0;
  while(val)
  {
   str[i]=val%10;
   val=val/10;
   i--;
  }
  
  while(str[j]==0) j++;
  
  for(i=j;i<5;i++)
  {
   LCDByte(48+str[i],1);
  }
}
//***************************
void LCDWriteIntXY(int val, uint8_t x, uint8_t y)
{
 //Call the function for the cursor movement
 LCDGotoXY(x,y);
 //Call the function for write the integer
 LCDWriteInt(val);
}

//**********************LCD_end*******************************

#endif

file=main.c
Code:
#define F_CPU 16000000L
#include <avr/io.h> 
#include <util/delay.h>
#include "lcd.h" 

int main()
{
int c=0;
while(1)
{ 

 LCDWriteIntXY(1,c,0);
 LCDWriteIntXY(2,c,1);
 LCDWriteIntXY(3,c,2);
 LCDWriteIntXY(4,c,3);
 _delay_ms(1000);
 LCDByte(0b00000001,0);
 if(c>=19){ c=0; }
 else {c++; }
}

}
 
Top