搜索
bottom↓
回复: 0
打印 上一主题 下一主题

《ESP32-S3使用指南—MicroPython版 V1.0》第三十章 RGB显示屏实验

[复制链接]

出0入234汤圆

跳转到指定楼层
1

1)实验平台:正点原子ESP32S3开发板
2)购买链接:https://detail.tmall.com/item.htm?id=768499342659
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-347618-1-1.html
4)正点原子官方B站:https://space.bilibili.com/394620890
5)正点原子手把手教你学ESP32S3快速入门视频教程:https://www.bilibili.com/video/BV1sH4y1W7Tc
6)正点原子FPGA交流群:132780729



第三十章 RGB显示屏实验


       对于那些阅读过MicroPython手册的读者,他们可能已经注意到,该源码库并未提供针对ESP32 RGB显示屏的API接口。为了在MicroPython环境下实现对RGB显示屏的驱动,作者编写了RGB显示屏的C模块扩展组件。该扩展组件的RGB驱动实现代码是参考ESP-IDF源码库来实现的。在本章中,我们将探讨如何在MicroPython环境下驱动RGB显示屏,并实现字符串显示以及颜色的刷新。
       本章分为如下几个小节:
       30.1 RGB C模块解析
       30.2 硬件设计
       30.3 软件设计
       30.4 下载验证

       30.1 RGB C模块解析
       RGB屏相关内容,可参考正点原子提供的《ATK-MD0430R模块用户手册_V1.0》和《ATK-MD0430R模块使用说明_V1.0》,在这两个手册中,已经详细说明了RGB的工作原理及相关参数信息。

       30.1.1 C模块解析
       本章的RGB C模块组件可在资料A盘6,软件资料1,软件2,MicroPython开发工具01-Windows2,正点原子MicroPython驱动CModules_LibRGBLCD目录下找到。下面作者将简要介绍正点原子RGB C模块驱动。这个讲解内容会分为几个部分:RGB构造函数、读取面板ID和RGB初始化。

       1,RGB构造函数
  1. mp_obj_t ltdc_make_new(const mp_obj_type_t *type,size_t n_args,size_t n_kw,
  2. const mp_obj_t *all_args )
  3. {
  4.     /* 创建对象的参数 */
  5.     enum
  6.     {
  7.         ARG_dir,
  8.     };
  9.     /* 创建对象参数的默认值 */
  10.     static const mp_arg_t allowed_args[] = {
  11.         { MP_QSTR_dir, MP_ARG_KW_ONLY        |        MP_ARG_INT, {.u_int = 0} },
  12.     };
  13.     mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
  14. mp_arg_parse_all_kw_array(n_args, n_kw, all_args,
  15.                           MP_ARRAY_SIZE(allowed_args), allowed_args, args);

  16.     /* 创建对象 */
  17.     ltdc_self = m_new_obj(_ltdc_dev);
  18.     ltdc_self->base.type = <dc_type;

  19.     /* 设置对象参数 */
  20.     ltdc_self->dir      = args[ARG_dir].u_int;
  21.    
  22.     if (ltdc_self->dir != 1 && ltdc_self->dir != 0)
  23.     {
  24.         mp_raise_ValueError(MP_ERROR_TEXT("Not horizontal and
  25. vertical screens"));
  26.     }
  27.     /* 初始化ltdc */
  28.     ltdc_init();
  29.     /* 返回RGB对象 */
  30.     return MP_OBJ_FROM_PTR(ltdc_self);
  31. }
复制代码
       在RGB类的构造函数中,我们只需要传入一个参数即可创建RGB对象。这个参数用于设置RGB屏幕的方向。当dir参数的值为0时,屏幕方向为竖屏模式;否则,屏幕方向为横屏模式。最后,我们需要初始化LCD,并返回创建的RGB对象。

       2,读取面板ID函数
       读取面板ID是为了兼容多款RGB显示屏,设计代码如下所示:
  1. /**
  2. * @brief       LTDC读取面板ID
  3. * @note        利用LCD RGB线的最高位(R7,G7,B7)来识别面板ID
  4. *              PG6 = R7(M0); PI2 = G7(M1); PI7 = B7(M2);
  5. *              M2:M1:M0
  6. *              0 :0 :0     4.3 寸480*272  RGB屏,ID = 0X4342
  7. *              1 :0 :0     4.3 寸800*480  RGB屏,ID = 0X4384
  8. * @param       无
  9. * @retval      0, 非法;
  10. *              其他, LCD ID
  11. */
  12. uint16_t ltdc_panelid_read(void)
  13. {
  14.     uint8_t idx = 0;
  15.     gpio_config_t gpio_init_struct;

  16.     gpio_init_struct.intr_type = GPIO_INTR_DISABLE;         /* 失能引脚中断 */
  17.     gpio_init_struct.mode = GPIO_MODE_INPUT;                /* 输入输出模式 */
  18.     gpio_init_struct.pull_up_en = GPIO_PULLUP_ENABLE;       /* 使能上拉 */
  19.     gpio_init_struct.pull_down_en = GPIO_PULLDOWN_DISABLE;  /* 失能下拉 */
  20.     gpio_init_struct.pin_bit_mask = 1ull << GPIO_NUM_6;
  21.     gpio_config(&gpio_init_struct);                         /* 配置GPIO */

  22.     gpio_init_struct.pin_bit_mask = 1ull << GPIO_NUM_14 || 1ull << GPIO_NUM_18;
  23.     gpio_config(&gpio_init_struct);                         /* 配置GPIO */

  24.     idx = (uint8_t)gpio_get_level(GPIO_NUM_14);             /* 读取M0 */
  25.     idx|= (uint8_t)gpio_get_level(GPIO_NUM_18) << 1;        /* 读取M1 */
  26.     idx|= (uint8_t)gpio_get_level(GPIO_NUM_6) << 2;         /* 读取M2 */

  27.     switch (idx)
  28.     {
  29.         case 0 :
  30.             return 0X4342;           /*  4.3寸屏, 480*272分辨率 */
  31.         case 4 :
  32.             return 0X4384;            /*  4.3寸屏, 800*480分辨率 */
  33.         default :
  34.             return 0;
  35.     }
  36. }
复制代码
       上述源代码通过读取M0~M2的电平来确定面板的ID,并据此执行相应的代码。由此可见,正点原子ESP32-S3开发板仅支持两种RGB屏幕,它们的ID分别为0x4342和0x4384。

       3,RGB初始化函数
  1. /**
  2. * @brief       初始化ltdc
  3. * @param       无
  4. * @retval      无
  5. */
  6. void ltdc_init(void)
  7. {
  8.     panel_handle = NULL;                        /* 初始化XL9555 */
  9.     ltdc_self->id = ltdc_panelid_read();        /* 读取LCD面板ID */

  10.     if (ltdc_self->id == 0X4342)                   /* 4.3寸屏, 480*272 RGB屏 */
  11.     {
  12.         ltdc_self->pwidth = 480;                   /* 面板宽度,单位:像素 */
  13.         ltdc_self->pheight = 272;                  /* 面板高度,单位:像素 */
  14.         ltdc_self->hsw = 1;                        /* 水平同步宽度 */
  15.         ltdc_self->vsw = 1;                        /* 垂直同步宽度 */
  16.         ltdc_self->hbp = 40;                       /* 水平后廊 */
  17.         ltdc_self->vbp = 8;                        /* 垂直后廊 */
  18.         ltdc_self->hfp = 5;                        /* 水平前廊 */
  19.         ltdc_self->vfp = 8;                        /* 垂直前廊 */
  20.         ltdc_self->pclk_hz = 9 * 1000 * 1000;      /* 设置像素时钟 9Mhz */
  21.     }
  22.     else if (ltdc_self->id == 0X4384)
  23.     {
  24.         ltdc_self->pwidth = 800;                   /* 面板宽度,单位:像素 */
  25.         ltdc_self->pheight = 480;                  /* 面板高度,单位:像素 */
  26.         ltdc_self->hbp = 88;                       /* 水平后廊 */
  27.         ltdc_self->hfp = 40;                       /* 水平前廊 */
  28.         ltdc_self->hsw = 48;                       /* 水平同步宽度 */
  29.         ltdc_self->vbp = 32;                       /* 垂直后廊 */
  30.         ltdc_self->vfp = 13;                       /* 垂直前廊 */
  31.         ltdc_self->vsw = 3;                        /* 垂直同步宽度 */
  32.         ltdc_self->pclk_hz = 15 * 1000 * 1000;     /* 设置像素时钟 15Mhz */
  33.     }

  34.     /* 配置RGB参数 */
  35.     esp_lcd_rgb_panel_config_t panel_config = {
  36.         .data_width = 16,              /* RGB565处于并行模式,因此宽度为16位 */
  37.         .psram_trans_align = 64,
  38.         .clk_src = LCD_CLK_SRC_PLL160M,
  39.         .disp_gpio_num = GPIO_NUM_NC,
  40.         .pclk_gpio_num = GPIO_LCD_PCLK,
  41.         .de_gpio_num = GPIO_LCD_DE,
  42.         .data_gpio_nums = {
  43.             GPIO_LCD_B3, GPIO_LCD_B4, GPIO_LCD_B5, GPIO_LCD_B6, GPIO_LCD_B7,
  44.             GPIO_LCD_G2, GPIO_LCD_G3, GPIO_LCD_G4, GPIO_LCD_G5,
  45. GPIO_LCD_G6, GPIO_LCD_G7,
  46.             GPIO_LCD_R3, GPIO_LCD_R4, GPIO_LCD_R5, GPIO_LCD_R6, GPIO_LCD_R7,
  47.         },
  48.         .timings = {
  49.             .pclk_hz = ltdc_self->pclk_hz,         /* 像素时钟频率 */
  50.             .h_res = ltdc_self->pwidth,            /* 水平分辨率,即一行中的像素数 */
  51.             .v_res = ltdc_self->pheight,           /* 垂直分辨率,即帧中的行数 */
  52. /* 水平后廊,hsync和行活动数据开始之间的PCLK数 */
  53.             .hsync_back_porch = ltdc_self->hbp,   
  54. /* 水平前廊,活动数据结束和下一个hsync之间的PCLK数 */
  55.             .hsync_front_porch = ltdc_self->hfp,   
  56.             .hsync_pulse_width = ltdc_self->vsw,   /* 垂直同步宽度,单位:行数 */
  57. /* 垂直后廊,vsync和帧开始之间的无效行数 */
  58.             .vsync_back_porch = ltdc_self->vbp,   
  59. /* 垂直前廊,帧结束和下一个vsync之间的无效行数 */
  60.             .vsync_front_porch = ltdc_self->vfp,   
  61.             .vsync_pulse_width = ltdc_self->hsw,/* 水平同步宽度,单位:PCLK周期 */
  62.             .flags.pclk_active_neg = true,      /* RGB数据在下降沿计时 */
  63.         },
  64.         .flags.fb_in_psram = true,              /* 在PSRAM中分配帧缓冲区 */
  65.     };
  66.     /* 创建RGB对象 */
  67.     ESP_ERROR_CHECK(esp_lcd_new_rgb_panel(&panel_config, &panel_handle));
  68.     /* 复位RGB屏 */
  69.     ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle));
  70.     /* 初始化RGB */
  71.     ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle));
  72.     ltdc_display_dir(ltdc_self->dir);
  73.     /* 清除屏幕为颜色 */
  74.     ltdc_clear(WHITE);
  75. }
