《ESP32-S3使用指南—MicroPython版 V1.0》第十五章 OLED实验

第十五章 OLED实验


       在本章实验中,我们将通过编写MicroPython驱动程序来实现OLED显示。在开发板上,我们已经预留了OLED模块接口,因此需要准备一个OLED显示模块。我们将一起点亮OLED,并实现ASCII字符的显示。

       15.1 OLED模块简介

       15.2 OLED C模块解析

       15.3 硬件设计

       15.4 软件设计

       15.5 下载验证


        15.1 OLED模块简介

       OLED,即有机发光二极管(Organic Light-Emitting Diode),又称为有机电激光显示(Organic Electroluminesence Display,OLED)。OLED可按发光材料分为两种:小分子OLED和高分子OLED(也可称为PLED)。OLED是一种利用多层有机薄膜结构产生电致发光的器件,它很容易制作,而且只需要低的驱动电压,OLED由于同时具备自发光(不需背光源)、对比度高、厚度薄、视角广、反应速度快、功耗低、柔性好等优异特性,目前主要用于显示领域,OLED在节能照明领域的开发也成为全球趋势。

       本章我们将介绍ALINETEK的OLED显示模块及其使用方法,该模块有以下特点:

       1) 模块有单色和双色两种可选,单色为纯蓝色,而双色则为黄蓝双色(分区域的双色,前16行为黄色,后48行为蓝色,且黄蓝色之间有一行不显示的间隔区)。

       2) 尺寸小,显示尺寸为0.96寸,而模块的尺寸仅为27mm*26mm大小。

       3) 高分辨率,该模块的分辨率为128*64。

       4) 多种接口方式,该模块提供了总共4种接口包括:6800、8080两种并行接口方式、4线SPI接口方式以及IIC接口方式(只需要2根线就可以控制OLED了!)。

       5) 不需要高压,直接接3.3V就可以工作了。

       这里要提醒大家的是,该模块不和5.0V接口兼容,所以请大家在使用的时候一定要小心,别直接接到5V的系统上去,否则可能烧坏模块。以下4种模式通过模块的BS1和BS2设置,BS1和BS2的设置与模块接口模式的关系如表24.1.1所示:


表15.1.1 OLED模块接口方式设置表


       表15.1.1中:“1”代表接VCC,而“0”代表接GND。该模块的外观图如图24.1.1所示:


图15.1.1 正点原子 OLED模块外观图


       正点原子 OLED模块默认设置是:BS1和BS2接VCC,即使用8080并口方式,如果你想要设置为其他模式,则需要在OLED的背面,用烙铁修改BS1和BS2的设置。模块的原理图如图15.1.2所示:


图15.1.2 正点原子 OLED模块原理图


       该模块采用8*2的2.54排针与外部连接,总共有16个管脚,在16条线中,我们只用了15条,有一个是悬空的。15条线中,电源和地线占了2条,还剩下13条信号线。在不同模式下,我们需要的信号线数量是不同的,在8080模式下,需要全部13条,而在IIC模式下,仅需要2条线就够了!这其中有一条是共同的,那就是复位线RST(RES),RST上的低电平,将导致OLED复位,在每次初始化之前,都应该复位一下OLED模块。

       正点原子 OLED模块的控制器是SSD1306,本章,我们将学习如何通过ESP32S3来控制该模块显示字符和数字,本章的实例代码仅支持IIC方式与OLED模块连接,这种方式需对OLED硬件整改,整改流程请参考正点原子提供的OLED手册,在这个手册里面,已经详细介绍IIC模式的硬件设置流程。


        15.2 OLED C模块解析


       15.2.1 C模块解析

       作者将简要介绍正点原子OLED C模块驱动。这个讲解内容会分为几个部分:OLED构造函数、写入数据。OLED C模块驱动可在A盘à6,软件资料à1,软件à2,MicroPython开发工具à01-Windowsà2,正点原子MicroPython驱动àCModules_LibàIIC路径下找到。


       1,OLED构造函数

mp_obj_t oled_make_new(const mp_obj_type_t *type,size_t n_args,size_t n_kw,
const mp_obj_t *all_args )
{
    /* 创建对象的参数 */
    enum
    {
        ARG_iic,
    };
 
    static const mp_arg_t allowed_args[] = {
        { MP_QSTR_iic, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} },
    };
    mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all_kw_array(n_args, n_kw, all_args,
                          MP_ARRAY_SIZE(allowed_args), allowed_args, args);
    
    /* 创建对象 */
    oled_self = m_new_obj(oled_obj_t);
    oled_self->base.type = &oled_type;
    /* 设置对象参数 */
mp_obj_base_t *oled_obj   =
                      (mp_obj_base_t*)MP_OBJ_TO_PTR(args[ARG_iic].u_obj);
 
    if (oled_obj == MP_OBJ_NULL)
    {
        mp_raise_ValueError(MP_ERROR_TEXT("I2C init ???"));
    }
 
    oled_self->iic_obj        = oled_obj;
    /* 初始化OLED */
    oled_init();
    
    return MP_OBJ_FROM_PTR(oled_self);
}

       从上述源代码中可以得知,该构造函数只有一个参数,即传入IIC驱动的控制块。我们可以通过这个控制块调用IIC驱动下的收发函数。然后,我们还创建了一个XL9555对象,用于实例化对象并引用类的方法。最后,调用了oled_init函数来初始化OLED模块。


       2,OLED写时序

/**
 * @brief       oled IIC写数据
 * @param       i2c_num :IIC端口号
 * @param       data    :发送的数据或者命令
 * @param       len     :发送数据的大小
 * @retval      ESP_OK:发送成功;其他:发送失败
 */
esp_err_t oled_write(uint8_t* data, size_t len)
{
    int data_len = 0;
    mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(oled_self->iic_obj);
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)
MP_OBJ_TYPE_GET_SLOT(self->type, protocol);
 
    mp_machine_i2c_buf_t bufs = {
        .len = len,
        .buf = data,
    };
 
data_len = i2c_p->transfer(self,OLED_ADDR,1,
&bufs, MP_MACHINE_I2C_FLAG_STOP);
    
    if (data_len != 0)
    {
        return ESP_OK;
    }
    else
    {
        return ESP_FAIL;
    }
}

       此函数也是通过调用IIC控制块下的收发函数来发送数据和命令。其他函数,如画线、画点等,请参考oled.c/.h文件。


       15.2.2 C模块构造与类的方法


       1,atk_oled类的构造函数

       在 MicroPython 中oled对象的构造函数如下:

class atk_oled.init(iic)
使用示例:
i2c0 = I2C(0, scl = Pin(42), sda = Pin(41), freq = 400000)
oled = atk_oled.init(i2c0)

       该构造函数的参数描述,如下表所示。


表15.1.1 atk_oled.init构造函数参数描述


       返回值:OLED对象。


       2,oled类的方法


       ①:打开OLED背光。

       其函数原型如下:

oled.on()


       ②:关闭OLED背光。

       其函数原型如下:

oled.off()


       ③:OLED清屏。

       其函数原型如下:

oled.clear()


       ④:OLED画点。

       其函数原型如下:

oled.point(x,y,t)

        该函数的参数描述,如下表所示。


表15.1.2 oled.point函数参数描述


       ⑤:OLED填充函数

       其函数原型如下:

oled.fill(x1,y1,x2,y2,dot)

        该函数的参数描述,如下表所示。


表15.1.3 oled.fill函数参数描述


       ⑥:OLED显示单字符

       其函数原型如下:

oled.char(x,y,chr,size,mode)

        该函数的参数描述,如下表所示。


表15.1.4 oled.char函数参数描述


       ⑦:OLED显示数字

       其函数原型如下:

oled.num(x,y,num,len,size)

        该函数的参数描述,如下表所示。


表15.1.5 oled.num函数参数描述


       ⑧:OLED显示字符串

       其函数原型如下:

oled.string(x,y,p,size)

        该函数的参数描述,如下表所示。


表15.1.6 oled.string函数参数描述


       ⑨:更新显存到OLED

       其函数原型如下:

oled.refresh_gram()


        15.3 硬件设计


       1. 例程功能

       本章实验功能简介:使用IIC模式驱动OLED模块,不停的显示ASCII码和码值。LED闪烁,提示程序运行。


       2. 硬件资源


       1)LED灯

              LED-IO1


       2)XL9555

              IIC_INT-IO0(需在P5连接IO0)

              IIC_SDA-IO41

              IIC_SCL-IO42


       3)OLED

              IIC_SCL-IO4

              IIC_SDA-IO5

              OLED_RST-IO0_5(XL9555)


       3. 原理图

       OLED模块的原理图在前面已有详细说明了,这里我们介绍OLED模块与我们开发板的连接,开发板上有一个OLED/CAMERA的接口(P2接口)可以和正点原子OLED模块直接对插(靠左插!),连接如下图所示。


图15.3.1 OLED模块与开发板连接示意图


       我们只需要将OLED模块插上去就好了。实物连接如下图所示。


图15.3.2 OLED模块与开发板连接实物图


        15.4 软件设计


       15.3.1 程序流程图

       程序流程图能帮助我们更好的理解一个工程的功能和实现的过程,对学习和设计工程有很好的主导作用。下面看看本实验的程序流程图:


图15.3.1.1 程序流程图


       15.3.2 程序解析

       本书籍的代码都在main.py脚本下编写的,读者可在光盘资料下找到对应的源码。OLED实验main.py源码如下:

from machine import Pin,I2C
import atk_xl9555 as io_ex
import atk_oled as oled
import time
 
 
"""
 * @brief       程序入口
 * @param       无
 * @retval      无
"""
if __name__ == '__main__':
    
    # 初始化LED并输出高电平
    led = Pin(46,Pin.OUT,value = 1)
    # IIC初始化
    i2c0 = I2C(0, scl = Pin(42), sda = Pin(41), freq = 400000)
    i2c1 = I2C(1, scl = Pin(4), sda = Pin(5), freq = 400000)
# start:以下是使用正点原子OLED模块IIC通讯所必备的设置,
如果使用四线OLED模块,可删除start~end区域的代码
    xl9555 = io_ex.init(i2c0)
    dc = Pin(38,Pin.OUT,value = 0)
 
    # 复位OLED
    xl9555.write_bit(io_ex.OV_RESET,0)
    time.sleep_ms(100)
    xl9555.write_bit(io_ex.OV_RESET,1)
    time.sleep_ms(100)
    # end
    
    # 初始化OLED,默认设置:oled.init(port = 1,sda = 5,scl = 4,freq = 200000)
    display = oled.init(i2c1)
    
    # 显示实验信息
    display.string(0,0,str("ALIENTEK"),24)
    display.string(0,24,str("0.96' OLED TEST"),16)
    display.string(0,40,str("ATOM 2023/09/13"),12)
    display.string(0,52,str("ASCII:"),12)
    display.string(64,52,str("CODE:"),12)
    display.refresh_gram()
    
    t = ' '
    
    while True:
        
        # 显示ASCII字符
        display.char(36,52,t,12,1)
        # 显示ASCII字符的码值
        display.num(94,52,ord(t),3,12)
        # 更新显示到OLED
        display.refresh_gram()
 
        t = chr(ord(t) + 1)
 
        if t > '~':
        
            t = ' '
        
        time.sleep_ms(500)

       main.py主要功能就是在OLED上显示一些实验信息字符,然后开始从空格键开始不停的循环显示ASCII字符集,并显示该字符的ASCII值。最后LED闪烁提示程序正在运行。

       需要注意的是:上述的示例是使用正点原子OLED实现的(SPI模式,需用户修改硬件),如果用户想使用四线OLED,也可以使用上述的代码,需使用杜邦线连接四线的OLED模块。


        15.5 下载验证

       下载代码后,LED不停的闪烁,提示程序已经在运行了。同时OLED模块显示ASCII字符集等信息,如下图所示。


图15.5.1 OLED显示效果


       OLED显示了三种尺寸的字符:24*12(ALIENTEK)、16*8(0.96’ OLED TEST)和12*6(剩下的内容)。说明我们的实验是成功的,实现了三种不同尺寸ASCII字符的显示,在最后一行不停的显示ASCII字符以及其码值。

       通过这一章的学习,我们学会了正点原子OLED模块的使用,在调试代码的时候,又多了一种显示信息的途径,在以后的程序编写中,大家可以好好利用。


请使用浏览器的分享功能分享到微信等