• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

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 DataDir_EIGHTbits    DDRB
#define LCDcontrol            PORTD
#define DataDir_LCDcontrol    DDRD
#define Enable                5 // enable
#define ReadWrite            7
#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)
{
    DataDir_LCDcontrol |= 1<<Enable | 1<<ReadWrite | 1<<RegisterSelect; // Enable, R/W, RS made as outputs
    _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<<ReadWrite; // make sure it's in READ 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;
}
Please help me identify the issue here if possible. Thanks for reading!
 

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
Most Helpful Member
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 :D. 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.

Thank you both for your answers.
 

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.

Latest threads

EE World Online Articles

Loading
Top