复制代码
       从上述源代码中可以得知,我们首先获取面板的ID号,然后根据该ID号来设置RGB相关的参数,如时钟频率、水平同步宽度等。接着,我们调用ESP-IDF源码库中的RGB API函数来初始化RGB显示屏。最后,复位显示屏并设置屏幕的方向。

       30.1.2 C模块构造与类的方法

       1,RGBLCD类的构造方法
       RGBLCD的构造对象方法如下:
  1. class atk_ltdc.init(dir)
  2. 使用示例:ltdc = atk_ltdc.init(dir)
复制代码
       该构造函数的参数描述,如下表所示。

表30.1.2.1 atk_ltdc.init构造函数参数描述

       返回值: RGBLCD对象。

       2,RGBLCD类的方法

       ①:清屏方法
       其函数原型如下:
  1. ltdc.clear(color)
复制代码
       该方法的参数描述,如下表所示。

表30.1.2.2 ltdc.clear方法参数描述

       返回值:无。

       ②:画点
       其方法原型如下:
  1. ltdc.pixel(x,y,color)
复制代码
       该方法的参数描述,如下表所示。

表30.1.2.3 ltdc.pixel方法参数描述

       返回值:无。

       ③:画一个矩形
       其方法原型如下:
  1. ltdc.line(x1,y1,x2,y2,color)
