【方法】Ilitek ILI9325、ILI9328、ILI9341 LCD TFT彩屏利用Memory Read指令讀取屏幕上顯示的內容

網上很多彩屏例程都通過0號命令(有時也稱爲0號寄存器)讀取彩屏的ID號,以此來判斷彩屏的芯片型號,然而ILI9341芯片的0號命令是一個空操作(No Operation),無法得到器件ID。


4號命令和0xda~0xdc命令雖然是讀取ID的命令,但是讀出來的ID全都是0。這會不會是STM32 FSMC的時序配置問題?或者STM32的FSMC根本就不支持這款液晶的讀操作?到底是STM32的時序問題,還是芯片的器件ID本來就爲0?
通過Memory Read(0x2e)命令可以發現,即使把FSMC的時序值配置爲最小值,STM32也能通過FSMC正確讀取到屏幕上顯示的像素點的顏色值,這說明FSMC的讀時序配置沒有問題,可以產生正確的讀時序。是這款液晶的器件ID本來就爲0。
此外,Memory Read命令還可以用來實現屏幕截圖,將屏幕上顯示的內容以位圖的格式保存到存儲器中。

在下面的程序中,我們先將圖片顯示到屏幕上,然後將屏幕顯示內容的前120行讀出來,和原來的圖像數據比較,看是否一樣。如果一樣,則說明讀操作沒有問題。

程序下載地址:https://blog.csdn.net/ZLK1214/article/details/107144250

#include <stdio.h>
#include <stm32f1xx.h>
#include <string.h>
#include "common.h"
#include "images.h"
#include "ILI9341.h"
 
#define RGB888TO565(color) ((((color) >> 8) & 0xf800) | (((color) >> 5) & 0x7e0) | (((color) >> 3) & 0x1f))
 
static void ILI9341_GetPixels(uint16_t *pixels, int count)
{
  int i = 0;
  uint16_t data[3];
  uint16_t rgb565[2];
  uint32_t rgb888[2];
  
  ILI9341_CMD = 0x2e;
  ILI9341_DATA; // dummy read
  while (i < count)
  {
    // 讀兩個像素, 每個像素3字節
    // 每字節表示一個分量, 分量在字節中是左對齊的
    data[0] = ILI9341_DATA; // 0xr1g1 (高字節爲第一個像素的紅色分量, 低字節爲第一個像素的綠色分量)
    data[1] = ILI9341_DATA; // 0xb1r2 (高字節爲第一個像素的藍色分量, 低字節爲第二個像素的紅色分量)
    data[2] = ILI9341_DATA; // 0xg2b2 (高字節爲第二個像素的綠色分量, 低字節爲第二個像素的藍色分量)
    
    // 轉換成RGB888
    rgb888[0] = (data[0] << 8) | (data[1] >> 8);
    rgb888[1] = ((data[1] & 0xff) << 16) | data[2];
    //printf("#%06X #%06X => ", rgb888[0], rgb888[1]);
    
    // 再轉換成RGB565
    rgb565[0] = RGB888TO565(rgb888[0]);
    rgb565[1] = RGB888TO565(rgb888[1]);
    //printf("0x%04x 0x%04x\n", rgb565[0], rgb565[1]);
    
    // 保存顏色值
    pixels[i++] = rgb565[0];
    if (i < count)
      pixels[i++] = rgb565[1];
  }
}
 
static void ILI9341_GetPixelsInRect(void *pixels, uint16_t x, uint16_t y, uint16_t width, uint16_t height)
{
  ILI9341_SetRegion(x, y, x + width - 1, y + height - 1);
  ILI9341_GetPixels(pixels, width * height);
}
 
int main(void)
{
  static uint16_t pixels[120][239];
  
  HAL_Init();
  
  clock_init();
  usart_init(115200);
  printf("STM32F103VE FSMC ILI9341\n");
  printf("SystemCoreClock=%u\n", SystemCoreClock);
  
  ILI9341_Init();
  ILI9341_Clear(ILI9341_COLOR_BLUE);
  ILI9341_Enable(1);
  
  ILI9341_DrawImage(image1, 0, 36, 239, 248); // 在屏幕上顯示一張圖片
  ILI9341_GetPixelsInRect(pixels, 0, 36, 239, 120); // 讀取屏幕上的圖像內容
  if (memcmp(pixels, image1, sizeof(pixels)) == 0) // 和原圖比較
    printf("same\n"); // 相同
  else
    printf("different\n"); // 不相同
  
  while (1)
  {
  }
}

程序運行結果爲:

STM32F10STM32F103VE FSMC ILI9341
SystemCoreClock=72000000
same

所以,讀操作沒有問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章