# Using LCD and ATMega32 problem

Status
Not open for further replies.

#### Cantafford

##### Member
Hello,

I'm trying to interface an 16x2 LCD with an ATMega32 microcontroller. I have watched and understood a simple tutorial and followed the steps to do it. However when I run the code the LCD turns on and displays the cursor but I cannot display any characters on it.

I'm interfacing the LCD in the 8 bit mode and I have connected it like this(it's a simulation I'm not wiring an actual LCD):

Here is the code I wrote:
Code:
/*
* LCD.c
*
* Created: 1/9/2017 4:09:35 PM
*  Author: Paul
*/

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

#define F_CPU 1000000L

#define EIGHTbits            PORTB
#define LCDcontrol            PORTD
#define Enable                5 // enable
#define RegisterSelect        2

void Check_IF_MrLCD_isBusy(void);
void Peek_A_Boo(void); // in prototypes you have to always put something in the paranthesis :D
void Send_A_Command(unsigned char command);
void Send_A_Character(unsigned char character);

int main(void)
{
_delay_ms(15); // wait 15ms after the microcontroller is on so the LCD can turn on

Send_A_Command(0x01); // Clear Screen
_delay_ms(2);
Send_A_Command(0x38); // configure the LCD in the 8bit mote // check the LCD's datasheet for commands
_delay_us(50);
Send_A_Command(0b00001110); // second 1: display on(1) or off(0), third 1:cursor on or off, last one: cursor blinking(1) or not(0)
_delay_us(50);

Send_A_Character(0x4E); // Display character
Send_A_Character(0x65); // Display character
Send_A_Character(0x77); // Display character
Send_A_Character(0x62); // Display character
// Cursor increments automatically

while(1)
{

}
}

void Check_IF_MrLCD_isBusy(void)
{
DataDir_EIGHTbits = 0; // must be in the input mode

LCDcontrol &= ~1<<RegisterSelect; // also make sure it's in the COMMAND mode

while(EIGHTbits >= 0x80) // D7 PortB Pin7 (if it's one means it's busy). If it's 0 means it's not busy. Calling the Peek_A_Boo fills EIGHTbits with values
{
Peek_A_Boo();
}

DataDir_EIGHTbits = 0xFF; // 0xFF means output for each of the pins(bring it back to output when it's done cuz it's the only instance when we read)
}

void Peek_A_Boo()
{
LCDcontrol |= 1<<Enable;
asm volatile  ("nop"); // volatile instruction means the compiler won't optimize it
asm volatile  ("nop"); // used for delay after we "turn the Enable on"(TURN enable to 1)
LCDcontrol &= ~1<<Enable; // then we turn it off
}

void Send_A_Command(unsigned char command)
{
Check_IF_MrLCD_isBusy();
EIGHTbits = command;
LCDcontrol &= ~(1<<ReadWrite | 1<<RegisterSelect); // !!!!!! we make sure it's in the WRITE mode
Peek_A_Boo();
EIGHTbits = 0; // erase the information once it's transmitted
}
void Send_A_Character(unsigned char character)
{
Check_IF_MrLCD_isBusy();
EIGHTbits = character;
LCDcontrol &= ~(1<<ReadWrite); // !!!!!! we make sure it's in the READ mode
LCDcontrol |= 1<<RegisterSelect; // now he's ready to recieve a character
Peek_A_Boo();
EIGHTbits = 0;
}

#### wkrug

##### Active Member
Try it with a real display.
I suspect that the initialisation of the display is not proper.
Look into the datasheet of the used / wished display.
Mustn't there be sent the initialisation 2 or 3 times?

I'll suggest You to use a working library to solve the problem.

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
Agreed...
Code:
     _delay_ms(15); // wait 15ms after the microcontroller is on so the LCD can turn on
Send_A_Command(0x38);
_delay_ms(5);
Send_A_Command(0x38); // configure the LCD in the 8bit mote // check the LCD's datasheet for commands
_delay_ms(2);
Send_A_Command(0b00001110); // second 1: display on(1) or off(0), third 1:cursor on or off, last one: Cursor   Blinking(1) or not(0)
Send_A_Command(0x01); // Clear Screen
_delay_us(50);

#### Cantafford

##### Member
Try it with a real display.
I suspect that the initialisation of the display is not proper.
Look into the datasheet of the used / wished display.
Mustn't there be sent the initialisation 2 or 3 times?

I'll suggest You to use a working library to solve the problem.
I don't have an ATmega microcontroller so I cannot interface it . In hardware I interfaced LCD's only with PIC's using libraries and it worked fine.
Yes, I can do it with a library. I just wanted to understand the function of the LCD better and then maybe create my own library from that code.

#### wkrug

##### Active Member
I just wanted to understand the function of the LCD better and then maybe create my own library from that code.
You can do this, but the initialisation of an LCD is tricky and time critical.
I would suggest You to us a Library and let it run with a simulator.
So You can figure out what that routine does step by step.

Status
Not open for further replies.

Replies
6
Views
3K
Replies
2
Views
1K
Replies
5
Views
9K
Replies
4
Views
3K
Replies
0
Views
3K
{"extraction_info": {"found_math": true, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 0, "mathjax_display_tex": 0, "mathjax_asciimath": 1, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0, "katex": 0, "math-container": 0, "wp-katex-eq": 0, "align": 0, "equation": 0, "x-ck12": 0, "texerror": 0, "math_score": 0.2609909474849701, "perplexity": 10716.556574997907}, "config": {"markdown_headings": true, "markdown_code": true, "boilerplate_config": {"ratio_threshold": 0.18, "absolute_threshold": 10, "end_threshold": 15, "enable": true}, "remove_buttons": true, "remove_image_figures": true, "remove_link_clusters": true, "table_config": {"min_rows": 2, "min_cols": 3, "format": "plain"}, "remove_chinese": true, "remove_edit_buttons": true, "extract_latex": true}, "warc_path": "s3://commoncrawl/crawl-data/CC-MAIN-2021-04/segments/1610704832583.88/warc/CC-MAIN-20210127183317-20210127213317-00529.warc.gz"}