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;
}
}
|