概述
因为esp32 micropython中没有SSD_1306驱动代码遂决定移植arduino平台中驱动代码到micropython
arduino平台驱动代码
//定义类
CN_SSD1306::CN_SSD1306(int sda, int scl)
{
_sda = sda;
_scl = scl;
pinMode(sda, OUTPUT);
pinMode(scl, OUTPUT);
}
每次开启关闭iic总线可以节省cpu负担
//开启IIC总线
void CN_SSD1306::IIC_Start()
{
digitalWrite(_scl, HIGH);
digitalWrite(_sda, HIGH);
digitalWrite(_sda, LOW);
digitalWrite(_scl, LOW);
}
//停止IIC总线
void CN_SSD1306::IIC_Stop()
{
digitalWrite(_scl, LOW);
digitalWrite(_sda, LOW);
digitalWrite(_scl, HIGH);
digitalWrite(_sda, HIGH);
}
向iic总线写一比特数据
//通过IIC写一个8位的数据,比如0xff
void CN_SSD1306::Write_IIC_Byte(unsigned char IIC_Byte)
{
unsigned char i;
for(i=0;i<8;i++)
{
if((IIC_Byte << i) & 0x80)digitalWrite(_sda, HIGH);
else
digitalWrite(_sda, LOW);
digitalWrite(_scl, HIGH);
digitalWrite(_scl, LOW);
// IIC_Byte<<=1;
}
digitalWrite(_sda, HIGH);
digitalWrite(_scl, HIGH);
digitalWrite(_scl, LOW);
}
//IIC写命令 -- 命令操作很少,对速度影响不大
void CN_SSD1306::Write_IIC_Command(unsigned char IIC_Command)
{
IIC_Start();
Write_IIC_Byte(0x78); //Slave address,SA0=0
Write_IIC_Byte(0x00); //write command
Write_IIC_Byte(IIC_Command);
IIC_Stop();
}
//开始IIC写数据 -- 这样可以让一组数据发送完成后再关闭IIC,能很大程度提速
void CN_SSD1306::Begin_IIC_Data()
{
IIC_Start();
Write_IIC_Byte(0x78);
Write_IIC_Byte(0x40); //write data
}
设置起始点坐标
//设置起始点坐标
void CN_SSD1306::IIC_SetPos(unsigned char x, unsigned char y)
{
IIC_Start();
Write_IIC_Byte(0x78); //Slave address,SA0=0
Write_IIC_Byte(0x00); //write command
Write_IIC_Byte(0xb0+y);
Write_IIC_Byte(((x&0xf0)>>4)|0x10);//|0x10
Write_IIC_Byte((x&0x0f)|0x01);//|0x01
IIC_Stop();//SetPos函数经常被使用,所以采用了这种发送一组命令再关闭IIC总线的方式
}
//全屏显示 -- Fill_Screen(0x00)可用作清屏
void CN_SSD1306::Fill_Screen(unsigned char fill_Data)
{
unsigned char m,n;
for(m=0;m<8;m++)
{
Write_IIC_Command(0xb0+m); //page0-page1
Write_IIC_Command(0x00); //low column start address
Write_IIC_Command(0x10); //high column start address
Begin_IIC_Data();
for(n=0;n<128;n++)
{
Write_IIC_Byte(fill_Data);
}
IIC_Stop();
}
}
可用于16*16中文
//显示16x16的中文
void CN_SSD1306::ShowCN(unsigned char x, unsigned char y, unsigned char N)
{
unsigned char wm=0;
unsigned int adder=32*N;
IIC_SetPos(x , y);
Begin_IIC_Data();
for(wm = 0;wm < 16;wm++)
{
Write_IIC_Byte(CN16x16[adder]);
adder += 1;
}
IIC_Stop();
IIC_SetPos(x,y + 1);
Begin_IIC_Data();
for(wm = 0;wm < 16;wm++)
{
Write_IIC_Byte(CN16x16[adder]);
adder += 1;
}
IIC_Stop();
}
可用于显示8*16英文或数字
void CN_SSD1306::Show_8(unsigned char x, unsigned char y, unsigned char N)
{
unsigned char wm=0;
unsigned int adder=16*N;
IIC_SetPos(x , y);
Begin_IIC_Data();
for(wm = 0;wm < 8;wm++)
{
Write_IIC_Byte(CN16x8[adder]);
adder += 1;
}
IIC_Stop();
IIC_SetPos(x,y + 1);
Begin_IIC_Data();
for(wm = 0;wm < 8;wm++)
{
Write_IIC_Byte(CN16x8[adder]);
adder += 1;
}
IIC_Stop();
}
//SSD1306初始化
void CN_SSD1306::Initial()
{
Write_IIC_Command(0xAE);//display off
Write_IIC_Command(0x00);//set lower column address
Write_IIC_Command(0x10);//set higher column address
Write_IIC_Command(0x40);//set display start line
Write_IIC_Command(0xB0);//set page address
Write_IIC_Command(0x81);//对比度设置
Write_IIC_Command(0xCF);//0~255(对比度值……效果不是特别明显)
Write_IIC_Command(0xA1);//set segment remap
Write_IIC_Command(0xA6);//normal / reverse
Write_IIC_Command(0xA8);//multiplex ratio
Write_IIC_Command(0x3F);//duty = 1/64
Write_IIC_Command(0xC8);//Com scan direction
Write_IIC_Command(0xD3);//set display offset
Write_IIC_Command(0x00);
Write_IIC_Command(0xD5);//set osc division
Write_IIC_Command(0x80);
Write_IIC_Command(0xD9);//set pre-charge period
Write_IIC_Command(0xF1);
Write_IIC_Command(0xDA);//set COM pins
Write_IIC_Command(0x12);
Write_IIC_Command(0xDB);//set vcomh
Write_IIC_Command(0x40);
Write_IIC_Command(0x8D);//set charge pump enable
Write_IIC_Command(0x14);
Write_IIC_Command(0xAF);//display ON
}
移植后
myiic.py
from machine import Pin, I2C
class IIC(object):
#初始化相关引脚
def __init__(self, sda=21, scl=22):
self.i2c = I2C(scl=scl, sda=sda, freq=400000)
#启动iic总线
def IIC_Start(self):
self.i2c.start()
#关闭iic总线
def IIC_Stop(self):
self.i2c.stop()
#写8位数据
def Write_IIC_Byte(self, IIC_Byte: hex):
self.i2c.write(IIC_Byte)
#oled写命令
def Write_IIC_Command(self, IIC_Command: hex):
self.IIC_Start()
self.Write_IIC_Byte(0x78)
self.Write_IIC_Byte(0x00)
self.Write_IIC_Byte(IIC_Command)
self.IIC_Stop()
#oled写数据
def Write_IIC_Data(self, IIC_Data: hex):
self.IIC_Start()
self.Write_IIC_Byte(0x78)
self.Write_IIC_Byte(0x40)
self.Write_IIC_Byte(IIC_Data)
self.IIC_Stop()
#开始IIC写数据 -- 这样可以让一组数据发送完成后再关闭IIC,能很大程度提速
def Begin_IIC_Data(self):
self.IIC_Start()
self.Write_IIC_Byte(0x78)
self.Write_IIC_Byte(0x40)
myoled.py
from myIIC import IIC
I2C = IIC
BMP1 = [0x00, 0x80, 0x60, 0xF8, 0x07, 0x40, 0x20, 0x18, 0x0F, 0x08, 0xC8, 0x08, 0x08, 0x28, 0x18, 0x00,
0x01, 0x00, 0x00, 0xFF, 0x00, 0x10, 0x0C, 0x03, 0x40, 0x80, 0x7F, 0x00, 0x01, 0x06, 0x18, 0x00,
0x10, 0x10, 0xF0, 0x1F, 0x10, 0xF0, 0x00, 0x80, 0x82, 0x82, 0xE2, 0x92, 0x8A, 0x86, 0x80, 0x00,
0x40, 0x22, 0x15, 0x08, 0x16, 0x61, 0x00, 0x00, 0x40, 0x80, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00]
class OLED(object):
def __init__(self):
self.i2c = I2C(sda=21, scl=22)
def OLED_Init(self):
self.i2c.Write_IIC_Command(0xae) # 关显示
self.i2c.Write_IIC_Command(0xd5) # 设置显示时钟分频率、振荡器频率
self.i2c.Write_IIC_Command(0x80) # A[ty77:0]: 分频频率1到16,A[7:4]频率
self.i2c.Write_IIC_Command(0xa8) # duty设置
self.i2c.Write_IIC_Command(0x3f) # duty = 1 / 64
self.i2c.Write_IIC_Command(0xd3) # 显示偏移
self.i2c.Write_IIC_Command(0x00) # 不偏移
self.i2c.Write_IIC_Command(0x40) # 起始行40~7F
self.i2c.Write_IIC_Command(0x8d) # 升压允许
self.i2c.Write_IIC_Command(0x14) #
self.i2c.Write_IIC_Command(0x20) # 设置内存地址模式
self.i2c.Write_IIC_Command(0x02) # 00水平地址模式,01垂直模式,02页地址模式,
self.i2c.Write_IIC_Command(0xc8) # 行扫描顺序:从上到下c8 // 上下颠倒c0
self.i2c.Write_IIC_Command(0xa1) # 列扫描顺序:从左到右a1 // 左右翻转a0
self.i2c.Write_IIC_Command(0xda) #
self.i2c.Write_IIC_Command(0x12) #
self.i2c.Write_IIC_Command(0x81) # 微调对比度, 本指令的0x81不要改动,改下面的值
self.i2c.Write_IIC_Command(0xcf) # 微调对比度的值,可设置范围0x00~0xff
self.i2c.Write_IIC_Command(0xd9) #
self.i2c.Write_IIC_Command(0xf1) #
self.i2c.Write_IIC_Command(0xdb) #
self.i2c.Write_IIC_Command(0x40) #
self.i2c.Write_IIC_Command(0xaf) # 开显示
#设置起始点坐标
def OLED_SetPos(self, x, y):
self.i2c.IIC_Start()
self.i2c.Write_IIC_Byte(0x78)
self.i2c.Write_IIC_Byte(0x00)
self.i2c.Write_IIC_Byte(0xb0 + y)
self.i2c.Write_IIC_Byte(((x & 0xf0) >> 4) | 0x10)
self.i2c.Write_IIC_Byte((x & 0x0f)) # | 0x01)
self.i2c.IIC_Stop()
#显示16*16中文
def Show_16(self, x, y, N):
adder = 32 * N
self.OLED_SetPos(x, y)
self.i2c.Begin_IIC_Data()
for wm in range(0, 16):
self.i2c.Write_IIC_Byte(BMP1[adder])
adder += 1
self.i2c.IIC_Stop()
self.OLED_SetPos(x, y + 1)
self.i2c.Begin_IIC_Data()
for wm in range(0, 16):
self.i2c.Write_IIC_Byte(BMP1[adder])
adder += 1
self.i2c.IIC_Stop()
#刷屏
def Fill_Screen(self, fill_Data):
for m in range(0, 8):
self.i2c.Write_IIC_Command(0xb0 + m) # page0-page1
self.i2c.Write_IIC_Command(0x00) # low column start address
self.i2c.Write_IIC_Command(0x10) # high column start address
self.i2c.Begin_IIC_Data() #
for n in range(0, 128):
self.i2c.Write_IIC_Byte(fill_Data) #
self.i2c.IIC_Stop() #