清屏函数:
void Oled_Clear()
{
int i, j;//注意char 是 -128 -- 127,j++会越界,有时会出现问题,unsigned char
for(i=0;i<8;i++)
{
Oled_Write_Cmd(0xB0+i);//page0--page7
//每个page从0列开始清理屏幕
Oled_Write_Cmd(0x00);
Oled_Write_Cmd(0x10);//可以不用写,因为下面有0-128
//一共有128列,0~127,写入0清理屏幕
for(j=0;j<128;j++)
{
Oled_Write_Data(0x00);
}
}
}
oled的页寻址模式的列地址怎么了解
首先查看手册的地址说明
可以得到结论
//有128列,2的7次方,手册中3.Address setting command table,
//lower higher,8个x,有7个x是1就可以了满足128列屏幕的要求,
Oled_Write_Cmd(0x0F);//0000 1111 0x0F
Oled_Write_Cmd(0x11);//0001 0001 0x18
//根据,0000 1111 0x0F,0001 1000 0x18,可知,x只有5个是1,要想在最后一列,
//必须满足x为7个1以上,
//注意:1. 0000 1111
0001 1110 这种不行2. 大于128的点就会显示在屏幕外
//所以
Oled_Write_Cmd(0x0F);
Oled_Write_Cmd(0x17);//或者Oled_Write_Cmd(0x1F);
#include "reg52.h"
#include "intrins.h"
sbit SCL = P0^1;
sbit SDA = P0^3;
void IIC_Star()
{
SCL=0;//防止雪花屏
SCL=1;
SDA=1;
//判断是起始信号,SDA在延时大于4.7us后,电频由高变低,然后再延时大于4us
_nop_();//一个nop()函数在11.592晶振得机器周期为1us ,但是在函数调用中有时间损耗,大约有5us.
SDA=0;
_nop_();
}
void IIC_Stop()
{
SCL=0;//防止雪花屏
SCL=1;
SDA=0;
//判断是停止信号,SDA在延时大于4us后,电频由低变高,然后在延时大于4.7us
_nop_();
SDA=1;
_nop_();
}
char IIC_ACK()//有效应答
{
char flag;//为了获取SDA得高电频还是低电频
SDA = 1;//就在时钟脉冲9期间释放数据线
_nop_();
SCL = 1;
_nop_();
flag = SDA;//scl为高电平时,记录SDA得电频
_nop_();
SCL = 0;
_nop_();
return flag;
}
void IIC_Send_Byte(char dataSend)
{
int i = 0;
for(i=0;i<8;i++)
{
SCL = 0;//给SDA做数据准备
SDA = dataSend & 0x80;//1000 0000,取高位,SDA升高电频
_nop_();//延时等待
SCL = 1;//升高再等一会,就是发送一位完整得bit,
_nop_();
SCL = 0;//重新变低,准备下次的字节bit数据发送,给SDA做数据准备
_nop_();
dataSend = dataSend << 1;//左移一位
}
}
void Oled_Write_Cmd(char dataCmd)
{
//start();
IIC_Star();
//写入从机地址,b0111 1000 0x78 最后两位bit---SAO(0/1),RW(0/1)
IIC_Send_Byte(0x78);
//ACK
IIC_ACK();
//cotrol byte (0)(D/C)000000 。 D/C=0 写入命令 0x00, D/C=1 写入数据 0x40
IIC_Send_Byte(0x00);
//ACK
IIC_ACK();
//写入数据、命令
IIC_Send_Byte(dataCmd);
//ACK
IIC_ACK();
//STOP
IIC_Stop();
}
void Oled_Write_Data(char dataData)
{
//start();
IIC_Star();
//写入从机地址,b0111 1000 0x78 最后两位bit---SAO(0/1),RW(0/1)RW=0为write
IIC_Send_Byte(0x78);
//ACK
IIC_ACK();
//cotrol byte (0)(D/C)000000 。 D/C=0 写入命令 0x00, D/C=1 写入数据 0x40
IIC_Send_Byte(0x40);
//ACK
IIC_ACK();
//写入数据、命令
IIC_Send_Byte(dataData);
//ACK
IIC_ACK();
//STOP
IIC_Stop();
}
void Oled_Init(void){
Oled_Write_Cmd(0xAE);//--display off
Oled_Write_Cmd(0x00);//---set low column address
Oled_Write_Cmd(0x10);//---set high column address
Oled_Write_Cmd(0x40);//--set start line address
Oled_Write_Cmd(0xB0);//--set page address
Oled_Write_Cmd(0x81); // contract control
Oled_Write_Cmd(0xFF);//--128
Oled_Write_Cmd(0xA1);//set segment remap
Oled_Write_Cmd(0xA6);//--normal / reverse
Oled_Write_Cmd(0xA8);//--set multiplex ratio(1 to 64)
Oled_Write_Cmd(0x3F);//--1/32 duty
Oled_Write_Cmd(0xC8);//Com scan direction
Oled_Write_Cmd(0xD3);//-set display offset
Oled_Write_Cmd(0x00);//
Oled_Write_Cmd(0xD5);//set osc division
Oled_Write_Cmd(0x80);//
Oled_Write_Cmd(0xD8);//set area color mode off
Oled_Write_Cmd(0x05);//
Oled_Write_Cmd(0xD9);//Set Pre-Charge Period
Oled_Write_Cmd(0xF1);//
Oled_Write_Cmd(0xDA);//set com pin configuartion
Oled_Write_Cmd(0x12);//
Oled_Write_Cmd(0xDB);//set Vcomh
Oled_Write_Cmd(0x30);//
Oled_Write_Cmd(0x8D);//set charge pump enable
Oled_Write_Cmd(0x14);//
Oled_Write_Cmd(0xAF);//--turn on oled panel
}
void Oled_Clear()
{
int i, j;//注意char 是 -128 -- 127,j++会越界,有时会出现问题,unsigned char
for(i=0;i<8;i++)
{
Oled_Write_Cmd(0xB0+i);//page0--page7
//每个page从0列开始清理屏幕
Oled_Write_Cmd(0x00);
Oled_Write_Cmd(0x10);//可以不用写,因为下面有0-128
//一共有128列,0~127,写入0清理屏幕
for(j=0;j<128;j++)
{
Oled_Write_Data(0x00);
}
}
}
void main()
{
int i=0;
//1.初始化OLED
Oled_Init();
//2.确认一个位置67
//2.1.确认页寻址模式 0x20 0x02
Oled_Write_Cmd(0x20);
Oled_Write_Cmd(0x02);
Oled_Clear();//清屏操作
//2.2.选择page(0-7) 我们使用page0 地址命令在手册上找,
//1011 0x1x2x3,page0为1011 0000 0xB0
Oled_Write_Cmd(0xB0);
//第一列开始显示
Oled_Write_Cmd(0x00);
Oled_Write_Cmd(0x10);
//输入数据显示
//3.显示一个点 0000 1000 0x08,page的特性那个bit位为高电频就亮
Oled_Write_Data(0x08);
Oled_Write_Data(0x08);
Oled_Write_Data(0x08);
Oled_Write_Data(0x08);
Oled_Write_Data(0x08);
Oled_Write_Data(0x08);
Oled_Write_Cmd(0xB2);
//第一列开始显示
Oled_Write_Cmd(0x00);
Oled_Write_Cmd(0x10);
//输入数据显示
Oled_Write_Data(0x08);
Oled_Write_Data(0x08);
Oled_Write_Data(0x08);
Oled_Write_Data(0x08);
Oled_Write_Data(0x08);
Oled_Write_Data(0x08);
Oled_Write_Cmd(0xB3);
//第一列开始显示
Oled_Write_Cmd(0x00);
Oled_Write_Cmd(0x10);
//输入数据显示
Oled_Write_Data(0x08);
Oled_Write_Data(0x08);
Oled_Write_Data(0x08);
Oled_Write_Data(0x08);
Oled_Write_Data(0x08);
Oled_Write_Data(0x08);
//有128列,2的7次方,手册中3.Address setting command table,
//lower higher,8个x,有7个x是1就可以了满足128列屏幕的要求,
//大于128的点就会显示在屏幕外
// Oled_Write_Cmd(0x0F);//0000 1111 0x0F(或者0x0f)
// Oled_Write_Cmd(0x11);//0001 0001 0x18
//根据,0000 1111 0x0F,0001 1000 0x18,可知,x只有5个是1,要想在最后一列,
//必须满足x为7个1以上,
//注意:0000 1111
// 0001 1110 这种不行
//所以
Oled_Write_Cmd(0x0F);
Oled_Write_Cmd(0x17);//或者Oled_Write_Cmd(0x1F);
Oled_Write_Data(0x08);
//4.防止程序退出
while(1);
}