GrandAlf
Advanced Member level 2

I am using a 16x1 LCD which is electrically configured as 2x8, to get to the second line, I have to add 0x40 to the display position. Eg home position is 0x80, second line is 0x80+0x40 = (0xC0). At the moment I am doing this in the main program by splitting messages in half and adding 0x40 to the position before writing the second half. This however is not very elegant, and I would like to do this automatically with lcd prog. I have had a few attempts at this, but with limited success. Any advice much appreciated.
LCD.H
/*
* LCD interface header file
* See lcd.c for more info
*/
/* write a byte to the LCD in 4 bit mode */
extern void lcd_write(unsigned char);
/* Clear and home the LCD */
extern void lcd_clear(void);
/* write a string of characters to the LCD */
extern void lcd_puts(const char * s);
/* Go to the specified position */
extern void lcd_goto(unsigned char pos);
/* intialize the LCD - call before anything else */
extern void lcd_init(void);
extern void lcd_putch(char);
/* Set the cursor position */
#define lcd_cursor(x) lcd_write(((x)&0x7F)|0x80)
LCD.C
#include <reg51.h>
#include "delay.h"
sbit LCD_RS =P1^0; // Register select
sbit LCD_E =P1^1; // Enable
#define LCD_STROBE ((LCD_E = 1),(LCD_E=0))
// Time in Milliseconds
void DelayMs(unsigned char cnt)
{ cnt=2*cnt;
do
{DelayUs(500);}
while(--cnt != 0);
}
// Send to Display
void lcd_write(unsigned char c)
{
unsigned char Movit;
Movit = (c >> 2);
P1 = (P1 & 0xC3) | (Movit & 0x3C);
LCD_STROBE;
Movit = (c << 2);
P1 = (P1 & 0xC3) | (Movit & 0x3C);
LCD_STROBE;
DelayUs(60);
}
// Clear and home the LCD
void lcd_clear(void)
{
LCD_RS = 0;
lcd_write(0x80);
DelayMs(2);
}
// Send Character String
void lcd_puts(const char * s)
{
LCD_RS = 1;
while(*s)
lcd_write(*s++);
}
// Send a Character
void lcd_putch(char c)
{
LCD_RS = 1;
lcd_write(c);
}
// Position the Cursor
void lcd_goto(unsigned char pos)
{
LCD_RS = 0;
lcd_write (0x80+pos);
}
// Initialise the LCD - mode 4 bits
void lcd_init(void)
{
LCD_RS = 0;
DelayMs(40); // power on delay
lcd_write(0x28); // 4 bit mode, 1/16 duty, 5x8 font
LCD_STROBE;
DelayMs(5);
LCD_STROBE;
DelayMs(5);
LCD_STROBE;
lcd_write(0x28);
lcd_write(0x08); // display off
lcd_write(0x0C); // display on, cursor off
lcd_write(0x06); // entry mode
}
LCD.H
/*
* LCD interface header file
* See lcd.c for more info
*/
/* write a byte to the LCD in 4 bit mode */
extern void lcd_write(unsigned char);
/* Clear and home the LCD */
extern void lcd_clear(void);
/* write a string of characters to the LCD */
extern void lcd_puts(const char * s);
/* Go to the specified position */
extern void lcd_goto(unsigned char pos);
/* intialize the LCD - call before anything else */
extern void lcd_init(void);
extern void lcd_putch(char);
/* Set the cursor position */
#define lcd_cursor(x) lcd_write(((x)&0x7F)|0x80)
LCD.C
#include <reg51.h>
#include "delay.h"
sbit LCD_RS =P1^0; // Register select
sbit LCD_E =P1^1; // Enable
#define LCD_STROBE ((LCD_E = 1),(LCD_E=0))
// Time in Milliseconds
void DelayMs(unsigned char cnt)
{ cnt=2*cnt;
do
{DelayUs(500);}
while(--cnt != 0);
}
// Send to Display
void lcd_write(unsigned char c)
{
unsigned char Movit;
Movit = (c >> 2);
P1 = (P1 & 0xC3) | (Movit & 0x3C);
LCD_STROBE;
Movit = (c << 2);
P1 = (P1 & 0xC3) | (Movit & 0x3C);
LCD_STROBE;
DelayUs(60);
}
// Clear and home the LCD
void lcd_clear(void)
{
LCD_RS = 0;
lcd_write(0x80);
DelayMs(2);
}
// Send Character String
void lcd_puts(const char * s)
{
LCD_RS = 1;
while(*s)
lcd_write(*s++);
}
// Send a Character
void lcd_putch(char c)
{
LCD_RS = 1;
lcd_write(c);
}
// Position the Cursor
void lcd_goto(unsigned char pos)
{
LCD_RS = 0;
lcd_write (0x80+pos);
}
// Initialise the LCD - mode 4 bits
void lcd_init(void)
{
LCD_RS = 0;
DelayMs(40); // power on delay
lcd_write(0x28); // 4 bit mode, 1/16 duty, 5x8 font
LCD_STROBE;
DelayMs(5);
LCD_STROBE;
DelayMs(5);
LCD_STROBE;
lcd_write(0x28);
lcd_write(0x08); // display off
lcd_write(0x0C); // display on, cursor off
lcd_write(0x06); // entry mode
}