搜索
bottom↓
回复: 0

《ESP32-S3使用指南—MicroPython版 V1.0》第三十一章 RGB触摸实验

[复制链接]

出0入234汤圆

发表于 3 小时前 | 显示全部楼层 |阅读模式
2.jpg
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
1.png
3.png

第三十一章 RGB触摸实验


       本章,作者将介绍如何使用ESP32-S3来驱动触摸屏,我们通过外接带触摸屏的LCD模块(比如正点原子RGBLCD模块),来实现触摸屏控制。在本章中,我们将向大家介绍ESP32-S3控制正点原子RGBLCD模块,实现触摸屏驱动(电容触摸),最终实现一个手写板的功能。
       本章分为如下几个小节:
       31.1 Touch C模块解析
       31.2 硬件设计
       31.3 软件设计
       31.4 下载验证

       31.1 Touch C模块解析
       RGB屏相关内容,可参考正点原子提供的《ATK-MD0430R模块用户手册_V1.0》和《ATK-MD0430R模块使用说明_V1.0》,在这两个手册中,已经详细说明了RGB的工作原理及相关参数信息。
       温馨提示:正点原子ATK-MD0430R 模块搭载了GT9147电容式触摸屏IC,我们可通过IIC协议读取显示屏的触摸点。

       31.1.1 C模块解析
       本章的Touch C模块组件可在资料A盘6,软件资料1,软件2,MicroPython开发工具01-Windows2,正点原子MicroPython驱动CModules_LibRGBLCD目录下找到。下面作者将简要介绍正点原子Touch C模块驱动。这个讲解内容会分为几个部分:Touch模块初始化、扫描触摸屏、获取x坐标、获取y坐标和获取触摸状态。

       1,Touch模块初始化模块方法
  1. _m_tp_dev tp_dev =
  2. {{
  3.     tp_init,
  4.     0,
  5.     0,
  6.     0,
  7.     0,
  8.     0,
  9. }};

  10. /**
  11. * @brief       触摸屏初始化
  12. * @param       无
  13. * @retval      0,没有进行校准
  14. *              1,进行过校准
  15. */
  16. uint8_t tp_init(void)
  17. {
  18.     tp_dev.touchtype = 0;                                 /* 默认设置(电阻屏 & 竖屏) */
  19.     tp_dev.touchtype |= ltdc_self->dir & 0X01;           /* 根据LCD判定是横屏还是竖屏 */

  20.     if (ltdc_self->id == 0X4342 || ltdc_self->id == 0X4384)
  21.     {
  22.         gt9xxx_init();
  23.         tp_dev.scan = gt9xxx_scan;                 /* 扫描函数指向GT9147触摸屏扫描 */
  24.         tp_dev.touchtype |= 0X80;                   /* 电容屏 */
  25.         return 0;
  26.     }

  27.     return 1;
  28. }

  29. /**
  30. * @brief       触摸初始化
  31. * @param       无
  32. * @retval      无
  33. */
  34. STATIC mp_obj_t mp_touch_init(void)
  35. {
  36.     tp_dev.init();
  37.     return mp_const_none;
  38. }
  39. STATIC MP_DEFINE_CONST_FUN_OBJ_0(touch_init_obj, mp_touch_init);
复制代码
       在上述源代码中,我们首先初始化tp_dev结构体的成员变量。然后,在tp_init函数中,我们判断RGB显示屏的ID是否为0x4342和0x4384,这两款是RGB屏幕。接着,我们执行触摸IC的初始化操作,并将tp_dev.scan函数指针指向gt9xxx_scan函数,该函数用于扫描触摸,最后,将mp_touch_init函数注册至模块列表当中,使得在MicroPython环境下调用此模块的方法。
       请注意,gt9xxx.c/.h文件与正点原子STM32F429以上开发板提供的触摸IC驱动完全一致,只是将IIC协议通信替换为硬件IIC通信。

       2,扫描触摸屏模块方法
       上述作者提到,RGB显示屏的扫描函数由tp_dev结构体中的tp_dev.scan函数指针指向。因此,如果MicroPython想调用扫描触摸屏方法,可以将tp_dev.scan函数指针注册到模块列表中。如下源代码所示:
  1. /**
  2. * @brief       扫描触摸屏(采用查询方式)
  3. * @param       mode : 电容屏未用到次参数, 为了兼容电阻屏
  4. * @retval      当前触屏状态
  5. *   @arg       0, 触屏无触摸;
  6. *   @arg       1, 触屏有触摸;
  7. */
  8. STATIC mp_obj_t mp_touch_scan(mp_obj_t mode)
  9. {
  10.     int ct_mode = mp_obj_get_int(mode);
  11.     tp_dev.scan(ct_mode);
  12.     return mp_const_none;
  13. }
  14. STATIC MP_DEFINE_CONST_FUN_OBJ_1(touch_scan_obj, mp_touch_scan);
复制代码
       可以看到,此方法需要传入一个形参,用来设置触摸屏的状态,若此入参为0时,则触摸屏并没有触摸,反次,有触摸。

       3,获取x/y坐标模块方法
  1. /**
  2. * @brief       获取X轴坐标
  3. * @param       无
  4. * @retval      无
  5. */
  6. STATIC mp_obj_t mp_touch_get_x(void)
  7. {
  8. return mp_obj_new_bytearray_by_ref(sizeof(uint16_t)
  9. * MP_ARRAY_SIZE(tp_dev.x), tp_dev.x);
  10. }
  11. STATIC MP_DEFINE_CONST_FUN_OBJ_0(touch_get_x_obj, mp_touch_get_x);

  12. /**
  13. * @brief       获取Y轴坐标
  14. * @param       无
  15. * @retval      无
  16. */
  17. STATIC mp_obj_t mp_touch_get_y(void)
  18. {
  19. return mp_obj_new_bytearray_by_ref(sizeof(uint16_t)
  20. * MP_ARRAY_SIZE(tp_dev.y), tp_dev.y);
  21. }
  22. STATIC MP_DEFINE_CONST_FUN_OBJ_0(touch_get_y_obj, mp_touch_get_y);
复制代码
       上述模块方法中,我们使用MicroPython字节数组来存储触摸屏的X和Y轴坐标,然后,把字节数组返回给用户,这样就可以得到当前触摸的X与Y轴坐标了。

       4,获取触摸状态模块方法
  1. /**
  2. * @brief       获取触摸状态
  3. * @param       无
  4. * @retval      无
  5. */
  6. STATIC mp_obj_t mp_touch_get_sta(void)
  7. {
  8.     sta[0] = tp_dev.sta;
  9.    
  10. return mp_obj_new_bytearray_by_ref(sizeof(uint16_t)
  11. *MP_ARRAY_SIZE(sta), sta);
  12. }
  13. STATIC MP_DEFINE_CONST_FUN_OBJ_0(touch_get_sta_obj, mp_touch_get_sta);
复制代码
       同理,触摸状态方法也是利用MicroPython的字节数组来存储触摸状态数值,然后,返回给用户,来判断当前RGB显示屏触摸状态。

       31.1.2 C模块构造与类的方法
       在上小节中,作者已介绍了RGB触摸C模块的方法,下面是MicroPython引用这些模块方法的原型,如下所示:

       ①:初始化触摸驱动
       其方法原型如下:
  1. touch.init()
复制代码
       返回值:无。

       ②:扫描触摸
       其方法原型如下:
  1. touch.scan(0)
复制代码
       返回值:无。

       ③:获取X轴坐标
       其方法原型如下:
  1. touch.get_x()
复制代码
       返回值:X坐标。

       ④:获取Y轴坐标
       其方法原型如下:
  1. touch.get_y()
复制代码
       返回值:Y坐标。

       ⑤:获取触摸状态
       其方法原型如下:
  1. touch.get_sta()
复制代码
       返回值:触摸状态。
       温馨提示:调用触摸模块的方法之前,必须先导入atk_touch模块,后调用此模块的方法,如下是导入模块示例:
  1. import atk_touch as touch
复制代码

       31.2 硬件设计

       1. 例程功能
       本章实验功能简介:经过一系列的初始化之后,进入电容触摸屏测试程序,用户可在画板上绘画字符、线条等,在测试界面的右上角会有一个清空的操作区域(RST),点击这个地方就会将输入全部清除,恢复白板状态。

       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的连接关系,如下图所示:

第三十一章 RGB触摸实验4080.png
图31.2.1 RGB接口与ESP32-S3的连接电路图

       31.3 软件设计

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

第三十一章 RGB触摸实验4221.png
图31.3.1.1 程序流程图

       31.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 atk_touch as touch
  5. import time


  6. # 设置屏幕横竖屏:0为竖屏;1为横屏
  7. atk_dir = 1

  8. if atk_dir == 1:
  9.     LCD_WIDTH  = 800
  10.     LCD_HEIGHT = 480
  11. else:
  12.     LCD_WIDTH  = 480
  13.     LCD_HEIGHT = 800

  14. """
  15. * @brief       清空屏幕并在右上角显示"RST"
  16. * @param       无
  17. * @retval      无
  18. """
  19. def load_draw_dialog():
  20.    
  21.     display.clear(ltdc.WHITE)
  22.     display.string(LCD_WIDTH - 30, 0, 200, 16, 16, "RST", ltdc.BLUE)


  23. """
  24. * @brief       画粗线
  25. * @param       x1,y1: 起点坐标
  26. * @param       x2,y2: 终点坐标
  27. * @param       size : 线条粗细程度
  28. * @param       color: 线的颜色
  29. * @retval      无
  30. """
  31. def lcd_draw_bline(x1,y1,x2,y2,size,color):
  32.    
  33.     t = 0
  34.     xerr = 0
  35.     yerr = 0
  36.     delta_x = 0
  37.     delta_y = 0
  38.     distance = 0
  39.     incx = 0
  40.     incy = 0
  41.     row = 0
  42.     col = 0

  43.     delta_x = x2 - x1                       # 计算坐标增量
  44.     delta_y = y2 - y1
  45.     row = x1
  46.     col = y1

  47.     if delta_x > 0:
  48.         incx = 1                            # 置单步方向  
  49.     elif delta_x == 0:
  50.         incx = 0                            # 垂直线
  51.     else:
  52.         incx = -1
  53.         delta_x = -delta_x

  54.     if delta_y > 0:
  55.         incy = 1
  56.     elif delta_y == 0:
  57.         incy = 0                            # 水平线
  58.     else:
  59.         incy = -1
  60.         delta_y = -delta_y

  61.     if delta_x > delta_y:
  62.         distance = delta_x;                 # 选取基本增量坐标轴
  63.     else:
  64.         distance = delta_y

  65.     for t in range(0,distance + 1):         # 画线输出
  66.         display.circle(row, col, size, color)   # 画点
  67.         xerr += delta_x
  68.         yerr += delta_y

  69.         if xerr > distance:
  70.             xerr -= distance
  71.             row += incx

  72.         if yerr > distance:
  73.             yerr -= distance
  74.             col += incy

  75. """
  76. * @brief       电容屏测试
  77. * @param       无
  78. * @retval      无
  79. """
  80. def ctp_test():
  81.    
  82.     t = 0
  83.     i = 0
  84.     lastpos = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0]]    #最后一次的数据

  85.     while True:
  86.         
  87.         touch.scan(0)
  88.         
  89.         x_data = touch.get_x()
  90.         y_data = touch.get_y()
  91.         sta_data = touch.get_sta()
  92.         
  93.         x = (x_data[9] << 8) | x_data[8]
  94.         y = (y_data[9] << 8) | y_data[8]
  95.         sta = (sta_data[1] << 8) | sta_data[0]
  96.         
  97.         for t in range(0,5):
  98.             
  99.             if sta & (1 << t):
  100.                
  101.                 if (x < LCD_WIDTH and y < LCD_HEIGHT):
  102.                     
  103.                     if lastpos[t][0] == 0xFFFF:
  104.                         
  105.                         lastpos[t][0] = x
  106.                         lastpos[t][1] = y
  107.                     
  108.                     lcd_draw_bline(lastpos[t][0], lastpos[t][1],x,y,2,ltdc.RED);
  109.                     lastpos[t][0] = x
  110.                     lastpos[t][1] = y
  111.                     
  112.                     if (x > (LCD_WIDTH - 30) and y < 20):
  113.                         
  114.                         load_draw_dialog()
  115.                 else:
  116.                     lastpos[t][0] = 0xFFFF
  117.                
  118.         time.sleep_ms(5)
  119.         
  120.         i += 1
  121.         
  122.         if (i % 20 == 0):
  123.             
  124.             led_state = led.value()
  125.             led.value(not led_state)

  126. """
  127. * @brief       程序入口
  128. * @param       无
  129. * @retval      无
  130. """
  131. if __name__ == '__main__':
  132.    
  133.     x = 0
  134.     # 初始化LED并输出高电平
  135.     led = Pin(1,Pin.OUT,value = 1)
  136.     # IIC初始化
  137.     i2c0 = I2C(0, scl = Pin(42), sda = Pin(41), freq = 400000)
  138.     # XL9555初始化
  139.     xl9555 = io_ex.init(i2c0)
  140.    
  141.    
  142.     # 初始化RGB
  143.     display = ltdc.init(dir = atk_dir)
  144.     # 打开RGB屏背光
  145.     xl9555.write_bit(io_ex.LCD_BL,1)
  146.     time.sleep_ms(100)
  147.    
  148.     # 复位触摸芯片
  149.     xl9555.write_bit(io_ex.CT_RST,0)
  150.     time.sleep_ms(10)
  151.     xl9555.write_bit(io_ex.CT_RST,1)
  152.     time.sleep_ms(10)
  153.    
  154.     # 初始化触摸驱动
  155.     touch.init()
  156.    
  157.     # 清空屏幕并在右上角显示"RST"
  158.     load_draw_dialog()
  159.    
  160.     while True:
  161.         
  162.         ctp_test()
复制代码
       该示例经过一些列初始化之后,执行ctp_test函数创建白色的画板,用户可在画板上涂鸦,如果xiang 清除画板上的涂鸦,可点击右上角的“RST”按键清除。

       31.4 下载验证
       在代码编译成功之后,我们通过下载代码到开发板上,触摸屏测试如下图所示界面:

第三十一章 RGB触摸实验8251.png
图31.4.1 触摸屏测试界面

       图中,作者在触摸板绘画“ALIENTEK”字符串。按右上角的RST标志,可以清屏。

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

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

本版积分规则

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

GMT+8, 2024-8-29 19:21

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

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