Discussion in "AVR Discussion Forum" started by    prajwalsnh    Feb 28, 2013.
Thu Feb 28 2013, 09:38 pm
#1
Hi freinds,

I have written a code for interfacing 16x2 LCD with ATMEGA 8.. I have not tested it yet.. need to know whether i can program in 8bit mode or not. the code is like this

//Program to Display string on LCD using AVR Microcontroller (ATmega16)
/*
LCD DATA port----PORT D
signal port------PORT B
rs-------PB0
rw-------PB1
en-------PB2
*/

#include<avr/io.h>
#include<util/delay.h>

#define LCD_DATA PORTD //LCD data port

#define ctrl PORTB
#define en PB2 // enable signal
#define rw PB1 // read/write signal
#define rs PB0 // register select signal

void LCD_cmd(unsigned char cmd);
void init_LCD(void);
void LCD_write(unsigned char data);

int main()
{
DDRD=0xff;
DDRB=0x07;
init_LCD(); // initialization of LCD
_delay_ms(50); // delay of 50 mili seconds
LCD_write_string("EngineersGarage"); // function to print string on LCD
return 0;
}

void init_LCD(void)
{
LCD_cmd(0x38); // initialization of 16X2 LCD in 8bit mode
_delay_ms(1);

LCD_cmd(0x01); // clear LCD
_delay_ms(1);

LCD_cmd(0x0E); // cursor ON
_delay_ms(1);

LCD_cmd(0x80); // ---8 go to first line and --0 is for 0th position
_delay_ms(1);
return;
}

void LCD_cmd(unsigned char cmd)
{
LCD_DATA=cmd;
ctrl =(0<<rs)|(0<<rw)|(1<<en);
_delay_ms(1);
ctrl =(0<<rs)|(0<<rw)|(0<<en);
_delay_ms(50);
return;
}

void LCD_write(unsigned char data)
{
LCD_DATA= data;
ctrl = (1<<rs)|(0<<rw)|(1<<en);
_delay_ms(1);
ctrl = (1<<rs)|(0<<rw)|(0<<en);
_delay_ms(50);
return ;
}

void LCD_write_string(unsigned char *str) //store address value of the string in pointer *str
{
int i=0;
while(str[i]!='\0') // loop will go on till the NULL character in the string
{
LCD_write(str[i]); // sending data on LCD byte by byte
i++;
}
return;
}

Please help.. i dont have proteus to verify.. im using 16Mhz crystal
Thu Feb 28 2013, 11:44 pm
#2
see the LCD library instead, in the tutorials section, or if you're new to AVR programming, rather than going into confusion of setting/resetting bits using the way you did, simply use the cbi and sbi
include this first <avr/deprecated.h>, then in your code cbi to reset a bit and sbit to set a bit
so making your code for lcd_cmd becomes
lcd_data = data;
sbi(PORTB,rs);
cbi(PORTB,rw);
sbi(PORTB,en);
_delay_ms(10);
cbi(PORTB,en);
Fri Mar 01 2013, 12:02 am
#3
@amitrana3348

Thanks for the reply... i tried to interface the same way what i have written in code. boxes are appearing on LCD.. what may be the problem???

Is delay a problem for display? I'm using 16Mhz external crystal. i dont know to write the delay function for 16Mhz.. pls help
Fri Mar 01 2013, 10:23 am
#4
You can define oscillator frequency in your C code as shown so that delay_ms can generate correct delay accordingly.
#define F_CPU 16000000UL


try it and let me know.
Fri Mar 01 2013, 04:58 pm
#5
@Ajay Bhargav

Thanks for your kind support sir.

I modified the code and wrote it for 4-bit mode. its as below.. I also added your suggestion in my code.. but its of no use.. black boxes are being displayed on first row... no data is being displayed.. Its my final year project need your help sir..


#define F_CPU 16000000UL

#include<avr/io.h>
#include<util/delay.h>
#include<inttypes.h>

#define rs PB0
#define rw PB1
#define en PB2

void lcd_init();
void dis_cmd(char);
void dis_data(char);
void lcdcmd(char);
void lcddata(char);

int main(void)
{
unsigned char data0[11]="HELLO";
unsigned char data1[10]="WORLD";

int i=0;
DDRD=0xFF;
lcd_init();
while(data0[i]!='\0')
{
dis_data(data0[i]);
_delay_ms(200);
i++;
}

dis_cmd(0xC5);

i=0;
while(data1[i]!='\0')
{
dis_data(data1[i]);
_delay_ms(200);
i++;
}

while(1);
}



void lcd_init() // fuction for intialize
{
dis_cmd(0x02); // to initialize LCD in 4-bit mode.
dis_cmd(0x28); //to initialize LCD in 2 lines, 5X7 dots and 4bit mode.
dis_cmd(0x0C);
dis_cmd(0x06);
dis_cmd(0x83);
}

void dis_cmd(char cmd_value)
{
char cmd_value1;
cmd_value1 = cmd_value & 0xF0; //mask lower nibble because PD4-PD7 pins are used.
lcdcmd(cmd_value1); // send to LCD

cmd_value1 = ((cmd_value<<4) & 0xF0); //shift 4-bit and mask
lcdcmd(cmd_value1); // send to LCD
}


void dis_data(char data_value)
{
char data_value1;
data_value1=data_value&0xF0;
lcddata(data_value1);

data_value1=((data_value<<4)&0xF0);
lcddata(data_value1);
}

void lcdcmd(char cmdout)
{
PORTD=cmdout;
PORTD&=~(1<<rs);
PORTD&=~(1<<rw);
PORTD|=(1<<en);
_delay_ms(1);
PORTD&=~(1<<en);
}

void lcddata(char dataout)
{
PORTD=dataout;
PORTD|=(1<<rs);
PORTD&=~(1<<rw);
PORTD|=(1<<en);
_delay_ms(1);
PORTD&=~(1<<en);
}


[ Edited Fri Mar 01 2013, 05:00 pm ]
Fri Mar 01 2013, 11:47 pm
#6
Have you tried adjusting the LCD contrast ?

Have you set the data direction register for port B ?

It would be safer to use simple instructions to control the signal bits.
For example..
PORTD|=(1<<rs  ) ;
//becomes 
 rs=1; 


[ Edited Sat Mar 02 2013, 12:00 am ]
Sat Mar 02 2013, 10:36 pm
#7
@ExperimenterUK

Yes after adjusting the contrast only im able to see boxes in first row...

Yes i have set the data direction register.. you can see it the program that i have posted
Mon Mar 04 2013, 11:04 am
#8
for LCD in 4-bit mode, your init function needs to be changed. Read about how to init LCD in 4-bit mode:

http://www.8051projects.net/lcd-interfacing/lcd-4-bit.php

You need to send init command 3 times and then set bus width to 4-bit. after that your LCD will start accepting 4-bit data.

Get Social

Information

Powered by e107 Forum System

Downloads

Comments

KevinTab
Sun Apr 28 2024, 05:35 am
Tumergix
Sun Apr 28 2024, 12:59 am
StevenDrulk
Sat Apr 27 2024, 08:47 pm
StephenHauct
Sat Apr 27 2024, 09:38 am
Adamsaf
Sat Apr 27 2024, 07:12 am
Robertphype
Sat Apr 27 2024, 12:23 am
ktaletrryp
Fri Apr 26 2024, 10:55 pm
Robertrip
Fri Apr 26 2024, 11:20 am