OLED之显示一个字符
首先需要用到点阵取模软件,具体配置如下
#include "reg52.h"
#include "intrins.h"
sbit scl = P0^1;
sbit sda = P0^3;
// 起始信号
void IIC_Start()
{
scl = 0; // 防止雪花
scl = 1;
sda = 1;
_nop_();
sda = 0;
_nop_();
}
// 终止信号
void IIC_Stop()
{
scl = 0; // 防止雪花
scl = 1;
sda = 0;
_nop_();
sda = 1;
_nop_();
sda = 0;
}
// 应答
char IIC_ACK()
{
char flag;
sda = 1; // 在时钟脉冲9期间释放数据线 拉高 == 释放
_nop_(); // 一个nop()相当于 5us
scl = 1;
_nop_();
flag = sda;
_nop_();
scl = 0;
_nop_();
return flag;
}
// 数据信号
void IIC_Send_Byte(char dataSend)
{
int i;
for(i = 0; i < 8; i++){
scl = 0; // scl拉低,让sda做好数据准备
// sda = dataSend的高位
sda = dataSend & 0x80;
_nop_(); // 发送数据建立时间
scl = 1; // scl拉高开始发送
_nop_(); // 数据发送时间
scl = 0; // 发送完毕拉低
_nop_();
dataSend = dataSend << 1; // 把传输完的那一位数据清除掉
}
}
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(0x40);
// 5. ACK
IIC_ACK();
// 6. 写入数据
IIC_Send_Byte(dataData);
// 7. ACK
IIC_ACK();
// 8. STOP
IIC_Stop();
}
void Oled_Init()
{
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()
{
unsigned char i,j; // -128 --- 127
for(i = 0; i < 8; i++){
Oled_Write_Cmd(0xB0 + i); // page0 - page7
// 从每个page第0列开始
Oled_Write_Cmd(0x00);
Oled_Write_Cmd(0x10);
// 每个page从0列到127列,以此写入0,每写入数据,列地址自动偏移
for(j = 0; j < 128; j++){
Oled_Write_Data(0);
}
}
}
/*-- 文字: A --*/
/*-- 宋体12; 此字体下对应的点阵为:宽x高=8x16 --*/
char A1[8] = {0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00};
char A2[8] = {0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20};
void main()
{
int i;
// 1.OLED初始化
Oled_Init();
// 2. 选择一个位置
Oled_Write_Cmd(0x20);
// 2.1 确认是页选址模式
Oled_Write_Cmd(0x02);
Oled_Clear();
// 2.2 选择PAGE0 1011 0000 0xB0
Oled_Write_Cmd(0xB0);
Oled_Write_Cmd(0x00);
Oled_Write_Cmd(0x10);
for(i = 0; i < 8; i++){
Oled_Write_Data(A1[i]);
}
Oled_Write_Cmd(0xB1);
Oled_Write_Cmd(0x00);
Oled_Write_Cmd(0x10);
for(i = 0; i < 8; i++){
Oled_Write_Data(A2[i]);
}
while(1);
}