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