Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Thread

4 bits LCD Driver Routine for AVR Micro

4 bits LCD Driver Routine for AVR Micro

2005-08-15 by Robert Rademacher

Hello all,

I found this lcd routines from avrfreaks.net - and want to improve on
this one - and then save it to AVR-Chat files folder on AVR-Chat Yahoo
Groups to be shared by our AVR-Chat members.

Maybe you can help on correcting these routines to make it right.

Cheers,

Robert
====================================

//lcd.h***************************
char  lcd_write_string (unsigned char x,unsigned char y, char *text,
unsigned char centered);
void lcd_init (void);
void lcd_cls (void);
//**********************************

//lcd.c***********************
#include <string.h>
#include <iom128v.h>
#include <macros.h>
#include "lcd.h"

#define LCDCOLS 20
#define LCDROWS 2
/*
Port Definition
AVR PINS - LCD
0 - Data0
1 - Data1
2 - Data2
3 - Data3
4 - RS
5 - R/W
6 - Enable
7 - Open / Not-Used
*/

//Edit the PORTx, DDRx, PINx based on your AVR micro ports
#define LCDPORT       PORTC
#define LCDDDR        DDRC
#define LCDPIN        PINC
#define LCD_RS_MASK   0x10
#define LCD_RW_MASK   0x20
#define LCD_EN1_MASK  0x40

extern void Delay_ms(unsigned int msecs);

/* for Delay_ms(unsigned int msecs) routine:

//pass the number of milliseconds of delay to the function
#define xtal 14745600L

void Delay_ms(unsigned int msecs)
   {
   unsigned long ms = (xtal/37700L);  //1 ms worth of clock pulses
   unsigned int y,z;
   for (z=0;z<msecs;z++)
   	for (y=0;y<ms;y++);
   }
*/

void lcd_ready (unsigned char enable)
{	
unsigned char busy;
unsigned char itemp,count;
 
	itemp    = LCDDDR;
	LCDDDR   = itemp & 0xF0;			                          	// Switch high
nibble to input
	LCDPORT  &= ~( LCD_RW_MASK | LCD_RS_MASK | enable);  //Clear all
control lines
	LCDPORT  |= LCD_RW_MASK;				
 	
 Delay_ms(10);
 
	do
	{	
 
  for (count = 0; count < 8; count++)
	  		LCDPORT |= enable;
   
		busy    =  LCDPIN & 0x80;			//Get Port input, check busy flag
		LCDPORT &= ~enable;
		LCDPORT |= enable;				     	//clock low nibble
		LCDPORT &= ~enable;
  Delay_ms(10);
	}		
	while (busy);
 
	LCDDDR = itemp;		           	//restore DDR
}		

void lcd_out (unsigned char data, unsigned char enable)
{	

unsigned char itemp, tempdat;
	
	itemp   = LCDDDR;
	LCDPORT &= 0x0F;					         //disable display data
	LCDPORT |= ( data & 0xF0 );			// Set Data to port, high nibble
	LCDDDR  |= 0xF0;						        //Set Port, high nibble  to output
	LCDPORT |= enable;
	LCDPORT &= ~enable;					      //Disable LCD
	data    = data <<4 ;
 
	LCDPORT &= 0x0F;
	LCDPORT |= data & 0xF0;			   	// Set Data to port, low nibble
	LCDPORT |= enable;					       //Enable LCD
	LCDPORT &= ~enable;				       //Disable LCD
	LCDDDR  =  itemp;					       	//restore DDR
}

void lcd_write_command (unsigned char com, unsigned char enable)
{	

 lcd_ready(enable);
	LCDPORT &= ~( LCD_RW_MASK | LCD_RS_MASK | enable);  //Clear all
control lines
	lcd_out (com, enable);
}	
	
char lcd_write_string (unsigned char x, unsigned char y, char *text,
unsigned char centered)
{	

 unsigned char error=0, ramadress,portstat;
	static unsigned char enable;
	
	if (centered)
		 x = ( LCDCOLS - strlen(text) ) >> 1;
   
	error = ( ( 0x40*y ) > ( 0x40*(LCDROWS-1) ) );
 
	if (!error)
		error=( x > LCDCOLS- 1 );					//adjust for different LCD, max
columns-1
  
	if (!error)
	{	

  if (y >= 0)
		{	
    ramadress = 0x40*y + x;
			 enable = LCD_EN1_MASK;
 			lcd_write_command ( ramadress | 0x80, enable);
		}
  
		while (*text != 0)
		{  	
   lcd_ready(enable);
			LCDPORT &= ~(LCD_RW_MASK | LCD_RS_MASK | enable);  //Clear all
control lines
			LCDPORT |= LCD_RS_MASK;
			lcd_out (*text++, enable);
		}
  
	}
 
	return error;
}



void lcd_cls (void)
{	
  lcd_write_command (1,LCD_EN1_MASK);
}


void lcd_init (void)
{	
unsigned char  counter;

	Delay_ms(20);	            	//wait 20ms
	LCDPORT &= 0x01;	          //switch off all except #1
 
	for (counter=0;counter<3;counter++)
	{	
  LCDPORT |= 0x30;	//set 4 bit mode
		LCDPORT |= LCD_EN1_MASK;
		LCDPORT &= ~LCD_EN1_MASK;
  Delay_ms(6);
	}

	LCDPORT |= 0x20;	//set 4 bit mode
	LCDPORT |= LCD_EN1_MASK;
	LCDPORT &= ~LCD_EN1_MASK;
	Delay_ms(6);
	
	lcd_write_command (0x28,LCD_EN1_MASK);      //2 line mode,5x7
dots,4bit Interface
	lcd_write_command (0x0c,LCD_EN1_MASK);		//Display on, Cursor off,not 
blinking
	lcd_write_command (1,   LCD_EN1_MASK);		//Clear display
	lcd_write_command (0x06,LCD_EN1_MASK); 	//Entry mode increment, shift
off
	Delay_ms(20);

}
//****************


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.