1. 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.
    Dismiss Notice

Using LCD and ATMega32 problem

Discussion in 'AVR' started by Cantafford, Jan 9, 2017.

  1. Cantafford

    Cantafford Member

    Joined:
    Jul 5, 2015
    Messages:
    251
    Likes:
    2
    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):
    [​IMG]

    Here is the code I wrote:
    Code (text):

    /*
     * 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!
     
  2. wkrug

    wkrug Active Member

    Joined:
    May 30, 2010
    Messages:
    280
    Likes:
    29
    Location:
    Germany
    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.
     
    • Like Like x 1
  3. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK
    ONLINE
    Agreed...
    Code (of a sort):

         _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);
     
     
    • Like Like x 1
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Cantafford

    Cantafford Member

    Joined:
    Jul 5, 2015
    Messages:
    251
    Likes:
    2

    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.
     
  6. wkrug

    wkrug Active Member

    Joined:
    May 30, 2010
    Messages:
    280
    Likes:
    29
    Location:
    Germany
    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.
     

Share This Page