Espanol
AddThis Social Bookmark Button

06b Display Manager

While these are the functions for the management of a 16x2 display with S6A0069 controller from Samsung

//Title:		DrvS6A0069_100.c
//Author:		najro.prestato
//Date:			12/03/07
//Current Rev:	100
//Mod.Descr.:  	LCD display management with Samsung S6A0069 controller
//		The LCD's format is managed by LCD_ROWS and LCD_COLS
//		The modality is managed by LCD_BUS.
//		The LCD control pins are declared by the following constants:
//			LCD_RS			pin for Register selector
//			LCD_RW			pin for Read/Write
//			LCD_EN			pin for Enable
//			LCD_IO_RS		tris for Register selector
//			LCD_IO_RW		tris for Read/Write
//			LCD_IO_EN		tris for Enable
//		The pins for DATA are all on the same port.
//			8 bit:	D0-D7	connected to	Portx0 - Portx7
//			4 bit:	D4-D7	connected to	Portx4 - Portx7
//		The point Top, Left is set to 1,1
//		The settings of the connections comes through:
//			LCD_PORT_DATA	pin port for Data
//			LCD_IO_DATA	tris for Data
//          In order to modify the characteristics for other LCD:
//          	access and modify lcd.h
//Note:		Size Char pos DDRAM addresses
//				2*16 	00..15 		00h..0Fh  +  40h..4Fh
//				2*20 	00..19 		00h..13h  +  40h..53h
//
//
//Functions available for operating LCD :
//
//	lcdinit(void)			Starts LCD
//	checkbf(void)			Waits for the end of the last operation
//	lcdclear(void)			Sends command Clear & Home
//	lcdputch(char)			Writes a character in the cursor's position
//	lcdputs(char *)			Writes a character string
//	lcdwrite(char, char)                         Writes a byte unsigned into DD RAM
//	lcdcommand(char)                           Writes a command
//	lcdgetch(char)			Reads the character in the cursor's position
//	lcdread(char)			Reads a byte unsigned from DD RAM
//	lcdsetcurs(char, char) 	             Moves the cursor to the line, row
//	lcdgetcurs (char, char)	             Returns the current cursor line, row
//

//1: Directives
#include "sfr62.h"
#include "global.h"
#include "S6A0069.h"

//2: Local variables

//3: Local functions prototypes
void delayms(uchar dly_ms);		//Routine of delay in mS (NB: realized with loop)
void delayus10(uchar dly_us);	//Routine of delay of 10uS (NB: realized with loop)
void lcdinit(void);			//Starts LCD - call first, before any other function
void checkbf(void);		//Waits the end of the last operation
void lcdputch(uchar car);		//Writes a character in the current position of the cursor
void lcdputs(uchar far *str);		//Writes a character string

//(NB: It is used to address eventual messages allocated in flash)

void lcdcommand(uchar lcd_cmd);		//Writes a command
void lcdwrite(uchar value, uchar modo);	//Writes a byte unsigned into DD RAM
uchar lcdgetch(void);			//Reads the character in the cursor's position
uchar lcdread(unsigned char modo);		//Reads a byte unsigned from DD RAM
void lcdsetcurs(uchar row, uchar col);	             //Moves the cursor to line, row
void lcdgetcurs(uchar *row,uchar *col);	//Returns the current cursor line, row

//4: LCD driver
void s6a0069(void)
{
	;
}

//5: Local functions code
//
//
//5a) Delay generation routine with BT 1mS (max 255mS)-
void delayms(unsigned char dly_ms)
{
unsigned char	wkreg,wkreg1,wkreg2;
	
	for (wkreg = dly_ms; wkreg ; --wkreg)
	{
		//delay cycle of 1000 uS
		for (wkreg1 = 100; wkreg1 ; --wkreg1)
		{
  			delayus10(DLY10US);	
  		}
	}
}
//
//5b) Delay generation routine with BT 10us-
void delayus10(unsigned char dly_us)
{
#pragma asm			
loop1us:	adjnz.b	#-1,R1L,loop1us
#pragma endasm
}
//

//5c) LCD  initialization with S6A0069 Samsung controller
void lcdinit(void)
{
	LCD_RS = LCD_CMD;		//Set modality Command
	LCD_RW = LCD_WRITE;		//Set modality Write
	LCD_EN = LCD_DISABLE;        	//Disable lcd
	LCD_IO_RS = 1;			//Set pin as output
	LCD_IO_RW = 1;			//Set pin as output
	LCD_IO_EN = 1;			//Set pin as output
	LCD_PORT_DATA = 0x00;		//Set DB7-DB0 = 00000000
	LCD_IO_DATA |= LCD_IO_DMASK;	//Set data bus as output

	//Initialization sequence for S6A0069 Samsung
	//
	//1-Wait for stabilization Vcc: minimum 40mS 
   	delayms(60);
   	//2-Function set: Bus at 8 bit, 2 lines, font 5x8
   	LCD_PORT_DATA = (LCD_BUS_8BIT | LCD_LINE_MULTI | LCD_FONT_5x8);
   	//Strobe E
	LCD_STROBE;
	delayms(1);
   	//3-Display on
   	lcdcommand(LCD_DISPLAY_ON | LCD_CURSOR_OFF |LCD_BLINK_OFF);
	delayms(1);
   	//4-Display clear
    lcdcommand(LCD_CLEAR);
	delayms(3);
   	//5-Default Entry Mode: Autoincrement right, Display shift off
   	lcdcommand(LCD_CURSOR_INC);
}
//
//5d) Verify busy flag LCD
void checkbf(void)
{
unsigned char busy;

    LCD_RS = LCD_CMD;                           // Set modality command
    LCD_RW = LCD_READ;                         // Set modality read
    LCD_IO_DATA &= ~LCD_IO_DMASK;      // Set port as input
    LCD_EN = LCD_ENABLE;		       // Activate Lcd
    do{
        busy = LCD_PORT_DATA & LCD_BIT_BUSY;	// DB7 = BF
    }while (busy);
    LCD_EN = LCD_DISABLE;                       // Disable lcd
    LCD_RW = LCD_WRITE; 			// Set modality write
	LCD_IO_DATA |= LCD_IO_DMASK;	// Set port as output
}
//
//5e) Send a command to LCD
void lcdcommand(uchar lcd_cmd)
{
    //Verify busy flag display (nb: verify made reading BF in loop)
	checkbf();
	//Set modality command on display 
	LCD_RS = LCD_CMD;
	//Transfer to display (check first if bus at 4 or 8 bit)
	#if (LCD_BUS == 8 )
 		LCD_PORT_DATA = lcd_cmd;
	#else
   		//Transfer high byte
   		LCD_PORT_DATA = (LCD_PORT_DATA & ~LCD_IO_DMASK) | (lcd_cmd & LCD_IO_DMASK);
   		LCD_STROBE;
		//Trasfer low byte
   		LCD_PORT_DATA = (LCD_PORT_DATA & ~LCD_IO_DMASK) | (lcd_cmd << 4);
	#endif
   	LCD_STROBE;
}
//
//5f) Write a character on the LCD
void lcdputch(uchar car)
{
    //Verify busy flag display (nb: verify made reading BF in loop)
	checkbf();
	//Set modality data on display
	LCD_RS = LCD_DATA;
	//Trasfer to display (check first if bus at 4 or 8 bit)
	#if (LCD_BUS == 8 )
 		LCD_PORT_DATA = car;
	#else
   		//Trasfer high byte
   		LCD_PORT_DATA = (LCD_PORT_DATA & ~LCD_IO_DMASK) | (car & LCD_IO_DMASK);
   		LCD_STROBE;
		//Trasfer low byte
   		LCD_PORT_DATA = (LCD_PORT_DATA & ~LCD_IO_DMASK) | (car << 4);
	#endif
   	LCD_STROBE;
}
//
//5g) Writes a character string on the LCD
void lcdputs(uchar far *str)
{
    while(*str)
		lcdputch(*str++);
}
//
//5h) Writes an 8 bit unsigned into DDRAM
void lcdwrite(uchar value, uchar modo)
{
	//Verify busy flag display (nb: verify made reading BF in loop)
	checkbf();
	//Set modality display (CMD if modo=0 or DATA if modo=1)
	if (modo==0)
		LCD_RS = LCD_CMD;
	else
		LCD_RS = LCD_DATA;
	//Trasfer to display (check first if bus at 4 or 8 bit)
	#if (LCD_BUS == 8 )
 		LCD_PORT_DATA = value;
	#else
   		//Trasfer high byte
   		LCD_PORT_DATA = (LCD_PORT_DATA & ~LCD_IO_DMASK) | (value & LCD_IO_DMASK);
   		LCD_STROBE;
		//Trasfer low byte
   		LCD_PORT_DATA = (LCD_PORT_DATA & ~LCD_IO_DMASK) | (value << 4);
	#endif
   	LCD_STROBE;
}
//
//5i) Reads the character from the current cursor position
uchar lcdgetch (void)
{
	return lcdread(LCD_DATA);
}
//
//5j) Reads a byte unsigned from DD RAM
uchar lcdread (uchar modo)
{
unsigned char byteDDRAM;
unsigned char highbits;

	//Sets DB7/DB0 as input
	LCD_IO_DATA &= ~LCD_IO_DMASK;
	//Set modality display (CMD if modo=0 or DATA if modo=1)
	LCD_RS = (modo) ? LCD_DATA : LCD_CMD;
	//Sets on display operation of Read
	LCD_RW = LCD_READ;
	delayus10(DLY10US);
	//Enable display
	LCD_EN = LCD_ENABLE;
	delayus10(DLY10US);
	//Read from display (check first if bus at 4 or 8 bit)
	#if (LCD_BUS == 4 )
		//Read high byte
		highbits = LCD_PORT_DATA & LCD_IO_DMASK;
		LCD_EN = LCD_DISABLE;
		delay_us(1);
		LCD_EN = LCD_ENABLE;
		//Read low byte
		byteDDRAM = ((LCD_PORT_DATA & LCD_IO_DMASK) >> 4);
		byteDDRAM |= highbits;
	#else
		byteDDRAM = LCD_PORT_DATA;
	#endif
	LCD_EN = LCD_DISABLE;
	LCD_RS = LCD_CMD;
	LCD_IO_DATA &= ~LCD_IO_DMASK;  		
                       //Sets port lines as output
	return (byteDDRAM);
                       //Returns the read character
}
//
//5k) Moves the cursor to the indicated line and row; the index starts from 1
void lcdsetcurs(uchar row, uchar col)
{
unsigned char pos;

	//Controls correctness of the line and row values
	if (row == 0)
		row = 1;
	if (col == 0)
		col = 1;
	if (row > LCD_ROWS)
		row = LCD_ROWS;
	if (col > LCD_COLS)
		col = LCD_COLS;
	//Sets the base address
	switch (row)
	{
		case 1: 
			pos = LCD_ADDRESS_ROW1;
			break;
		case 2:
			pos = LCD_ADDRESS_ROW2;
			break;
		case 3:
			pos = LCD_ADDRESS_ROW3;
			break;
		case 4:
			pos = LCD_ADDRESS_ROW4;
			break;
	}
    lcdcommand(LCD_SET_ADDRESS | (pos+col-1));
}
//
//5l) Returns the current cursor's position line, row
void lcdgetcurs (uchar *row, uchar *col)
{
unsigned char curAdd;
unsigned char pos;

    //Reads cursor's address
	curAdd = lcdread(LCD_CMD);
 	//Mask for determine the row address this can be 00h, 10h, 40h, 50h
	pos = (curAdd & 0x50);

	switch(pos)
	{
		case LCD_ADDRESS_ROW1:
				*row = 1;
				*col = curAdd - LCD_ADDRESS_ROW1 + 1;
				break;
		case LCD_ADDRESS_ROW2:
				*row = 2;
				*col = curAdd - LCD_ADDRESS_ROW2 + 1;
				break;
		case LCD_ADDRESS_ROW3:
				*row = 3;
				*col = curAdd - LCD_ADDRESS_ROW3 + 1;
				break;
		case LCD_ADDRESS_ROW4:
				*row = 4;
				*col = curAdd - LCD_ADDRESS_ROW4 + 1;
				break;
	}
}