一.了解IIC协议


#include <reg52.h>
#include <intrins.h>
sbit sda=P0^3;
sbit scl=P0^1;
void IIC_Start()
{
scl=0;
sda=1;
scl=1;
_nop_();
sda=0;
_nop_();
}
void IIC_Stop()
{
scl=0;
sda=0;
scl=1;
_nop_();
sda=1;
_nop_();
}
//数据翻转是在SCL为低电平的时候,可以观察上面的时序图
char IIC_ACK()
{
char flag;
sda=1;
_nop_();
scl=1;
_nop_();
flag=sda;
_nop_();
scl=0;
_nop_();
return flag;
}
void IIC_Send_Byte(char datas)
{
int i;
for(i=0;i<8;i++) {
scl=0;//scl拉低,让sda做好数据准备
sda=datas & 0x80;//1000 0000 让sda等于datas的高位
_nop_(); //发送数据建立时间
scl=1; //scl拉高开始发送
_nop_(); //数据发送时间
scl=0; //发送完毕,scl拉低
_nop_();
datas= datas <<1; //左移一位,
}
}
二.OLED写命令
下面是IIC总线数据格式
从图中的s开始写,步骤如下:
a.start()
b.写入slave Adress(通过查询手册,可知地址为b0111 1000 ==0x78)
c.ACK(有效应答位)
d.写Control Byte:(0)(0)00 0000写入命令,(0)(1)00 0000写入数据
如果Co位被设置为逻辑“0”,则以下信息的传输将只包含数据字节。
如果D/C#位设置为逻辑“0”,则会将以下数据字节定义为命令。如果D/C#位被设置为逻辑“1”,那么它会将以下数据字节定义为将存储在GDDRAM中的数据。每次写入数据后,GDDRAM列地址指针将自动增加一个。
e.ACK
f.stop
例如下面的代码:
//这是写入命令的代码
void Oled_Write_Cmd(char dataCmd)
{
// 1. start()
IIC_Start();
//
// 2. 写入从机地址 b0111 1000 0x78
IIC_Send_Byte(0x78);
// 3. ACK
IIC_ACK();
// 4. cotrol byte: (0)(0)000000 写入命令 (0)(1)000000写入数据
IIC_Send_Byte(0x00);
// 5. ACK
IIC_ACK();
//6. 写入指令/数据
IIC_Send_Byte(dataCmd);
//7. ACK
IIC_ACK();
//8. STOP
IIC_Stop();
}
//下面是写入数据的代码
void Oled_Write_Data(char dataData)
{
// 1. start()
IIC_Start();
//
// 2. 写入从机地址 b0111 1000 0x78
IIC_Send_Byte(0x78);
// 3. ACK
IIC_ACK();
// 4. cotrol byte: (0)(0)000000 写入命令 (0)(1)000000写入数据
IIC_Send_Byte(0x00);
// 5. ACK
IIC_ACK();
///6. 写入指令/数据
IIC_Send_Byte(dataData);
//7. ACK
IIC_ACK();
//8. STOP
IIC_Stop();
}
做好了上面关于oled的iic协议的代码之后,就可以着手OLED的寻址模式,行地址选择,列地址选择,之后可以用oled发送一个点,一个字符,一行字符以及一个图片。
3.OLED的寻址模式
寻址模式有三种:页地址模式,水平地址模式和垂直地址模式。
这里用的是页地址模式。
页地址模式
在页寻址模式下,读写显示RAM后,列地址指针自动增加1。如果列地址指针到达列结束地址,则列地址指针将被重置为列起始地址,而页地址指针将不会被更改。用户必须设置新的页面和列地址,才能访问下一页的RAM内容。页寻址模式的PAGE和列地址点的移动顺序如下图。
此OLED为8行,128列。
水平地址模式
垂直地址模式
在OLED电子说明书中查找Page Adressing,找到这个图,看到页地址模式(红色部分为页地址模式,得到后两位为10,即0x20,0x02为页地址模式)
在这里找到PAGE0的命令表,看图得PAGE0为0xB0。
下面是OLED的行和列的布局。一个PAGE有8位,有8个PAGE,然后有128列。