📄 ks0108.c
字号:
/*******************************************************************/
/*文件名:KS0108.c */
/*功能: SAMSUNG KS0108 控制器驱动 */
/*作者: 张驿风 */
/*时间: 20060112 */
/*******************************************************************/
/*
记录:KS0108和HD61202兼容但是RAM地址采用分页和Y地址自动加1的方法,每页
包含8行,每次写入的一个字节对应这8行的每一个点,(即一次写入的不
是传统显示RAM的8列,而是8行,这要特别注意.
本驱动假设使用的是双屏即是128列
20060112 Ver0.01 开始编写写入读取函数
20060114 Ver0.02 能够显示,但是不符合常规,这是由于KS0108本身分址的原
因,稍候要调整为正常的写点方式(模拟TC图形库方式).
20060131 Ver0.03 增加写点pixel函数以后大部分的显示函数将建立在该函数基础上,符合
TC图形库方式,这样KS0108显示屏就是一个128x64的画布可以任意发挥。
20060131 Ver0.04 支持ASCII字符,汉字显示。
KS0108C点阵对应示意图
01234567 . . . 128
0 ########
1 ########
2 ########
3 ########
4 ########
5 ########
6 ########
7 ######## --->一页(包含8行) 读写一个BYTE时实际读取的是一列中的一页8个点数据.
.
.
.
63
*/
#include "ks0108.h"
#include "board.h"
#include "KS0108.h"
#include <iom8v.h>
#include "init.h"
#include "serial.h"
#include <macros.h>
void delay(unsigned int t){
unsigned int i,j;
for(i=0;i<t;i++)
for(j=0;j<10;j++);
}
/*******************************************************************/
/*名称:WriteLcmCmd */
/*功能:写入一个Byte命令到LCM模块 */
/*参数:cmdcode要写入的命令 */
/*******************************************************************/
void WriteLcmCmd(u8 cmdcode){
while(ReadLcmStatus() & GLCD_STATUS_BUSY);
CLR_LCM_DI; //asm(" nop");
CLR_LCM_RW; //asm(" nop");
SET_LCM_DATA_OUT; //asm(" nop");
SET_LCM_DATA(cmdcode); //asm(" nop");
SET_LCM_E; //asm(" nop");
CLR_LCM_E;
}
/*******************************************************************/
/*名称:WriteLcmData */
/*功能:写入一个Byte数据到LCM模块 */
/*参数:uValue要写入的数据 */
/*******************************************************************/
void WriteLcmData(u8 uValue){
while(ReadLcmStatus() & GLCD_STATUS_BUSY);
SET_LCM_DI; //asm(" nop");
CLR_LCM_RW; //asm(" nop");
SET_LCM_DATA_OUT; //asm(" nop");
SET_LCM_DATA(uValue); //asm(" nop");
SET_LCM_E; //asm(" nop");
CLR_LCM_E;
}
/*******************************************************************/
/*名称:ReadLcmData */
/*功能:读出一个Byte数据从LCM模块 */
/*参数:返回读取的数据 */
/*******************************************************************/
u8 ReadLcmData(void){
u8 uData;
while(ReadLcmStatus() & GLCD_STATUS_BUSY);
SET_LCM_DATA_IN;
SET_LCM_DI; //asm(" nop");
SET_LCM_RW; //asm(" nop");
SET_LCM_E; // asm(" nop");
CLR_LCM_E; //asm(" nop");
uData = GET_LCM_DATA;
return uData;
}
/*******************************************************************/
/*名称:ReadLcmStatus */
/*功能:读出KS0108状态 */
/*参数:返回读取的数据 */
/*******************************************************************/
u8 ReadLcmStatus(void){
u8 uData;
SET_LCM_DATA_IN;
CLR_LCM_DI; //asm(" nop");
SET_LCM_RW; //asm(" nop");
SET_LCM_E; //asm(" nop");
CLR_LCM_E; //asm(" nop");
uData = GET_LCM_DATA;
return uData;
}
void InitLcd(void){
CLR_LCM_RST;
delay(100);
SET_LCM_RST;
delay(100);
SET_LCM_nCS1;
SET_LCM_nCS2;
WriteLcmCmd(GLCD_ON_CTRL | GLCD_OFF_DISPLAY); //关闭显示
WriteLcmCmd(GLCD_SET_PAGE + 0); //设置X页地址
WriteLcmCmd(GLCD_SET_Y_ADDR + 0); //设置Y列地址
WriteLcmCmd(GLCD_START_LINE + 0); //设置起始行
WriteLcmCmd(GLCD_ON_CTRL | GLCD_ON_DISPLAY); //开显示
}
void Clr(void){
unsigned char j,k;
SET_LCM_nCS1;
SET_LCM_nCS2;
WriteLcmCmd(GLCD_SET_Y_ADDR + 0);
for(k=0;k<8;k++){
WriteLcmCmd(GLCD_SET_PAGE + k);
for(j=0;j<64;j++)
WriteLcmData(0x00);
}
}
/***********************************************************************/
/*Name: pixel(u8 x,u8 y,u8 color) */
/*function : write a dot to lcd */
/*parameter: x:horizontal coordinate, y: vertical coordinate */
/* : color:显示色彩在黑白屏就是黑和白两种 */
/***********************************************************************/
/*记录:
这个函数我实现的比较复杂,其原因有2:
一是KS0108芯片的特点.
二是我习惯于PC下的显卡驱动写点方法,所以促成该函数的复杂性。
这样就为上层应用屏蔽了各种控制器的差异,便于移植到各种通用的图形函数控制库。
*/
void pixel(u8 x,u8 y,u8 color){
u8 uData;
u8 PageX,BitX,AddrY;
AddrY = y;
if(AddrY < 64 ){ //选择第二个ks0108控制器
SET_LCM_nCS1;
CLR_LCM_nCS2;
}
else{ //选择第一个ks0108控制器
SET_LCM_nCS2;
CLR_LCM_nCS1;
AddrY -= 64; //片内偏移
}
WriteLcmCmd(GLCD_SET_Y_ADDR + AddrY); //设置Y地址
PageX = x / 8;
BitX = x%8;
WriteLcmCmd(GLCD_SET_PAGE + PageX); //设置页地址
uData = ReadLcmData(); //读出缓冲区存储数据
uData = ReadLcmData(); //第一次读的数据不一定准确,第2次读的正确,实验得到的。
#if DEBUG_PIXEL
printf("Read pixel=");
sendhexstr8(uData);
putchar(' ');
#endif
switch(color){ //修改点数据
case clBlack:{
uData |= (1 << BitX);
break;
}
case clWhite:{
uData &= ~(1 << BitX);
break;
}
}
WriteLcmCmd(GLCD_SET_Y_ADDR + AddrY); //设置Y地址
#if DEBUG_PIXEL
printf("Write pixel=");
sendhexstr8(uData);
#endif
WriteLcmData(uData); //写入修改后的点数据
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -