Hi3861的micropython移植之OLED 原创 精华

再见南丫岛
发布于 2022-5-23 09:50
浏览
1收藏

1、准备知识

本文使用的OLED为0.96寸12864的显示屏。驱动为SSD1306。
Hi3861的micropython移植之OLED-鸿蒙开发者社区
在micropython下,有两种驱动OLED显示的方法,1)传统的思路,移植其他的MCU的驱动,然后封装python的函数。2)使用framebuf类,然后OLED的驱动代码使用python便携。这两种方法都会做相应的介绍。本篇文档,会先介绍传统的思路。

2、显示内容准备

驱动自己带一些ASCII等字符,有些时候还需要自己制作,这时候就会用上PC2LCD2002这个软件。该软件的使用,这里不过多的介绍。适配驱动的软件配置方法如下。
Hi3861的micropython移植之OLED-鸿蒙开发者社区

3、驱动的移植

需求移植的驱动包括下面的几个文件。
Hi3861的micropython移植之OLED-鸿蒙开发者社区

static uint32_t ssd1306_SendData(uint8_t* data, size_t size)
{
    int res = IoTI2cWrite(SSD1306_I2C_IDX, SSD1306_I2C_ADDR, data, size);
    HAL_Delayus();
    return res;
}

static uint32_t ssd1306_WiteByte(uint8_t regAddr, uint8_t byte)
{
    uint8_t buffer[] = {regAddr, byte};
    int res = ssd1306_SendData(buffer, sizeof(buffer));
    if(res != 0)
    {
        DEBUG_printf("ssd1306_SendData error.%08x\r\n",res);
    }
}

// Send a byte to the command register
void ssd1306_WriteCommand(uint8_t byte) {
    ssd1306_WiteByte(SSD1306_CTRL_CMD, byte);
}

// Send data
void ssd1306_WriteData(uint8_t* buffer, size_t buff_size) {
    uint8_t data[SSD1306_WIDTH * 2] = {0};
    for (size_t i = 0; i < buff_size; i++) {
        data[i*2] = SSD1306_CTRL_DATA | SSD1306_MASK_CONT;
        data[i*2+1] = buffer[i];
    }
    data[(buff_size - 1) * 2] = SSD1306_CTRL_DATA;
    ssd1306_SendData(data, sizeof(data));
}

针对提供给python的接口,跟之前移植micropython介绍的方法也基本移植,相对就比较容易了。

STATIC const mp_rom_map_elem_t gboard_oled_locals_dict_table[] = {
    // instance methods
    { MP_ROM_QSTR(MP_QSTR_fill),  MP_ROM_PTR(&gboard_oled_fill_obj)  },
    { MP_ROM_QSTR(MP_QSTR_line),  MP_ROM_PTR(&machine_lcd_line_obj)  },
    { MP_ROM_QSTR(MP_QSTR_rectangle), MP_ROM_PTR(&machine_lcd_rectangle_obj) },
    { MP_ROM_QSTR(MP_QSTR_fill_rectangle), MP_ROM_PTR(&machine_lcd_fill_rectangle_obj) },
    { MP_ROM_QSTR(MP_QSTR_circle), MP_ROM_PTR(&machine_lcd_circle_obj) }, 
    { MP_ROM_QSTR(MP_QSTR_fill_circle), MP_ROM_PTR(&machine_lcd_fill_circle_obj) }, 
    { MP_ROM_QSTR(MP_QSTR_text),  MP_ROM_PTR(&machine_lcd_text_obj)  },
    { MP_ROM_QSTR(MP_QSTR_bmp), MP_ROM_PTR(&machine_lcd_show_bmp_obj) }, 

    { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&gboard_oled_show_obj) }, 
    /*
    { MP_ROM_QSTR(MP_QSTR_light), MP_ROM_PTR(&machine_lcd_light_obj) },
    { MP_ROM_QSTR(MP_QSTR_set_color), MP_ROM_PTR(&machine_lcd_set_color_obj) }, 
    { MP_ROM_QSTR(MP_QSTR_show_image), MP_ROM_PTR(&machine_lcd_show_image_obj) }, 
    */
    // color
    
    { MP_ROM_QSTR(MP_QSTR_WHITE), MP_ROM_INT(White) },
    { MP_ROM_QSTR(MP_QSTR_BLACK), MP_ROM_INT(Black) },
}

此处介绍一个函数的移植,fill_rectangle。

STATIC mp_obj_t machine_lcd_fill_rectangle(size_t n_args, const mp_obj_t *args) {
    
    int x1 = mp_obj_get_int(args[1]);
    int y1 = mp_obj_get_int(args[2]);
    int x2 = mp_obj_get_int(args[3]);
    int y2 = mp_obj_get_int(args[4]);
    mp_int_t col = mp_obj_get_int(args[5]);

    error_check((x1 >= 0 && x1 <= MAX_CO) && (y1 >= 0 && y1 <= MAX_CO) , "The min/max X/Y coordinates is 0/239");
    error_check((x2 >= 0 && x2 <= MAX_CO) && (y2 >= 0 && y2 <= MAX_CO) , "The min/max X/Y coordinates is 0/239");

    ssd1306_FillRectangle(x1, y1, x2, y2,col);
    //ssd1306_UpdateScreen();
    return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_lcd_fill_rectangle_obj, 6, 6, machine_lcd_fill_rectangle);

4、Python的使用

from gboard import OLED
import time
lcd = OLED()
lcd.line(1,1,50,50)
lcd.show()
time.sleep(1)
lcd.fill(OLED.BLACK)
lcd.text("hello123",0,30,6)
lcd.show()

5、结束

OLED的移植部分,就先介绍到这里。下一篇文档介绍OLED上使用framebuf的驱动方式,使用起来更加灵活。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
oled驱动.zip 24.47K 39次下载
1
收藏 1
回复
举报
回复
    相关推荐