📄 ks0108.c
字号:
/*
***********************************************************************************************
* JHD12864G/J Graphical LCD Display Driver (KS0107/8 controller)
*
* File name : KS0108.c
* Programmer : RAUL
* Web presence :
* Note :
* Language : PICC18 MPLINK 4.15, Linker Copyright (c) 2007 Microchip Technology Inc.
* Hardware : PIC18F4520 demo board
* Date : Version 1.0 (04 MAY 2008) - ()
***********************************************************************************************
* DESCRIPTION
*
* This module provides an interface to JHD12864J Graphical LCD module of size 128x64 dots
* Display controller chip is KS0107/8
* LCD pinout function summarized as below
* --------- LCD MCU -----------------
* pin 1 Vss - 0V
* pin 2 Vdd - 5.0V
* pin 3 Vo - LCD Drive Voltage (adjust contrast, trimmer to Vee in our case)
* pin 4 D/I - LCD_DI (H:Data, L:Command (data or command control))
* pin 5 R/W - LCD_RW (H:Read, L:Write (read status or write data/command))
* pin 6 E - LCD_EN (H/H->L (Strobe signal, H->L effective))
* pin 7:14 DB0:DB7 - LCD_DATA
* pin 15 CS1 - LCD_CS1 (left, high effective)
* pin 16 CS2 - LCD_CS2 (right, high effective)
* pin 17 RST - LCD_RST (reset pin, low effective)
* pin 18 Vee - -10.0V, LCD driving voltage. There is a Vee generator built-in LCD
* module, thus there is no need to use external generator IC
* pin 19 EL1 / A - LCD_BL (Depends on the backlight option.
* If it's a LED backlight, it's an anode.
* If it is EL type, this is EL controller input)
* pin 20 EL2 / K - GND (Cathode for LED-backlight. EL input (OR NC) for EL-backlight model)
***********************************************************************************************
*/
#include <p18f452.h> /* for the special function register declarations */
#include "ks0108.h"
#if PIXEL_FONT_EN
#include "sysfont.h"
#endif
/*
*********************************************************************************************************
* LOCAL DEFINITIONS
*********************************************************************************************************
*/
#define LCD_STAT_RST 0x10
#define LCD_STAT_BUSY 0x80
#define LCD_STAT_OFF 0x20
#define DISPLAY_ON 0x3F
#define DISPLAY_OFF 0x3E
#define DISPLAY_START_LINE 0xC0
#define PAGE_OFFSET 0xB8
#define Y_OFFSET 0x40
#define STATUS_RD 0
#define DATA_RD 1
#define CMD 0
#define DAT 1
#define HIGH 1
#define LOW 0
#define RIGHT 0
#define LEFT 1
#define BOTH 2
#define NONE 3
const rom unsigned char tab_comp[] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
unsigned char xy;
#ifdef FAST_GLCD
struct
{
unsigned char left[512];
unsigned char right[512];
} displayData;
#endif
/*
*********************************************************************************************************
* DISPLAY INITIALIZATION
*
* Description : This function initializes the LCD module by the following steps:
* 1. Enable the backlight
* 2. Reset the LCD module
* 3. Disable the LCD
* 4. Set display start line at the top of the screen
* 5. clear the display by writing 0 to the whole screen
* 6. re-enable the display
* Arguments : none
*
* Returns : none
* Note : This function should be called once before any of the other functions
*********************************************************************************************************
*/
void GDispInit(void)
{
GDispBackLite(ENABLE);
GDispReset();
GDispSwitch(DISABLE);
GDispWr(CMD,DISPLAY_START_LINE);//set display start line at the top of the LCD
GDispClr(0x00); //clear the display
GDispSwitch(ENABLE);
}
/*
*********************************************************************************************************
* DISPLAY ON/OFF SWITCH
*
* Description : This function turns display ON/OFF by writing the command DISPLAY_ON / DISPLAY_OFF
* Arguments : (bit) 'sw' ENABLE for turning ON defined under ks0108.h
* DISABLE for turning OFF defined under ks0108.h
*
* Returns : none
* Notes : Internal status and display RAM data not changed by switching between ON and OFF
*
*********************************************************************************************************
*/
void GDispSwitch(unsigned char sw)
{
GDispChipSel(BOTH);
(sw==ENABLE)? (GDispWr(CMD,DISPLAY_ON)):(GDispWr(CMD,DISPLAY_OFF));
GDispChipSel(NONE);
}
/*
*********************************************************************************************************
* WRITE A SINGLE BYTE AT A COLUMN# AND PAGE#
*
* Description : This function writes a single byte 'c' to a column position defined by 'col' and
* to PAGE# indicated by the variable 'page'
* Arguments : 'col' the column position (0-127) of the LCD, 0<=col<128 (MAX_COL_PIXEL in ks0108.h)
* 'page' the PAGE number (0-7) of the LCD. It is NOT the y coordinate as our usual
* Cartesian coordinate system.
* It is the PAGE number defined in JHD12864J data sheet
* 'c' byte to write
* Returns : none
* Notes : This function should has been declared as a local function because it is rarely
* called in main. However, if we want to make a different version of string display with
* higher efficiency, we may make use of this function to write byte in vertical manner.
*********************************************************************************************************
*/
void GDispWrByte(unsigned char col, unsigned char page, unsigned char *c)
{
col = col%MAX_COL_PIXEL;
page = page%8;
if(col<(MAX_COL_PIXEL/2))
{GDispChipSel(LEFT);}
else
{GDispChipSel(RIGHT);col=col-(MAX_COL_PIXEL/2);}
GDispWr(CMD,PAGE_OFFSET|page);
GDispWr(CMD,Y_OFFSET|col); //set page and column position
GDispWr(DAT, c);
//output data to D0-D7
GDispChipSel(NONE);
}
/*
*********************************************************************************************************
* CLEAR DISPLAY
*
* Description : This function writes a fixed byte to all pages (0-7) of both half. If the byte is 0x00,
* the action is equivalent to clearing the display (turning all pixels OFF)
* Arguments : 'pat' is the pattern to write to the display in a repetitive manner. Writing 0xFF
* for example, will turn all pixels BLACK.
*
* Returns : none
* Notes : This function makes use of GdispWrByte() thus the speed of clearing is fast!
*********************************************************************************************************
*/
void GDispClr(unsigned char pat)
#ifdef FAST_GLCD
{
unsigned int i;
for(i = 0; i <512; ++i)
{
displayData.left[i]=pat;
displayData.right[i]=pat;
}
}
#else
{
unsigned char col, page;
for(col=0;col<128;col++)
{ for(page=0;page<8;page++)
GDispWrByte(col,page,pat);}
}
#endif
/*
*********************************************************************************************************
* SET PIXEL AT x, y POSITION
*
* Description : This function sets a pixel with color = BLACK / WHITE (defined in ks0108.h) at a position
* defined by (x,y) following Cartesian coordinate system. Coordinates (0,0) at the
* top left corner, coordinates (127,63) at the lower right corner of the LCD screen.
*
* Arguments : 'x' 0....MAX_COL_PIXEL-1 is matrix position in horizontal direction
* 'y' 0....MAX_ROW_PIXEL-1 is matrix position in vertical direction
* 'color' sets BLACK / WHITE standing for pixel ON/OFF
* Returns : none
* Notes : The action GDispRd() has an effect of auto-increment on the x-direction (Y address)
* Thus, GDispWr(CMD,Y_OFFSET|x) has to be immediate above data write code line
* (color==BLACK)? GDispWr(DAT,pre_data|(1<<y%8)):GDispWr(DAT,pre_data&~(1<<y%8))
*
*********************************************************************************************************
*/
void GDispSetPixel(unsigned char x, unsigned char y, char color)
#ifdef FAST_GLCD
{
unsigned char* p;
int temp;
temp = y/8;
temp *= 64;
temp += x;
if(x > 63)
{
p = displayData.right + temp - 64;
}
else
{
p = displayData.left + temp;
}
if(color)
{
*p|=(1<<(y%8));
}
else
{
*p&=~(1<<(y%8));
}
}
#else
{
unsigned char pre_data;
x = x%MAX_COL_PIXEL;
y = y%MAX_ROW_PIXEL;
if(x<(MAX_COL_PIXEL/2))
{GDispChipSel(LEFT);}
else
{GDispChipSel(RIGHT);x=x-(MAX_COL_PIXEL/2);
}
GDispWr(CMD,PAGE_OFFSET|(y/8)); //set pixel address in vertical direction (page address)
GDispWr(CMD,Y_OFFSET|x); //set pixel address in horizontal direction
pre_data=GDispRd(DATA_RD); //dummy read required
pre_data=GDispRd(DATA_RD); //address pointer auto increment by one
GDispWr(CMD,Y_OFFSET|x); //set pixel address in horizontal direction again to offset
//the address pointer shift from GDispRd(DATA_RD) above
(color==BLACK)? GDispWr(DAT,pre_data|(1<<(y%8))):GDispWr(DAT,pre_data&~(1<<(y%8)));
GDispChipSel(NONE);
}
#endif
/*
*********************************************************************************************************
* WRITE A PATTERN AT X, Y COORDINATES
*
* Description : This function writes a particular pattern of size patWidth and patHeight defined under
* the pattern structure in ks0108.h at a position defined by (x,y) following Cartesian
* coordinate system. Pixel set in horizontal direction.
* *** Pixels displayed in horizontal manner ***
* Arguments : 'x' 0....MAX_COL_PIXEL-1 is matrix position in horizontal direction
* top left corner of the pattern to write
* 'y' 0....MAX_ROW_PIXEL-1 is matrix position in vertical direction
* top left corner of the pattern to write
* '*pPat' pointer to pattern structure
* 'color' sets BLACK / WHITE standing for pixel ON/OFF
* Returns : none
* Notes :
*********************************************************************************************************
*/
#if PIXEL_PAT_EN
void GDispPixPatAt(unsigned char x, unsigned char y, pattern* pPat, bit color)
{
unsigned char i, j, bit_idx, pixelByte, patYsize, patByte;
patYsize = pPat->patHeight;
patByte = (pPat->patWidth)>>3; //number of byte = width of icon/8
for(i=0;i<patYsize;i++)
{
for(j=0;j<patByte;j++)
{
pixelByte = pPat->patBody[i*patByte+j];
for(bit_idx=0;bit_idx<8;bit_idx++)
{
(pixelByte&(0x80>>bit_idx))? GDispSetPixel(x+bit_idx+8*j, y+i, color):GDispSetPixel(x+bit_idx+8*j, y+i, !color);
}
}
}
}
#endif
/*
*********************************************************************************************************
* CONVERT A STRING TO PIXEL DATA AND DISPLAY AT x,y
*
* Description : This function outputs a string in graphic mode (pixel-by-pixel) at a position defined
* by (x,y) following Cartesian coordinate system with variable font spacing defined by
* fontSpace. Character wrapping is allowed.
* Enable switch PIXEL_FONT_EN under ks0108.h to use this function
* *** REQUIRE AT LEAST ONE FONT SET (sysfont.h) ****
*
* Arguments : 'x' 0....MAX_COL_PIXEL-1 is matrix position in horizontal direction,
* top left corner of each character to write
* 'y' 0....MAX_ROW_PIXEL-1 is matrix position in vertical direction,
* top left corner of each character to write
* '*pStr' pointer to an ASCII string
* 'fontSpace' font spacing from 1 to 127
* 'color' WHITE / BLACK
* Returns : none
* Notes : Example
* ....
* main()
* {
* GDispPixFontAt(0,20,"Hello!",1,BLACK); //Display the ASCII string "Hello!"
* //at (x,y)=(0,20), font space = 1
* //color in BLACK
* }
*
*
*********************************************************************************************************
*/
#if PIXEL_FONT_EN
void GDispPixStrAt(unsigned char x, unsigned char y, const rom unsigned char *pStr, unsigned char fontSpace,char color)
{
unsigned char pixelByte,bit_idx, i; //loop counters
unsigned char c,fwidth, fheight; //character, font width & height store
while (*pStr)
{
PORTCbits.RC1=1;
c = *pStr++ - 32;
fwidth = SYS_FNT[c].fontWidth;
fheight = 8;
if((x+fwidth)>MAX_COL_PIXEL) //character wrapping here
{
x=0;
y+=fheight;
}
if((y+fheight)>MAX_ROW_PIXEL) //check for y boundary
{
y=0;
}
for(i=0;i<fheight;i++)
{
pixelByte = SYS_FNT[c].fontBody[i];
for(bit_idx=0; bit_idx<fwidth; bit_idx++)
{
if((pixelByte)&(0x80>>bit_idx))
/*ekleme ba
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -