📄 ks0108.c
字号:
/*! \file ks0108.c \brief Graphic LCD driver for HD61202/KS0108 displays. */
//*****************************************************************************
//
// File Name : 'ks0108.c'
// Title : Graphic LCD driver for HD61202/KS0108 displays
// Author : Pascal Stang - Copyright (C) 2001-2003
// Date : 10/19/2002
// Revised : 5/5/2003
// Version : 0.5
// Target MCU : Atmel AVR
// Editor Tabs : 4
//
// NOTE: This code is currently below version 1.0, and therefore is considered
// to be lacking in some functionality or documentation, or may not be fully
// tested. Nonetheless, you can expect most functions to work.
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#include <avr/io.h>
#include <avr/interrupt.h>
#include "../global.h"
#include "ks0108.h"
// global variables
GrLcdStateType GrLcdState;
/*************************************************************/
/********************** LOCAL FUNCTIONS **********************/
/*************************************************************/
//------------------------------------------------------------------------//
// gLCD 器飘 檬扁拳
void glcdInitHW(void)
{
// LCD control port Output栏肺 檬扁拳
sbi(GLCD_CTRL_DDR, GLCD_CTRL_RS);
sbi(GLCD_CTRL_DDR, GLCD_CTRL_RW);
sbi(GLCD_CTRL_DDR, GLCD_CTRL_E);
sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS0);
sbi(GLCD_CTRL_DDR, GLCD_CTRL_CS1);
// LCD control 脚龋甫 0栏肺 檬扁拳
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS0);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS1);
// LCD data 檬扁拳
GLCD_DATA_PORT=0x00;
GLCD_DATA_DDR=0xFF;
}
//------------------------------------------------------------------------//
// 咯矾俺狼 Controller吝 茄俺 急琶
void glcdControllerSelect(U8 controller)
{
// unselect all controllers
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS0);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_CS1);
// select requested controller
switch(controller)
{
case 0: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS0);
break;
case 1: sbi(GLCD_CTRL_PORT, GLCD_CTRL_CS1);
break;
default:
break;
}
}
//------------------------------------------------------------------------//
// gLCD啊 Busy啊 场朝锭鳖瘤 措扁
void glcdBusyWait(U8 controller)
{
glcdControllerSelect(controller);
// do a read from control register
GLCD_DATA_PORT=0xFF;
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
GLCD_DATA_DDR=0x00;
sbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
NOP;
NOP;
while(GLCD_DATA_PIN & GLCD_STATUS_BUSY)
{
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
NOP;
NOP;
NOP;
NOP;
sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
NOP;
NOP;
NOP;
NOP;
}
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
GLCD_DATA_DDR=0xFF;
}
//------------------------------------------------------------------------//
// gLCD俊 command 傈价
void glcdControlWrite(U8 controller, U8 data)
{
glcdBusyWait(controller); // wait until LCD not busy
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
GLCD_DATA_DDR=0xFF;
GLCD_DATA_PORT=data;
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
}
//------------------------------------------------------------------------//
// gLCD狼 饭瘤胶磐 佬绢坷扁
U8 glcdControlRead(U8 controller)
{
register U8 data;
glcdBusyWait(controller); // wait until LCD not busy
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
GLCD_DATA_DDR=0x00;
sbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
NOP; NOP;
NOP; NOP;
NOP; NOP;
NOP; NOP;
data = GLCD_DATA_PIN;
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
GLCD_DATA_DDR=0xFF;
return data;
}
//------------------------------------------------------------------------//
// gLCD俊 单捞磐 傈价
void glcdDataWrite(U8 data)
{
register U8 controller = (GrLcdState.lcdXAddr/GLCD_CONTROLLER_XPIXELS);
glcdBusyWait(controller); // wait until LCD not busy
sbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
GLCD_DATA_DDR=0xFF;
GLCD_DATA_PORT=data;
NOP; NOP;
NOP; NOP;
NOP; NOP;
NOP; NOP;
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
// increment our local address counter
GrLcdState.ctrlr[controller].xAddr++;
GrLcdState.lcdXAddr++;
if(GrLcdState.lcdXAddr >= GLCD_XPIXELS)
{
GrLcdState.lcdYAddr++;
glcdSetYAddress(GrLcdState.lcdYAddr);
glcdSetXAddress(0);
}
}
//------------------------------------------------------------------------//
// gLCD狼 单捞磐 佬绢坷扁
U8 glcdDataRead(void)
{
register U8 data;
register U8 controller = (GrLcdState.lcdXAddr/GLCD_CONTROLLER_XPIXELS);
glcdBusyWait(controller); // wait until LCD not busy
sbi(GLCD_CTRL_PORT, GLCD_CTRL_RS);
GLCD_DATA_DDR=0x00;
sbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
sbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
NOP; NOP;
NOP; NOP;
NOP; NOP;
NOP; NOP;
data = GLCD_DATA_PIN;
cbi(GLCD_CTRL_PORT, GLCD_CTRL_E);
cbi(GLCD_CTRL_PORT, GLCD_CTRL_RW);
// increment our local address counter
GrLcdState.ctrlr[controller].xAddr++;
GrLcdState.lcdXAddr++;
if(GrLcdState.lcdXAddr >= GLCD_XPIXELS)
{
GrLcdState.lcdYAddr++;
glcdSetYAddress(GrLcdState.lcdYAddr);
glcdSetXAddress(0);
}
return data;
}
//------------------------------------------------------------------------//
// gLCD狼 X谅钎 汲沥
void glcdSetXAddress(U8 xAddr)
{
U8 i;
// record address change locally
GrLcdState.lcdXAddr = xAddr;
// clear y (col) address on all controllers
for(i=0; i<GLCD_NUM_CONTROLLERS; i++)
{
glcdControlWrite(i, GLCD_SET_Y_ADDR | 0x00);
GrLcdState.ctrlr[i].xAddr = 0;
}
// set y (col) address on destination controller
glcdControlWrite((GrLcdState.lcdXAddr/GLCD_CONTROLLER_XPIXELS),
GLCD_SET_Y_ADDR | (GrLcdState.lcdXAddr & 0x3F));
}
//------------------------------------------------------------------------//
// gLCD狼 Y谅钎 汲沥
void glcdSetYAddress(U8 yAddr)
{
U8 i;
// record address change locally
GrLcdState.lcdYAddr = yAddr;
// set page address for all controllers
for(i=0; i<GLCD_NUM_CONTROLLERS; i++)
{
glcdControlWrite(i, GLCD_SET_PAGE | yAddr);
}
}
/*************************************************************/
/********************* PUBLIC FUNCTIONS **********************/
/*************************************************************/
//------------------------------------------------------------------------//
// gLCD 檬扁拳
void glcdInit(void)
{
U8 i;
glcdInitHW();
// Turn on LCD
for(i=0; i<GLCD_NUM_CONTROLLERS; i++)
{
glcdControlWrite(i, GLCD_ON_CTRL | GLCD_ON_DISPLAY);
}
// 拳搁 瘤快扁
glcdClearScreen();
// 谅钎 檬扁拳
glcdHome();
}
//------------------------------------------------------------------------//
// gLCD 谅钎 檬扁拳 (0, 0)
void glcdHome(void)
{
U8 i;
// initialize addresses/positions
glcdStartLine(0);
glcdSetAddress(0,0);
// initialize local data structures
for(i=0; i<GLCD_NUM_CONTROLLERS; i++)
{
GrLcdState.ctrlr[i].xAddr = 0;
GrLcdState.ctrlr[i].yAddr = 0;
}
}
//------------------------------------------------------------------------//
// 拳搁 瘤快扁
void glcdClearScreen(void)
{
U8 pageAddr;
U8 xAddr;
// clear LCD
// loop through all pages
for(pageAddr=0; pageAddr<(GLCD_YPIXELS>>3); pageAddr++)
{
// set page address
glcdSetAddress(0, pageAddr);
// clear all lines of this page of display memory
for(xAddr=0; xAddr<GLCD_XPIXELS; xAddr++)
glcdDataWrite(0x00);
}
}
//------------------------------------------------------------------------//
// gLCD 矫累扼牢 汲沥
void glcdStartLine(U8 start)
{
glcdControlWrite(0, GLCD_START_LINE | start);
glcdControlWrite(1, GLCD_START_LINE | start);
}
//------------------------------------------------------------------------//
// gLCD X, Y谅钎 汲沥
void glcdSetAddress(U8 x, U8 yLine)
{
glcdSetXAddress(x);
glcdSetYAddress(yLine);
}
//------------------------------------------------------------------------//
//
void glcdGotoChar(U8 line, U8 col)
{
glcdSetAddress(col*6, line);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -