initialization lcd 44780 avr

Thread Starter

demsp

Joined Jun 28, 2018
2
Can i initialize 44780 like so
Code:
#include <avr/io.h>
#define F_CPU 16000000UL //16MHz
#include <util/delay.h>

int main(void) {
DDRD = 0b11111100;
PORTD = 0b00000000;
_delay_ms(20);   //delay 20ms
PORTD = 0b0011 0000;   //PD4=1; PD5=1;
PORTD = 0b0000 1000;   //E=1;
 //_delay_us(10);
PORTD = 0b0000 0000;   //E=0;
_delay_us(40);   //delay 40us
PORTD = 0b0000 1000;   //E=1;
PORTD = 0b0000 0000;   //E=0;
_delay_us(40);   //delay 40us
PORTD = 0b0000 1000;   //E=1;
PORTD = 0b0000 0000;   //E=0;
_delay_us(40);   //delay 40us
PORTD = 0b0010 0000;   //PD5=1;
PORTD = 0b0000 1000;   //E=1;
PORTD = 0b0000 0000;   //E=0;
_delay_us(40);       
// ...
}
A=PD2
RS=PD3
DB4=PD4
DB5=PD5
DB6=PD6
DB7=PD7
 

MrChips

Joined Oct 2, 2009
34,809
Maybe, but that is very poor design.
You need to do this many times, hence put it into a procedure.

Write out in pencil, in plain language what needs to be done. Forget about writing code for now.
Here is an example.

Set R/W to 0
Set RS to 0
Send 4-bit data
Send E = 1
Send E = 0
(Remember to do this without disturbing all other bits that have already been set to 0 or 1.)

Now put all of this into a function that accepts an 8-bit input.
 

Thread Starter

demsp

