OLED显示模块与C8051F单片机的接口设计
作者:华中科技大学 梁燕 胡浩 卢益民
有机发光显示OLED(Organic Light Emitting Display)是比液晶显示技术更为先进的新一代平板显示技术,是被业界公认为最具发展前景的下一代显示技术。它与液晶显示技术相比,具有超轻薄、高亮度、广视角、自发光、响应速度快、适应温度范围宽、抗震强、功耗低、可实现柔软显示等优越性能,可广泛应用于通信、计算机、消费电子、工业应用、商业、交通等领域。下面以VGS12864E显示模块为例,介绍C8051F020单片机与它的接口设计及软件编程方法。
1 VGS12864E显示模块
VGS12864E是128×64行点阵的OLED单色、字符、图形显示模块。模块内藏64×64的显示数据RAM,其中的每位数据都对应于OLED屏上一个点的亮、暗状态;其接口电路和操作指令简单,具有8位并行数据接口,读写时序适配6800系列时序,可直接与8位微处理器相连;与Intel 8080时序的MCU连接时需要进行时序转换。
2 显示模块结构
2.1 模块框图
VGS12864E显示模块显示屏为128列、64行,使用1片有64行输出的行驱动器和2片列驱动控制器,其中每片列驱动器有64路输出。行驱动器与MCU没有关系,只要提供电源就能产生驱动信号和同步信号,模块的外部信号仅与列驱动器有关。列驱动器内置64×64位显示存储器,RAM被分为8页,每页8行;显示屏上各像素点显示状态与显示存储器各位数据一一对应,显示存储器的数据直接作为图形显示的驱动信号,为“1”显示,为“0”不显示。图1为模块的逻辑电路接口框图。



//P2.7(lcd_rs)为推挽输出方式
P74OUT = 0xf3; //配置P5.0~P5.7(lcd_d0 lcd_d7)
//为推挽输出方式
}

void wr_command1() {
cs1=1; cs1=1; cs1=1; //选择左半屏
cs2=0; cs2=0; cs2=0;
read_status(); //读BUSY位状态
r_w=0; r_w=0; r_w=0;
P5=com; //将命令字节送I/O口
e=1; e=1; e=1;
e=0; e=0; e=0; //在E下降沿,命令字节被写
//入列驱动器
}
void wr_data1() {
cs1=1; cs1=1; cs1=1; //选择左半屏
cs2=0; cs2=0; cs2=0;
read_status(); //读BUSY位状态
d_i=1; d_i=1; d_i=1;
r_w=0; r_w=0; r_w=0;
P5=dat; //将数据字节送I/O口
e=1; e=1; e=1;
e=0; e=0; e=0; //在E下降沿,数据字节被写
//入列驱动器
}
其中,读状态位的函数采用查询标志位的方式,即
void read_status() reentrant {
uchar busy;
uchar temp;
d_i=0; d_i=0; d_i=0; //进行指令操作
r_w=1; r_w=1; r_w=1; //进行读操作
do {
P5=0xff;
e=1; e=1; e=1;
busy=P5; //读入P5端口状态
e=0; e=0; e=0;
temp=busy&0x80;
}while(temp!=0);
}
void init_lcd() {
com=0xc0; //从第0行开始
wr_command1();
wr_command2();
com=0x3f; //打开显示
wr_command1();
wr_command2();
}
void clear_lcd() {
uchar column1;
uchar page;
for(page=0;page<8;page++) {
com=(0xb8+page); //设置页号
wr_command1();
wr_command2();
com=0x40; //设置起始列为0,写操作完
//后列地址计数器自动加1
wr_command1();
wr_command2();
for(column1=0;column1<64;column1++) {
//清左半屏
dat=0;
wr_data1();
}
for(column1=64;column1<128;column1++) {
//清右半屏
dat=0;
wr_data2();
}
}
}
void lcd_write_char_code(uchar page8,uchar column8,uchar* block168)reentrant {
uchar column1;
set_position(page8,column8);//设置所写字符起始页位置
for(column1=0;column1<8;column1++) {
dat=block168[column1];
//从字库中取出上半页8×8点阵字模数据
dat=UpsetChar[dat];
//将每个字节数据高低位进行对调
if(column8<=7)
//如果设置的所写位置在左半屏,调用写左半屏
//数据的函数
wr_data1();
else
//如果设置的所写位置在右半屏,调用写右半屏
//数据的函数
wr_data2();
}
page8++;
set_position(page8,column8);//设置所写字符下半页位置
for(column1=8;column1<16;column1++) {
dat=block168[column1];
//从字库中取出下半页8×8点阵字模数据
dat=UpsetChar[dat];
//将每个字节数据高低位进行对调
if(column8<=7)
//如果设置的所写位置在左半屏,调用写左半屏
//数据的函数
wr_data1();
else
//如果设置的所写位置在右半屏,调用写右半屏数据的函数
wr_data2();
}
}