复制代码
       该方法的参数描述,如下表所示。

表30.1.2.4 ltdc.line方法参数描述

       返回值:无。

       ④:画一个矩形
       其方法原型如下:
  1. ltdc.rectangle(x0,y0,x1,y1,color)
复制代码
       该方法的参数描述,如下表所示。

表30.1.2.5 ltdc.rectangle方法参数描述

       ⑤:画圆
       其方法原型如下:
  1. ltdc.circle(x0,y0,r,color)
复制代码
       该方法的参数描述,如下表所示。

表30.1.2.6 ltdc.circle方法参数描述

       返回值:无。

       ⑥:显示字符
       其方法原型如下:
  1. ltdc.char(x,y,chr,size,mode,color)
复制代码
       该方法的参数描述,如下表所示。

表30.1.2.7 ltdc.char方法参数描述

       返回值:无。

       ⑦:显示len个数字
       其方法原型如下:
  1. ltdc.num(x,y,num,len,size,color)
复制代码
       该方法的参数描述,如下表所示。

表30.1.2.8 ltdc.num方法参数描述

       ⑧:显示字符串
       其方法原型如下:
  1. ltdc.string(x,y,width,heught,size,p,color)
复制代码
       该方法的参数描述,如下表所示。

表30.1.2.9 ltdc.string方法参数描述

       返回值:无。

       ⑨:填充区域
       其方法原型如下:
  1. ltdc.fill(sx,sy,ex,ey,color)