Joined Jun 28, 2018
2
Thanks, but i have no R/W and RS, i just want to nitialize lcd, so is it right (in 4bit mode)?
Code:
int main(void) {
DDRD = 0b11111100;
PORTD = 0b00000000;

// at first write PD4=1 and PD5=1
_delay_ms(15);         // delay 15ms (after power on)
PORTD = 0b0000 1000;   // E=1;
_delay_ms(4);         // delay 4ms
PORTD = 0b0011 1000;   // PD4=1; PD5=1; E=1;
_delay_ms(4);        // delay 4ms
PORTD = 0b0011 0000;   //PD4=1; PD5=1; E=0; (write)
_delay_ms(4);        // delay 4ms
PORTD = 0b0000 0000;  //PD4=0; PD5=0;

//than write PD4=1 and PD5=1 again
_delay_ms(4);        // delay 4ms
PORTD = 0b0000 1000;   // E=1;
_delay_ms(4);         // delay 4ms
PORTD = 0b0011 1000;   // PD4=1; PD5=1; E=1;
_delay_ms(4);        // delay 4ms
PORTD = 0b0011 0000;   //PD4=1; PD5=1; E=0; (write)
_delay_ms(4);        // delay 4ms
PORTD = 0b0000 0000;  //PD4=0; PD5=0;
//and so on...
 

jayanthd

Joined Jul 4, 2015
945
4-bit HD44780 or caompatible Lcd Driver. Adjust strobe delay as needed.

Code:
#define _LCD_FIRST_ROW          0x80     //Move cursor to the 1st row
#define _LCD_SECOND_ROW         0xC0     //Move cursor to the 2nd row
#define _LCD_THIRD_ROW          0x94     //Move cursor to the 3rd row
#define _LCD_FOURTH_ROW         0xD4     //Move cursor to the 4th row
#define _LCD_CLEAR              0x01     //Clear display
#define _LCD_RETURN_HOME        0x02     //Return cursor to home position, returns a 
                                         //shifted display to its original position.
                                         //Display data RAM is unaffected.
#define _LCD_CURSOR_OFF         0x0C     //Turn off cursor
#define _LCD_UNDERLINE_ON       0x0E     //Underline cursor on
#define _LCD_BLINK_CURSOR_ON    0x0F     //Blink cursor on
#define _LCD_MOVE_CURSOR_LEFT   0x10     //Move cursor left without changing 
                                         //display data RAM
#define _LCD_MOVE_CURSOR_RIGHT  0x14     //Move cursor right without changing 
                                         //display data RAM
#define _LCD_TURN_ON            0x0C     //Turn Lcd display on
#define _LCD_TURN_OFF           0x08     //Turn Lcd display off
#define _LCD_SHIFT_LEFT         0x18     //Shift display left without changing 
                                         //display data RAM
#define _LCD_SHIFT_RIGHT        0x1E     //Shift display right without changing 
                                         //display data RAM

#define EN_DELAY 300
#define LCD_STROBE {LCD_EN = 1; Delay_us(EN_DELAY); LCD_EN = 0; Delay_us(EN_DELAY);};

#define LCD_RS at LATBbits.LATB0
#define LCD_EN at LATBbits.LATB2
#define LCD_D4 at LATBbits.LATB4
#define LCD_D5 at LATBbits.LATB3
#define LCD_D6 at LATBbits.LATB7
#define LCD_D7 at LATBbits.LATB1

#define LCD_RS_Direction TRISBbits.TRISB0
#define LCD_EN_Direction TRISBbits.TRISB2
#define LCD_D4_Direction TRISBbits.TRISB4
#define LCD_D5_Direction TRISBbits.TRISB3
#define LCD_D6_Direction TRISBbits.TRISB7
#define LCD_D7_Direction TRISBbits.TRISB1

void LCD_Cmd(char out_char) {

    LCD_RS = 0;

    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE
    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0;
    LCD_STROBE

    if(out_char == 0x01)Delay_ms(2);
}

void LCD_Chr(char row, char column, char out_char) {

    switch(row){

        case 1:
        LCD_Cmd(0x80 + (column - 1));
        break;
        case 2:
        LCD_Cmd(0xC0 + (column - 1));
        break;
        case 3:
        LCD_Cmd(0x94 + (column - 1));
        break;
        case 4:
        LCD_Cmd(0xD4 + (column - 1));
        break;
    }

    LCD_RS = 1;

    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE

    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0;   
    LCD_STROBE
}

void LCD_Chr_Cp(char out_char) {

    LCD_RS = 1;

    LCD_D4 = (out_char & 0x10)?1:0;
    LCD_D5 = (out_char & 0x20)?1:0;
    LCD_D6 = (out_char & 0x40)?1:0;
    LCD_D7 = (out_char & 0x80)?1:0;
    LCD_STROBE

    LCD_D4 = (out_char & 0x01)?1:0;
    LCD_D5 = (out_char & 0x02)?1:0;
    LCD_D6 = (out_char & 0x04)?1:0;
    LCD_D7 = (out_char & 0x08)?1:0;   
    LCD_STROBE
}

void LCD_Init() {

    Delay_ms(200);

    LCD_RS_Direction = 0;
    LCD_EN_Direction = 0;
    LCD_D4_Direction = 0;
    LCD_D5_Direction = 0;
    LCD_D6_Direction = 0;
    LCD_D7_Direction = 0;
   
    LCD_RS = 0;
    LCD_EN = 0;
    LCD_D4 = 0;
    LCD_D5 = 0;
    LCD_D6 = 0;
    LCD_D7 = 0;   
   
    Delay_ms(30);

    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    Delay_ms(30);

    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    Delay_ms(30);

    LCD_D4 = 1;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    Delay_ms(30);

    LCD_D4 = 0;
    LCD_D5 = 1;
    LCD_D6 = 0;
    LCD_D7 = 0;

    LCD_STROBE

    Delay_ms(30);

    LCD_Cmd(0x28);
    LCD_Cmd(0x06);
}

void LCD_Out(char row, char col, char *text) {
    while(*text)
         LCD_Chr(row, col++, *text++);
}

void LCD_Out_Cp(char *text) {
    while(*text)
         LCD_Chr_Cp(*text++);
}

void main() {

    LCD_Init();
    LCD_Cmd(_LCD_CURSOR_OFF);
    LCD_Cmd(_LCD_CLEAR);
    LCD_Out(1,1,"LCD 20X4");   
    LCD_Out(2,1,"MCU ?");
    LCD_Out(3,1,"PIC ?");
    LCD_Out(4,1,"Working For You ?");

    while(1) {

    }
}
 

MrChips

Joined Oct 2, 2009
34,809
Thanks, but i have no R/W and RS, i just want to nitialize lcd, so is it right (in 4bit mode)?
Code:
int main(void) {
DDRD = 0b11111100;
PORTD = 0b00000000;

// at first write PD4=1 and PD5=1
_delay_ms(15);         // delay 15ms (after power on)
PORTD = 0b0000 1000;   // E=1;
_delay_ms(4);         // delay 4ms
PORTD = 0b0011 1000;   // PD4=1; PD5=1; E=1;
_delay_ms(4);        // delay 4ms
PORTD = 0b0011 0000;   //PD4=1; PD5=1; E=0; (write)
_delay_ms(4);        // delay 4ms
PORTD = 0b0000 0000;  //PD4=0; PD5=0;

//than write PD4=1 and PD5=1 again
_delay_ms(4);        // delay 4ms
PORTD = 0b0000 1000;   // E=1;
_delay_ms(4);         // delay 4ms
PORTD = 0b0011 1000;   // PD4=1; PD5=1; E=1;
_delay_ms(4);        // delay 4ms
PORTD = 0b0011 0000;   //PD4=1; PD5=1; E=0; (write)
_delay_ms(4);        // delay 4ms
PORTD = 0b0000 0000;  //PD4=0; PD5=0;
//and so on...
The code you have is not going to work. You have too many errors and too many inconsistencies.
You can get away with R/W = 0 but you will need RS.

You are modifying DATA bits while trying to pulse E.
You should assume that you might want to change pin assignments at some point.
It is better to define pin assignments so that you can easily port your code to a different application.

For example:

Code:
#define LCD_PORT PORTD
#define E PORTD_bits.BIT3

//Then you can write

LCD_PORT = data;
E = 1;
E = 0;
Edit: The code posted by @jayanthd above is a good example on how to program for any pin assignments.
 
Top