📄 ks0108.c
字号:
//================================================================
// KS0108驱动
//================================================================
#include <reg51.h>
#include <FONT.h>
//================================================================
// 液晶接口定义
//================================================================
#define Lcd_Bus P2
sbit RS = P1^0;
sbit RW = P1^1;
sbit E = P1^2;
sbit CSA = P1^3;
sbit CSB = P1^4;
sbit Lcd_Rst = P1^5;
//================================================================
// KS0108指令代码定义
//================================================================
#define Set_Disp_On 0x3F
#define Set_Disp_Off 0x3E
#define Set_Column 0x40
#define Set_Page 0xB8
#define Set_Start_Line 0xC0
//---------------------------------------------------------------
//基本硬件操作
//----------------------------------------------------------------
void Delay(int t);
//void CheckState();unsigned char Read_0108_Data();
void Write_0108_Reg(unsigned char Reg_Code);
void Write_0108_Data(unsigned char Disp_Data);
void Initialize();
void SetPage(unsigned char Page);
void SetColumn(unsigned char Column);
static void PutData(unsigned char Page,unsigned char Column,unsigned char Page_amount,unsigned char Column_amount);
void ClearScr(unsigned char Page,unsigned char Column,unsigned char Page_amount,unsigned char Column_amount);
static void PutFont(unsigned char ascii_code,unsigned char mode,unsigned char i) ;
void PutChar(unsigned char Page,unsigned char Column,unsigned char ascii_code,unsigned char mode) ;
void DisplayListChar(unsigned char Page,unsigned char Column,unsigned char *listchar,unsigned char mode);
static void PutPic(unsigned char width,unsigned char *pic,unsigned char mode,unsigned char i,unsigned char j);
void DisplayPic(unsigned char Page,unsigned char Column,unsigned char high,
unsigned char width,unsigned char *pic,unsigned char mode);
//================================================================
// TEST
//================================================================
/*unsigned char code tip_pic[]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0xF8,0xF8,0xC0,0x60,0x30,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xF8,0xF8,0x98,0x98,0x98,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xF8,0xF8,0x18,0x18,0xF8,0xF8,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x08,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xF8,0xF8,0x18,0x18,0xF8,0xF8,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x18,0x18,0xF8,0xF8,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
0xC0,0xC0,0xC0,0xE0,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,
0x3F,0x06,0x0C,0x18,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x31,0x31,0x31,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x20,0x3F,0x3F,0x20,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x3F,0x3F,0x31,0x31,0x3F,0x3F,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x00,
0x00,0x03,0x03,0x07,0x7F,0x7F,0x0F,0x1F,0x07,0x03,0x03,0x03,0x03,
0x03,0x03,0x01,0x01,0x01,0x00,0x00,0x00,0x00,
};
unsigned char code TEST[]="KS0108 CONTROLER TEST";
main()
{
Initialize();
ClearScr(0,0,8,128);
DisplayPic(0,0,2,128,tip_pic,1);
DisplayListChar(4,0,TEST,1);
//PutChar(1,62,'T',1);
while(1) ;
}*/
//================================================================
// 延时子程序
//================================================================
void Delay(int t)
{
while(--t);
}
/*================================================================
//状态检查
//================================================================
void CheckState()
{
unsigned char dat;
RS=0;
RW=1;
do{
Lcd_Bus=0xff;
E=1; dat=Lcd_Bus; E=0;
dat=0x90 & dat; //仅当第4,7位为0时才可操作
}while(!(dat==0x00));
}*/
//================================================================
// KS0108寄存器写入函数
//================================================================
void Write_0108_Reg(unsigned char Reg_Code)
{
//CheckState(); //如果不是频繁操作不需检查
RS=0;
RW=0;
Lcd_Bus=Reg_Code;
E=1;
E=0;
}
//================================================================
// KS0108显示数据写入函数
//================================================================
void Write_0108_Data(unsigned char Disp_Data)
{
//CheckState();
RS=1;
RW=0;
Lcd_Bus=Disp_Data;
E=1;
E=0;
}
//================================================================
// 读取KS0108显示数据函数
//================================================================
/*unsigned char Read_0108_Data()
{
unsigned char Disp_Data;
RS=1;
RW=1;
Lcd_Bus=0xff;
E=1;
Disp_Data=Lcd_Bus;
E=0;
return Disp_Data;
}*/
//================================================================
// KS0108寄存器初始化函数
//================================================================
void Initialize()
{
Lcd_Rst=0;
Delay(100);
Lcd_Rst=1;
Delay(100);
CSA=1;
CSB=1;
Delay(100);
Write_0108_Reg(Set_Disp_Off);
Write_0108_Reg(Set_Start_Line);
Write_0108_Reg(Set_Page);
Write_0108_Reg(Set_Column);
Write_0108_Reg(Set_Disp_On);
}
//================================================================
void SetPage(unsigned char Page)
{ if ( Page>7)Page=0;
Page=Page|Set_Page;
Write_0108_Reg(Page);}
void SetColumn(unsigned char Column)
{
if (Column>64)Column=0;
Column=Column | Set_Column;
Write_0108_Reg(Column);}
//===============================================================
// 清屏函数
//===============================================================
static void PutData(unsigned char Page,unsigned char Column,unsigned char Page_amount,unsigned char Column_amount)
{
unsigned char i,k;
for(k=0;k<Page_amount;k++)
{SetPage(Page+k);SetColumn(Column);for(i=0;i<Column_amount;i++) Write_0108_Data(0x00);}
}
//================================================================
void ClearScr(unsigned char Page,unsigned char Column,unsigned char Page_amount,unsigned char Column_amount)
{
unsigned char j;
if (Column+Column_amount<65) //左半部分
{CSA=1;CSB=0;PutData(Page,Column,Page_amount,Column_amount);}
//--------------------------------------------------------------------------------------
if (Column+Column_amount>64&&Column<=64) //左右交界处
{
j=64-Column;
CSA=1;CSB=0;PutData(Page,Column,Page_amount,j);
CSA=0;CSB=1;PutData(Page,Column,Page_amount,(Column_amount-j));
}
//--------------------------------------------------------------------------------------
if (Column>64) //右半部分
{CSA=0;CSB=1;PutData(Page,Column,Page_amount,Column_amount);}
}
//================================================================
// 输出一个ASCII字符
//================================================================
static void PutFont(unsigned char ascii_code,unsigned char mode,unsigned char i)
{if (mode)
Write_0108_Data(~asc[(ascii_code-0x20)*6+i]);
else
Write_0108_Data(asc[(ascii_code-0x20)*6+i]);}
//================================================================
void PutChar(unsigned char Page,unsigned char Column,unsigned char ascii_code,unsigned char mode)
{
unsigned char i,j; //左半部分显示
if (Column+7<65) //如判断左半部剩余空间在7列范围内则显示
{CSA=1;CSB=0;SetColumn(Column);SetPage(Page);
for(i=0;i<7;i++)PutFont(ascii_code,mode,i);}
//--------------------------------------------------------------------------------------
if (Column+7>64&&Column<=64) //左右交界处显示
{j=64-Column; //如判断左半部剩余空间不够7列时,先取出左半部剩余列数
CSA=1;CSB=0;SetColumn(Column);SetPage(Page);//然后显示字符在左半部分占用的内容
for(i=0;i<j;i++)PutFont(ascii_code,mode,i);
CSA=0;CSB=1;SetColumn(Set_Column);SetPage(Page);//列指针归零,再显示字符在右半部分剩余的内容
for(i=j;i<7;i++)PutFont(ascii_code,mode,i);} //总计在左右交界处合成显示一个字符
//--------------------------------------------------------------------------------------
if (Column>64) //右半部分显示 如判断在右半部分
{CSA=0;CSB=1;SetColumn(Column-64);SetPage(Page);//将指定列位置指针调整到右半部允许范围内即<64
for(i=0;i<7;i++)PutFont(ascii_code,mode,i);} //显示
}
//--------------------------------------------------------------------------------------
//================================================================
// 输出一个字符串
//================================================================
void DisplayListChar(unsigned char Page,unsigned char Column,unsigned char *listchar,unsigned char mode)
{
while (*listchar) //字符串如果为空则停止显示
{
if((128-Column)<6)Page++,Column=0;//一个字符占用6列,如判断剩余空间不够6列时则换行
if(Page>8)return;
PutChar(Page,Column,*(listchar++),mode);
Column+=6; //步进为6是为了节约显示空间
}
}
//================================================================
// 输出一个位图
//================================================================
static void PutPic(unsigned char width,unsigned char *pic,unsigned char mode,unsigned char i,unsigned char j)
{
if (mode)
Write_0108_Data(~pic[i+j*width]); //临时变量j代表位图高度计数i代表位图宽度计数 width代表位图实际宽度
else //如高2x宽4图共有数据8个 第一个数据地址为pic[0+0x4],第二个数据地址为pic[1+0x4]
Write_0108_Data(pic[i+j*width]); // 倒数第二个数据地址为pic[3+1x4],最后一个数据地址为pic[4+1x4]
}
//================================================================
void DisplayPic(unsigned char Page,unsigned char Column,unsigned char high,
unsigned char width,unsigned char *pic,unsigned char mode)
{
unsigned char i,j,k;
if(high>8||width>128)return; //越界退出
if (Column+width<65) //如在左半部分 则左半部显示
{CSA=1;CSB=0;for(j=0;j<high;j++)
{SetPage(Page+j);SetColumn(Column);
for(i=0;i<width;i++)PutPic(width,pic,mode,i,j);}}
//--------------------------------------------------------------------------------------
if (Column+width>64&&Column<=64) //如在左右交界处并超出左半部分
{
k=64-Column; //先取出左半部剩余显示区域
CSA=1;CSB=0;for(j=0;j<high;j++)
{SetPage(Page+j);SetColumn(Column);
for(i=0;i<k;i++)PutPic(width,pic,mode,i,j);}//以剩余显示区域k为上限显示在左半部内容
CSA=0;CSB=1;for(j=0;j<high;j++) //下来打开右半部
{SetPage(Page+j);SetColumn(Set_Column); //并将列指针归零
for(i=k;i<width;i++)PutPic(width,pic,mode,i,j);}//以k为下限显示在右半部内容
}
//--------------------------------------------------------------------------------------
if (Column>64) //如在右半部分
{CSA=0;CSB=1;for(j=0;j<high;j++)
{SetPage(Page+j);SetColumn(Column-64); //将指定列位置指针调整到右半部允许范围内即<64
for(i=0;i<width;i++)PutPic(width,pic,mode,i,j);}} //右半部显示
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -