1

I have made a library for LCD with HD44780 controller in it, and from the datasheet I read that the code 0x18 will shift the entire display one position to the left, but when I made that, the display disappears. I have also read that 0x1C shifts the entire display one position to the right but when I made it, the entire display shifts to left.

My code:

    /*
 * main.c
 *
 * Created: 11/14/2013 7:54:02 PM
 *  Author: A R M T
 */ 
#include <avr/io.h>

#define F_CPU 1000000UL
#define __DELAY_BACKWARD_COMPATIBLE__
#include <util/delay.h>
#define LCD_DPRT PORTA                   //LCD DATA PORT
#define LCD_DDDR DDRA                    //LCD DATA DDR
#define LCD_DPIN PINA                    //LCD DATA PIN
#define LCD_CPRT PORTB                   //LCD COMMANDS PORT
#define LCD_CDDR DDRB                    //LCD COMMANDS DDR
#define LCD_CPIN PINB                    //LCD COMMANDS PIN
#define LCD_RS 0                         //LCD RS
#define LCD_RW 1                         //LCD RW
#define LCD_EN 2                         //LCD EN

//*************************************************************

void delay_us(unsigned int d);
void lcdCommand(unsigned char cmnd);
void lcdData(unsigned char data);
void lcd_init(void);
void lcd_gotoxy(unsigned char x, unsigned char y);
void lcd_print(char *str);


//*************************************************************
void delay_us(unsigned int d)
{
    _delay_us(d);
}
//*************************************************************
void lcdCommand(unsigned char cmnd)
{
    LCD_DPRT = cmnd;                   //send cmnd to data port
    LCD_CPRT &= ~(1<<LCD_RS);          //RS = 0 for command
    LCD_CPRT &= ~(1<<LCD_RW);          //RW = 0 for write
    LCD_CPRT |= (1<<LCD_EN);           //EN = 1 for H-to-l pulse
    delay_us(1);                       //Wait to make enable wide
    LCD_CPRT &= ~(1<<LCD_EN);          //EN = 1 for H-to-l pulse
    delay_us(100);                     //Wait to make enable wide
}
//*************************************************************
void lcdData(unsigned char data)
{
    LCD_DPRT = data;                    //send data to data port
    LCD_CPRT |= (1<<LCD_RS);            //RS = 1 for data
    LCD_CPRT &= ~(1<<LCD_RW);           //RW = 0 for write
    LCD_CPRT |= (1<<LCD_EN);            //EN = 1 for H-to-L pulse
    delay_us(1);                        //wait to make enable wide
    LCD_CPRT &= ~(1<<LCD_EN);           //EN = 0 for H-to-L pulse
    delay_us(100);                      //wait to make enable wide
}
//*************************************************************
void lcd_init(void)
{
    LCD_DDDR = 0xFF;
    LCD_CDDR = 0xFF;

    LCD_CPRT &= ~(1<<LCD_EN);           //LCD_EN = 0
    delay_us(15000);                    //wait for init
    lcdCommand(0x38);                   //init. LCD 2 line, 5 * 7 matrix
    lcdCommand(0x0E);                   //display on, cursor on
    lcdCommand(0x01);                   //clear LCD
    delay_us(2000);                     //wait
    lcdCommand(0x06);                   //shift cursor right
}
//*************************************************************
void lcd_gotoxy(unsigned char x, unsigned char y)
{
    unsigned char firstCharAdr[] = {0x80, 0xC0, 0x94, 0xD4};
    lcdCommand(firstCharAdr[y-1] + x - 1);
    delay_us(100);
}
//*************************************************************
void lcd_print(char *str)
{
    unsigned char i = 0;
    while (str[i] != 0)
    {
        lcdData(str[i]);
        i++;
    }
}
//*************************************************************

int main(void)
{

    lcd_init();
    lcd_gotoxy(1,1);
    lcd_print("Armia");
    lcd_gotoxy(1,2);
    lcd_print("Wagdy");
    _delay_ms(1000 / 2);
    lcdCommand(0x18);   // Shift the entire display one position to the left
    while(1);
    return 0;
}

I meant that when I burned this code I excepected that aftr(1000 / 2) ms this output will shift to left enter image description here

but what appears was(the word disappears instead of shifting left one postition)

enter image description here

Can any one help me in that problem please?!

phuclv
  • 37,963
  • 15
  • 156
  • 475
Armia Wagdy
  • 567
  • 6
  • 22
  • From the datasheet (I found one here: www.sparkfun.com/datasheets/LCD/HD44780.pdf), the command to shift the cursor or screen, in binary, is 0001YZ00. Y = 1 to move the display, Z = 1 to shift right, Z = 0 to shift left. So yes, 0x1C should shift right, and 0x18 should shift it left... – Ross Nov 19 '13 at 13:56
  • but what appears was(the word disappears instead of shifting left one postition) – Armia Wagdy Nov 19 '13 at 14:20
  • 1
    I understand; however I didn't see anything incorrect in your code that would cause it to happen. The lcd_command() function must be working, as you use it in lcd_init() and lcd_gotoxy()... Is the _delay_ms() in main working properly? In the LCD code you use _delay_us()... Other than that I don't have any guesses. – Ross Nov 19 '13 at 16:50
  • This could be a simulator model bug, for instance if they do not wrap the display line at 40 as it should. Shifting one way would set the display address as -1, which in the real device wraps to 39. What simulator is this? – Yann Vernier Nov 25 '13 at 19:15

1 Answers1

2

I tried your code in proteus version 7.10 and shift left works fine

shift left

Note that you are using the _delay_us function with a variable parameter, that is not the correct way, it gives wrong delays and generates big hex file because it forces the float library to be included

delay.h manual

Note: In order for these functions to work as intended, compiler optimizations must be enabled, and the delay time must be an expression that is a known constant at compile-time. If these requirements are not met, the resulting delay will be much longer (and basically unpredictable), and applications that otherwise do not use floating-point calculations will experience severe code bloat by the floating-point library routines linked into the application.

Replace the code with a loop that calls the delay several times

while (d--) 
{
  _delay_ms(1);
} 
alexan_e
  • 136
  • 5