【解決方案】STM32F429IG單片機採用SDRAM驅動LTDC液晶屏,讀NAND Flash數據時液晶屏閃屏很厲害的解決辦法

LTDC驅動800×480的彩色LCD液晶屏,使用STemWin圖形庫顯示圖片,其中SDRAM用來做顯存。LTDC的頻率爲30MHz。

/* 初始化LTDC */
// 使用外部SRAM作顯存時, 時鐘頻率不能太高
clk.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
clk.PLLSAI.PLLSAIN = 360;
clk.PLLSAI.PLLSAIR = 6;
clk.PLLSAIDivR = RCC_PLLSAIDIVR_2;
HAL_RCCEx_PeriphCLKConfig(&clk);

NAND Flash接在FMC上,開啓FMC的Waitfeature功能。

NAND_HandleTypeDef hnand;
FMC_NAND_PCC_TimingTypeDef timing;

hnand.Instance = FMC_NAND_DEVICE;
hnand.Init.EccComputation = FMC_NAND_ECC_DISABLE;
hnand.Init.ECCPageSize = FMC_NAND_ECC_PAGE_SIZE_2048BYTE;
hnand.Init.MemoryDataWidth = FMC_NAND_PCC_MEM_BUS_WIDTH_8;
hnand.Init.NandBank = FMC_NAND_BANK3;
hnand.Init.TARSetupTime = 0;
hnand.Init.TCLRSetupTime = 0;
hnand.Init.Waitfeature = FMC_NAND_PCC_WAIT_FEATURE_ENABLE;
timing.HiZSetupTime = 0;
timing.HoldSetupTime = 0;
timing.SetupTime = 6;
timing.WaitSetupTime = 3;
HAL_NAND_Init(&hnand, &timing, &timing);

只要讀取NAND Flash,顯示屏就會出現刷新遲緩現象(屏幕紊亂)。

解決方案是,讀NAND Flash時,每發一條指令,都要用delay函數延時一下,這樣LTDC纔有機會讀取SDRAM的數據,避免underrun的錯誤。

#define NANDFLASH3C (*(volatile uint8_t *)0x80010000)
#define NANDFLASH3A (*(volatile uint8_t *)0x80020000)
#define NANDFLASH3 (*(volatile uint8_t *)0x80000000)

static void delay(void)
{
  int i;
  
  for (i = 0; i < 10000; i++);
}

static void read_page(void *buffer, int block, int page)
{
  int i;
  uint32_t addr = block * 64 + page;
  
  NANDFLASH3C = 0x00;
  delay();
  NANDFLASH3A = 0x00;
  delay();
  NANDFLASH3A = 0x00;
  delay();
  NANDFLASH3A = addr & 0xff;
  delay();
  NANDFLASH3A = (addr >> 8) & 0xff;
  delay();
  NANDFLASH3A = (addr >> 16) & 0xff;
  delay();
  NANDFLASH3C = 0x30;
  delay();
  for (i = 0; i < 2048; i++)
  {
    *((uint8_t *)buffer + i) = NANDFLASH3;
    delay();
  }
}

static void read_ecc(void *buffer, int block, int page)
{
  int i;
  uint32_t addr = block * 64 + page;
  uint32_t column = 2048;
  
  NANDFLASH3C = 0x00;
  delay();
  NANDFLASH3A = column & 0xff;
  delay();
  NANDFLASH3A = (column >> 8) & 0xff;
  delay();
  NANDFLASH3A = addr & 0xff;
  delay();
  NANDFLASH3A = (addr >> 8) & 0xff;
  delay();
  NANDFLASH3A = (addr >> 16) & 0xff;
  delay();
  NANDFLASH3C = 0x30;
  delay();
  for (i = 0; i < 4; i++)
  {
    *((uint8_t *)buffer + i) = NANDFLASH3;
    delay();
  }
}

 

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