复制代码
       该方法的参数描述,如下表所示。

表30.1.2.10 ltdc.fill方法参数描述

       返回值:无。

       ⑩,RGB888转RGB565。
       其方法原型如下:
  1. atk_ltdc.color565(r,g,b)
复制代码
       该方法的参数描述,如下表所示。

表30.1.2.11 atk_ltdc.color565方法参数描述

       返回值:RGB565颜色数值。
       温馨提示:调用RGB屏对象的方法之前,必须先导入atk_ltdc模块,后调用此对象的方法,如下是导入模块示例:
  1. import atk_ltdc as ltdc
复制代码

       30.2 硬件设计

       1. 例程功能
       本章实验功能简介:本实验利用ESP32-S3开发板的RGB接口来驱动RGB屏,RGBLCD模块的接口在核心板上,通过40P的FPC排线连接RGBLCD模块,实现RGBLCD模块的驱动和显示,下载成功后,按下复位之后,就可以看到RGBLCD模块不停的显示一些信息并不断切换底色。

       2. 硬件资源

       1)LED灯
              LED-IO1

       2)XL9555
              IIC_INT-IO0(需在P5连接IO0)
              IIC_SDA-IO41
              IIC_SCL-IO42

       3)RGBLCD
              LCD_BL-IO1_3(XL9555)
              LCD_DE-IO4
              LCD_VSYNC-NC
              LCD_HSYNC-NC
              LCD_PCLK-IO5
              LCD_R3-IO45
              LCD_R4-IO48
              LCD_R5-IO47
              LCD_R6-IO21
              LCD_R7-IO14
              LCD_G2-IO10
              LCD_G3-IO9
              LCD_G4-IO46
              LCD_G5-IO3
              LCD_G6-IO8
              LCD_G7-IO18
              LCD_B3-IO17
              LCD_B4-IO16
              LCD_B5-IO15
              LCD_B6-IO7
              LCD_B7-IO6

       3. 原理图
       RGB接口与ESP32-S3的连接关系,如下图所示:

图30.2.1 RGB接口与ESP32-S3的连接电路图

       30.3 软件设计

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

图30.3.1.1 程序流程图

       30.3.2 程序解析
       本书籍的代码都在main.py脚本下编写的,读者可在光盘资料下找到对应的源码。RGB实验main.py源码如下:
  1. from machine import Pin,I2C
  2. import atk_xl9555 as io_ex
  3. import atk_ltdc as ltdc
  4. import time


  5. """
  6. * @brief       程序入口
  7. * @param       无
  8. * @retval      无
  9. """
  10. if __name__ == '__main__':
  11.    
  12.     x = 0
  13.     # 初始化LED并输出高电平
  14.     led = Pin(1,Pin.OUT,value = 1)
  15.     # IIC初始化
  16.     i2c0 = I2C(0, scl = Pin(42), sda = Pin(41), freq = 400000)
  17.     # XL9555初始化
  18.     xl9555 = io_ex.init(i2c0)
  19.    
  20.     # 初始化RGB
  21.     display = ltdc.init(dir = 1)
  22.     # 打开RGB屏背光
  23.     xl9555.write_bit(io_ex.LCD_BL,1)
  24.     time.sleep_ms(100)
  25.    
  26.     while True:
  27.         
  28.         #创建字典
  29.         seasondict = {
  30.         0: ltdc.BLACK,
  31.         1: ltdc.BLUE,
  32.         2: ltdc.RED,
  33.         3: ltdc.GREEN,
  34.         4: ltdc.CYAN,
  35.         5: ltdc.MAGENTA,
  36.         6: ltdc.YELLOW}

  37.         #刷新颜色
  38.         display.clear(seasondict[x])
  39.         #显示字体
  40.         display.string(0, 5, 240, 32, 32, "ESP32S3",ltdc.RED)
  41.         display.string(0, 34, 240, 16, 16, "RGB Test",ltdc.RED)
  42.         display.string(0, 50, 240, 16, 16, "ATOM@ALIENTEK",ltdc.RED)
  43.         x += 1
  44.         
  45.         if x == 7:
  46.             x = 0
  47.         
  48.         led_state = led.value()
  49.         led.value(not led_state)
  50.         time.sleep(1)
复制代码
       该示例首先实例化IIC、XL9555和RGB对象,并打开RGB背光。随后,系统不停地切换背景颜色,每1秒切换一次。同时,LED也会不停地闪烁,以指示程序正在运行。

       30.4 下载验证
       程序下载到开发板后,可以看到LED不停的闪烁,提示程序已经在运行了。同时,可以看到RGBLCD模块的显示如下图所示:

图30.4.1 RGBLCD显示效果图

       我们可以看到屏幕的背景是不停切换的,同时 LED不停的闪烁,证明我们的代码被正确的执行了,达到了我们预期的目的。

阿莫论坛20周年了!感谢大家的支持与爱护!!

该献的血还是要献的。你不献他不献。难道让我去献? --- 出自坛友:lovejp1981
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-29 13:01

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表