之前已经驱动过TFT了,大有成果,不过如果驱动NAND呢?那就不一样呢,而且,这个芯片引脚有点紧缺,好像能做NAND,就不能做TFT.这实在有点..不过,其实CS是可以外部控制的,这也还好,用一个IO做CS而不是用FSMC自带的自动CS.
另外,根据使用的NAND不同,需要配置时序也不一样,我的系统CLK是168MHz,比如我现在用的K9F1G08U0B-SCB0,就需要先从手册入手,获取时序.比如我的是http://www1.futureelectronics.com/doc/SAMSUNG/K9F1G08U0B-PCB0T00.pdf,根据时序配置得到:
p.FSMC_SetupTime = 0xf1; p.FSMC_WaitSetupTime = 0xf3; p.FSMC_HoldSetupTime = 0xf2; p.FSMC_HiZSetupTime = 0xf1;
然后通过读取ID进行判断,是不是这个NAND,以及是否正确.
然而NAND读写不像EEPROM可以按BYTE,另外还需要FSMC_NAND_GetStatus读状态,而这些指令,都在手册这里.如读取状态,其中定义NAND_CMD_STATUS就是0x70,其他类似:
uint32_t FSMC_NAND_ReadStatus(void) { uint32_t data = 0x00, status = NAND_BUSY; /* Read status operation ------------------------------------ */ *(vu8 *)(NAND_FLASH_START_ADDR | CMD_AREA) = NAND_CMD_STATUS; data = *(vu8 *)(NAND_FLASH_START_ADDR); if((data & NAND_ERROR) == NAND_ERROR) { status = NAND_ERROR; } else if((data & NAND_READY) == NAND_READY) { status = NAND_READY; } else { status = NAND_BUSY; } return (status); }
手册中的命令:
根据这些,可以写出如下函数,程序,比较长,打包一下,不难的:
/* Private function prototypes -----------------------------------------------*/ void FSMC_NAND_Init(void); void FSMC_NAND_Test(void); void FSMC_NAND_ReadID(NAND_IDTypeDef* NAND_ID); uint32_t FSMC_NAND_WriteSmallPage(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumPageToWrite); uint32_t FSMC_NAND_ReadSmallPage (uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumPageToRead); uint32_t FSMC_NAND_WriteSpareArea(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumSpareAreaTowrite); uint32_t FSMC_NAND_ReadSpareArea(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumSpareAreaToRead); uint32_t FSMC_NAND_EraseBlock(NAND_ADDRESS Address); uint32_t FSMC_NAND_Reset(void); uint32_t FSMC_NAND_GetStatus(void); uint32_t FSMC_NAND_ReadStatus(void); uint32_t FSMC_NAND_AddressIncrement(NAND_ADDRESS* Address);
下面是效果图以及程序下载地址:
程序下载地址:并口驱动NAND