Nand Flash和LCD同时使用闪屏问题

1.LPC1788自带LCD控制器,当单片机同时接入并口的Nand Flash和并口的LCD显示屏时,当频繁写入Nand Flash时,LCD屏幕会不断闪烁,当然这个问题肯定是总线冲突了,查找资料,发现可以设置总线优先级,在手册的P19页,通常可以这么设置:(volatile INT32U)(0x400fc188)=0xc09;这样就设置了总线优先级:LCD>DATA & gt;CODE到这里,理论上应该是解决了,但是事实上还是差一点,依然闪烁,但是上面设置的总线优先级应该是没有什么问题了,而且合情合理,所以就先加着吧!
接着仔细分析,发生冲突肯定是因为SDRAM和Nand Flash的冲突,因为LCD屏的显存是在外部的SDRAM中的,并且SDRAM和Nand Flash都是属于FMC是挂接在AHB总线上的,同一时间肯定两者只能有一个占用总线,是不是因为在读取Nand Flash的时候,长时间的占用了总线时间,而LCD却长时间不能从SDRAM得到界面刷新,因此我们想着可以试着降低LCD的刷新率,在LCD的驱动文件中,果然看到了有个LCD_PIX_CLK的宏,试着将刷新率从20M改到了15M,果然屏不闪烁了。

2.STM32F429单片机,在bootloader程序中,格式化Nand Flash过程中,屏幕会闪屏,通过进一步调试发现问题主要出在写入数据的过程中闪屏,由于在格式化Nand Flash过程中,会存在对Nand Flash频繁写入,频繁写入过程中占用总线大量的时间。
解决方法:降低LCD的时钟频率,修改SystemClock_Config(void)函数中的PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_2;修改为PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_4;

3.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();
  }
}

你可能感兴趣的:(单片机)