星瞳实验室APP,快速收到回复
  • 我们只解决官方正版的OpenMV的问题(STM32),其他的分支有很多兼容问题,我们无法解决。
  • 如果有产品硬件故障问题,比如无法开机,论坛很难解决。可以直接找售后维修
  • 发帖子之前,请确认看过所有的视频教程,https://singtown.com/learn/ 和所有的上手教程http://book.openmv.cc/
  • 每一个新的提问,单独发一个新帖子
  • 帖子需要目的,你要做什么?
  • 如果涉及代码,需要报错提示全部代码文本,请注意不要贴代码图片
  • 必看:玩转星瞳论坛了解一下图片上传,代码格式等问题。
  • 驱动自己的LCD,帧率很低,SPI速率问题?



    • 0_1633923993604_微信图片_20211011114429.png

      请在这里粘贴代码
      ## OpenMV 驱动自己的LCD屏
      # 驱动IC ILI9341
      # 分辨率 240*240 QVGA 1.54寸
      import time
      from pyb import Pin, SPI
      
      # IO接线:
      # SDO/MISO  ---> P1(MISO)   		如果不读LCD颜色,可不接
      # LED       ---> P6 (背光控制) 		可直接 接VCC,开机亮屏
      # SCK       ---> P2(SCLK)			SCLK 时钟线
      # SDI/MOSI  ---> P0(MOSI)			SDA 数据线
      # DO/RS     ---> P8					数据命令选择线
      # RESET     ---> P7					复位线
      # CS        ---> P5					片选线
      # GND       ---> GND
      # VCC       ---> 3.3V
      
      cs  = Pin("P5", Pin.OUT_OD)
      rst = Pin("P7", Pin.OUT_PP)
      rs  = Pin("P8", Pin.OUT_PP)
      bl  = Pin("P6", Pin.OUT_PP)     # 背光控制
      
      # 定义横屏/竖屏
      USE_HORIZONTAL  = True         # 定义横屏
      IMAGE_INVER     = True         # 旋转180°
      
      # TFT resolution 240*320
      X_MIN_PIXEL = 0
      Y_MIN_PIXEL = 0
      if USE_HORIZONTAL:
          X_MAX_PIXEL = 240               # 定义屏幕宽度
          Y_MAX_PIXEL = 240               # 定义屏幕高度
      else:
          X_MAX_PIXEL = 240               # 定义屏幕宽度
          Y_MAX_PIXEL = 240               # 定义屏幕高度
      
      # 常用颜色表 						#可去除
      RED     = 0XF800
      GREEN   = 0X07E0
      BLUE    = 0X001F
      BLACK   = 0X0000
      YELLOW  = 0XFFE0
      WHITE   = 0XFFFF
      
      CYAN    = 0X07FF
      BRIGHT_RED = 0XF810
      GRAY1   = 0X8410
      GRAY2   = 0X4208
      
      # OpenMV  SPI2 总线  8位数据模式
      spi = SPI(2, SPI.MASTER,baudrate=48000000,prescaler=1,polarity=0, phase=0,bits=8,firstbit=SPI.MSB)
      
      # SPI 写命令
      def write_command_byte(c):
          cs.low()
          rs.low()
          spi.send(c)
          cs.high()
      
      # SPI 写数据
      def write_data_byte(data):
          cs.low()
          rs.high()
          spi.send(data)
          cs.high()
      
      def write_command(c, *data): #命令数据一起写,先写命令 第二个开始为数据位。如果只写一个,则代表不写数据只写命令。
          write_command_byte(c)
          if data:
              for d in data:
                  if d > 0xFF:
                      write_data_byte(d >> 8)
                      write_data_byte(d&0xFF)
                  else:
                      write_data_byte(d)
      
      def write_image(img):
          SetRegion(0, 0, sensor.height()-1 , sensor.width()-1 )
          cs.low()
          rs.high()
          fbuf = bytearray(500)#建立帧缓冲区,对于每个RGB565像素,帧缓冲区都需2字节
          for m in img: 					#把一帧图像的对象取出来,放到帧缓存区中
              fbuf=m
              for i in range(0,sensor.height()):		#每行每行的发送
                  spi.send(fbuf[i]>>8)	#先发第N行的第I个数据的高八位
                  spi.send(fbuf[i]&0xFF)	#再发低八位
      
          cs.high()
      
      def SetXY(xpos, ypos):
          write_command(0x2A, xpos>>8, xpos&0XFF)
          write_command(0x2B, ypos>>8, ypos&0XFF)
          write_command(0x2C)
      
      def SetRegion(xStar, yStar, xEnd, yEnd):
          write_command(0x2A, xStar>>8, xStar&0XFF, xEnd>>8, xEnd&0XFF)
          write_command(0x2B, yStar>>8, yStar&0XFF, yEnd>>8, yEnd&0XFF)
          write_command(0x2C)
      
      # 在指定位置绘制一个点
      def DrawPoint(x, y, Color):
          SetXY(x, y)
          write_data_byte(Color >> 8)
          write_data_byte(Color&0XFF)
      
      def ReadPoint(x, y):
          data = 0
          SetXY(x, y)
          write_data_byte(data)
          return data
      
      def Clear(Color):
          global X_MAX_PIXEL, Y_MAX_PIXEL
          SetRegion(0, 0, X_MAX_PIXEL-1 , Y_MAX_PIXEL-1 )
          #cs.low()
          #rs.high()
          for i in range(0, Y_MAX_PIXEL):
              for m in range(0, X_MAX_PIXEL):
                  write_data_byte(Color >> 8)
                  write_data_byte(Color&0xFF)
      
      def LCDinit():
          SetRegion(0, 0, X_MAX_PIXEL-1 , Y_MAX_PIXEL-1 )
          rst.low()
          time.sleep_ms(100)
          rst.high()
          time.sleep_ms(100)
          bl.high()   # 拉背光
          write_command(0x11)
          time.sleep_ms(120)
      
          # Memory Data Access Control
          if USE_HORIZONTAL:      # //C8   //48 68竖屏//28 E8 横屏
              if IMAGE_INVER:
                  write_command(0x36, 0x00)   # 从右到左 e8/68
              else:
                  write_command(0x36, 0xC0)   # 从左到右 28
          else:
              if IMAGE_INVER:
                  write_command(0x36, 0x70)   # 从下到上刷
              else:
                  write_command(0x36, 0xA0)   # 从上到下刷
      
          write_command(0x3A,0x05)
      
          write_command(0xB2, 0x0C, 0x0C, 0x00, 0x33, 0x33)
      
          write_command(0xB7, 0x35)
      
          write_command(0xBB, 0x32)
      
          write_command(0xC2,0x01)
      
          write_command(0xc3,0x15)
      
          write_command(0xc4,0x20)
      
          write_command(0xC6,0x05)
      
          write_command(0xD0,0xA4,0xA1)
      
          write_command(0xE0,0xD0,0x08,0x0E,0x09,0x09,0x05,0x31,0x33,0x48,0x17,0x14,0x15,0x31,0x34)
      
          write_command(0xE1,0xD0,0x08,0x0E,0x09,0x09,0x15,0x31,0x33,0x48,0x17,0x14,0x15,0x31,0x34)
          # Interface Pixel Format
      
      
          write_command(0x21)
      
          # Display On
          write_command(0x29)
          #write_command(0x2C)
      
      
      def LCDDisplay(img):
          #write_command(0x2C)
          write_image(img)
      
      
      
      import sensor, image, cpufreq, time
      sensor.reset() # Initialize the camera sensor.
      sensor.set_vflip(True)
      sensor.set_pixformat(sensor.RGB565) # or sensor.GRAYSCALE
      sensor.set_framesize(sensor.QVGA) # Special 128x160 framesize for LCD Shield.
      cpufreq.set_frequency(480)
      spi.init(SPI.MASTER,prescaler=2)
      LCDinit() # Initialize the lcd screen.
      Clear(WHITE)
      clock = time.clock()
      print(spi)
      while(True):
      
          clock.tick()
          #sensor.snapshot()
          #sensor.alloc_extra_fb(sensor.width(),sensor.height(),20000)
          LCDDisplay(sensor.snapshot()) # Take a picture and display the image.
          #print(sensor.snapshot())
          #print("帧率 : ",clock.fps())
      
      
      
      


    • 一方面是SPI速度,代码也有问题。按行发送会慢,而且可能还有复制。

      参考这个:
      https://book.openmv.cc/example/02-Board-Control/spi-control.html



    • 0_1634014718158_4daa3a2c82115aca9df4d0585935202.jpg
      我尝试了一下使用您发的例程中直接将图片数据传入SPI.send(),帧率确实流畅了,但是屏幕变成了花屏,画面发生变化的屏幕也会发生变化,说明确实是有一定的数据传输过来了,请指教一下



    • 这里是代码

      ## OpenMV 驱动自己的LCD屏
      # 驱动IC ST7789
      # 分辨率 240*240 QVGA 1.54寸
      import time
      from pyb import Pin, SPI
      
      # IO接线:
      # SDO/MISO  ---> P1(MISO)   		如果不读LCD颜色,可不接
      # LED       ---> P6 (背光控制) 		可直接 接VCC,开机亮屏
      # SCK       ---> P2(SCLK)			SCLK 时钟线
      # SDI/MOSI  ---> P0(MOSI)			SDA 数据线
      # DO/RS     ---> P8					数据命令选择线
      # RESET     ---> P7					复位线
      # CS        ---> P5					片选线
      # GND       ---> GND
      # VCC       ---> 3.3V
      
      cs  = Pin("P5", Pin.OUT_OD)
      rst = Pin("P7", Pin.OUT_PP)
      rs  = Pin("P8", Pin.OUT_PP)
      bl  = Pin("P6", Pin.OUT_PP)     # 背光控制
      
      # 定义横屏/竖屏
      USE_HORIZONTAL  = True         # 定义横屏
      IMAGE_INVER     = True         # 旋转180°
      
      # TFT resolution 240*320
      X_MIN_PIXEL = 0
      Y_MIN_PIXEL = 0
      if USE_HORIZONTAL:
          X_MAX_PIXEL = 240               # 定义屏幕宽度
          Y_MAX_PIXEL = 240               # 定义屏幕高度
      else:
          X_MAX_PIXEL = 240               # 定义屏幕宽度
          Y_MAX_PIXEL = 240               # 定义屏幕高度
      
      # 常用颜色表 						#可去除
      RED     = 0XF800
      GREEN   = 0X07E0
      BLUE    = 0X001F
      BLACK   = 0X0000
      YELLOW  = 0XFFE0
      WHITE   = 0XFFFF
      
      CYAN    = 0X07FF
      BRIGHT_RED = 0XF810
      GRAY1   = 0X8410
      GRAY2   = 0X4208
      
      # OpenMV  SPI2 总线  8位数据模式
      spi = SPI(2, SPI.MASTER, polarity=0, phase=0)
      
      # SPI 写命令
      def write_command_byte(c):
          cs.low()
          rs.low()
          spi.send(c)
          cs.high()
      
      # SPI 写数据
      def write_data_byte(data):
          cs.low()
          rs.high()
          spi.send(data)
          cs.high()
      
      def write_command(c, *data): #命令数据一起写,先写命令 第二个开始为数据位。如果只写一个,则代表不写数据只写命令。
          write_command_byte(c)
          if data:
              for d in data:
                  if d > 0xFF:
                      write_data_byte(d >> 8)
                      write_data_byte(d&0xFF)
                  else:
                      write_data_byte(d)
      
      def write_image(img):
          SetRegion(0, 0, sensor.height()-1 , sensor.width()-1 )
          cs.low()
          rs.high()
          fbuf = bytearray(500)#建立帧缓冲区,对于每个RGB565像素,帧缓冲区都需2字节
          fbuf=img.bytearray()
          spi.send(fbuf)
          for m in img: 					#把一帧图像的对象取出来,放到帧缓存区中
              fbuf=m
              for i in range(0,sensor.height()):		#每行每行的发送
                  spi.send(fbuf[i]>>8)	#先发第N行的第I个数据的高八位
                  spi.send(fbuf[i]&0xFF)	#再发低八位
          cs.high()
      
      def SetXY(xpos, ypos):
          write_command(0x2A, xpos>>8, xpos&0XFF)
          write_command(0x2B, ypos>>8, ypos&0XFF)
          write_command(0x2C)
      
      def SetRegion(xStar, yStar, xEnd, yEnd):
          write_command(0x2A, xStar>>8, xStar&0XFF, xEnd>>8, xEnd&0XFF)
          write_command(0x2B, yStar>>8, yStar&0XFF, yEnd>>8, yEnd&0XFF)
          write_command(0x2C)
      
      # 在指定位置绘制一个点
      def DrawPoint(x, y, Color):
          SetXY(x, y)
          write_data_byte(Color >> 8)
          write_data_byte(Color&0XFF)
      
      def ReadPoint(x, y):
          data = 0
          SetXY(x, y)
          write_data_byte(data)
          return data
      
      def Clear(Color):
          global X_MAX_PIXEL, Y_MAX_PIXEL
          SetRegion(0, 0, X_MAX_PIXEL-1 , Y_MAX_PIXEL-1 )
          #cs.low()
          #rs.high()
          for i in range(0, Y_MAX_PIXEL):
              for m in range(0, X_MAX_PIXEL):
                  write_data_byte(Color >> 8)
                  write_data_byte(Color&0xFF)
      
      def LCDinit():
          SetRegion(0, 0, X_MAX_PIXEL-1 , Y_MAX_PIXEL-1 )
          rst.low()
          time.sleep_ms(100)
          rst.high()
          time.sleep_ms(100)
          bl.high()   # 拉背光
          write_command(0x11)
          time.sleep_ms(120)
      
          # Memory Data Access Control
          if USE_HORIZONTAL:      # //C8   //48 68竖屏//28 E8 横屏
              if IMAGE_INVER:
                  write_command(0x36, 0x00)   # 从右到左 e8/68
              else:
                  write_command(0x36, 0xC0)   # 从左到右 28
          else:
              if IMAGE_INVER:
                  write_command(0x36, 0x70)   # 从下到上刷
              else:
                  write_command(0x36, 0xA0)   # 从上到下刷
      
          write_command(0x3A,0x05)
      
          write_command(0xB2, 0x0C, 0x0C, 0x00, 0x33, 0x33)
      
          write_command(0xB7, 0x35)
      
          write_command(0xBB, 0x32)
      
          write_command(0xC2,0x01)
      
          write_command(0xc3,0x15)
      
          write_command(0xc4,0x20)
      
          write_command(0xC6,0x05)
      
          write_command(0xD0,0xA4,0xA1)
      
          write_command(0xE0,0xD0,0x08,0x0E,0x09,0x09,0x05,0x31,0x33,0x48,0x17,0x14,0x15,0x31,0x34)
      
          write_command(0xE1,0xD0,0x08,0x0E,0x09,0x09,0x15,0x31,0x33,0x48,0x17,0x14,0x15,0x31,0x34)
          # Interface Pixel Format
      
      
          write_command(0x21)
      
          # Display On
          write_command(0x29)
          #write_command(0x2C)
      
      
      def LCDDisplay(img):
          #write_command(0x2C)
          write_image(img)
      
      
      
      import sensor, image, cpufreq, time
      sensor.reset() # Initialize the camera sensor.
      sensor.set_vflip(True)
      sensor.set_pixformat(sensor.RGB565) # or sensor.GRAYSCALE
      sensor.set_framesize(sensor.QVGA) # Special 128x160 framesize for LCD Shield.
      cpufreq.set_frequency(480)
      spi.init(SPI.MASTER,prescaler=2)
      LCDinit() # Initialize the lcd screen.
      Clear(WHITE)
      clock = time.clock()
      print(spi)
      while(True):
      
          clock.tick()
          #sensor.snapshot()
          #sensor.alloc_extra_fb(sensor.width(),sensor.height(),20000)
          LCDDisplay(sensor.snapshot()) # Take a picture and display the image.
          #print(sensor.snapshot())
          #print("帧率 : ",clock.fps())
      
      
      
      


    • 这个代码是LCD扩展板的,https://singtown.com/product/636/opeenmv-lcd-shield/

      你的硬件不是配套的LCD扩展板,要自己改里面寄存器的值,这方面肯定是没有教程的。



    • @kidswong999 不是寄存器问题,我感觉是SPI配置的问题,可否指点一下