xs128之OLED12864

OLED12864

前言:

昨天晚上,我们组团购的龙丘OLED12864终于到了,我怀着激动的心情拿着比想象中要小的显示屏,真想一下子就把他点亮。

遗憾的是,买来时没有数据手册,手头上没有写好的程序,自己对它的操作也完全一头雾水。

各种百度无果后,登录论坛去淘资料,经过层层筛选,终于得到了一个比较好的资料。在此向智能车论坛这位楼主致谢!

看了一遍后,还是一头雾水,果断回去睡觉。

第二天,已经有小伙伴点亮了他们的OLED,我却看着手册,根据上面的理论,开始写自己的代码。

我实在不愿做代码的搬运工,不愿去照搬别人写好的代码,那样虽然见效快,却没有太大意义,明白原理后自己写出来才是真正的学习。

中午前写了初始化和基本的显示,自觉可以测验了,结果却还是一片黑暗,然后就去吃饭吧。

吃饭回来后,我决定对比着网上已有的例程去稍作更改自己不好的地方,就是这个过程中,我发现了我写的一个致命的错误!把时钟错当为了复位!!!

而在程序中,复位是绝对关键的部分

下面开始具体分析过程:

  看到大多程序初始化全是”惊人“一致地有好多语句,其实好多语句是没有多大用处的,因为好多语句是在默认情况下就已成立的,直接复位采取默认就好了。

复位操作:

当 RES 输入低电平时,芯片将执行以下的初始化步骤:
1、关闭显示
2、128*64 显示模式
3、正常列地址以及行地址映射(SEG0 映射至列地址 00H,COM0 映射至行地址 00H)
4、串行移位寄存器数据清零
5、将 RAM 存储区的 0 地址设为显示的起始行
6、列地址计数器设为 0
7、设置行正常扫描方向
8、对比度寄存器设置为 0x7F

9、正常显示模式

由于在上电后 RES 低电平使芯片内部相关寄存器已经复位,所以只需要设置电荷泵和 开启显示就可以了

软件初始化步骤:

1、设置 RES 低电平,延时一段时间。经过测试这个只要很短时间即可。

2、设置 RES 高电平,正常操作芯片时 RES 需要保持高电平。

3、设置段地址重映射 0xA0/0xA1。如果图像反了修改此命令即可。

4、设置行扫描方向 0xC0/0xC8。行输出反了修改此处命令。

5、允许电荷泵 0x8D,0x14。(这个是手册上说明的,没弄懂什么意思。)

6、开启显示 0xAF。

经过以上步骤就可以对显示屏 RAM 区写入数据操作了,其他的保持默认配置即可


写指令与写数据:

 串行数据 SDIN(D1)接口的数据在时钟信号 SCLK(D0)的每个上升沿移位到内部寄存器,8 位数据以 D7,D6...D0 高位在前低位在后的顺序转移。
  数据/命令 DC 在每第 8 个时钟周期 采样判断输入的是数据还是命令。在串行总线模式下,只允许对芯片进行写操作。

 为LED写指令

**八位指令,从高到低逐字节写入**
    1.选择写指令 DC=0
    2.时钟拉低 SCLK=0
    3.循环右移写入各个字节

 注意写字节后拉高时钟,稍微延时后拉低,这是因为数据在时钟信号 SCLK 的每个上升沿移位到内部寄存器

为LED写数据:

    选择写数据 DC=1  其他同写指令


简易代码参考:

/********************************
*     XS128OLED12864
*     by Quex
*     2014/7/10
********************************/
#include       /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */


#define LED_SCL	PTT_PTT0 // 时钟定义
#define LED_SDA PTT_PTT1  //数据口D1
#define LED_RST PTT_PTT2 //复位低能电平
#define LED_DC  PTT_PTT3 //偏置常低
#define WIDTH 128
#define HEIGHT 64

//写指令:
void Write_Cmd(byte cmd){
    uchar cycle;  //循环量
    LED_DC=0;     //写命令
    LED_SCL=0;    //拉低时钟
    for(cycle=0;cycle<8;cycle++){
         if(cmd&0x80)
            LED_SDA=1;
          else
            LED_SDA=0;
        // asm("nop"); 
         LED_SCL=1;
         asm("nop");
         asm("nop");
         LED_SCL=0;
         cmd<<=1;
    }
}

//写数据
void Write_Data(byte data){
    uchar cycle;  //循环量
    LED_DC=1;     //写命令
    LED_SCL=0;    //拉低时钟
    for(cycle=0;cycle<8;cycle++){
         if(data&0x80)
            LED_SDA=1;
         else
            LED_SDA=0;
        // asm("nop");
         LED_SCL=1;
         asm("nop");
         asm("nop");
         LED_SCL=0;
         data<<=1;
    }
}

//初始化
void OLED_Init(){
   DDRT=0xff;  //T口作为输出
   LED_SCL=1;
   LED_RST=0;
   asm("nop");
   asm("nop");
   LED_RST=1;
   Write_Cmd(0xa0); //写命令
   Write_Cmd(0xc0);//写命令
   Write_Cmd(0x8d); //写命令
   Write_Cmd(0x14);
   Write_Cmd(0xaf); //开显示
}

//填充数据
void OLED_Fill(byte data)
{
	byte y,x;
	
	for(y=0;y<8;y++)
	{
		Write_Cmd(0xb0+y);//设置页地址
		Write_Cmd(0x01); //设置列低四位
		Write_Cmd(0x10); //设置列高四位
		for(x=0;x

效果是这样子的:

xs128之OLED12864_第1张图片


先这样,其他的还有待研究,替我加油吧,我会尽快更新剩下内容。





你可能感兴趣的:(飞思卡尔)