移植IIC 0.96OLED(SSD1306)驱动到MicropPython(esp32)

概述

因为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()  #

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值