本帖最后由 shuaigew88 于 2016-9-17 20:25 编辑
我用STM32F407的FSMC驱动NANDFLASH(K9F1208)可以正常读出NANDFLASH的ID,现在的问题是当正确擦除块后用页读命令读取擦除的块时读出的数据全是0,
void NAND_GpioInit()
{
GPIO_InitTypeDef myGPIO;
AFGPIO_InitTypeDef myAFGPIO;
myGPIO.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_14|GPIO_Pin_15;
myGPIO.GPIO_Mode =GPIO_Mode_AF;
myGPIO.GPIO_OType =GPIO_OType_PP;
myGPIO.GPIO_PuPd =GPIO_PuPd_NOPULL;
myGPIO.GPIO_Speed =GPIO_Speed_100MHz;
GPIO_Init(GPIOD,&myGPIO);
myGPIO.GPIO_Pin =GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;
GPIO_Init(GPIOE,&myGPIO);
myGPIO.GPIO_Pin =GPIO_Pin_9;
GPIO_Init(GPIOG,&myGPIO);
myGPIO.GPIO_Pin =GPIO_Pin_6;
myGPIO.GPIO_Mode =GPIO_Mode_IN;
myGPIO.GPIO_PuPd =GPIO_PuPd_IPU;
myGPIO.GPIO_OType =GPIO_OType_OD;
GPIO_Init(GPIOG,&myGPIO);
myGPIO.GPIO_Pin =GPIO_Pin_6;
GPIO_Init(GPIOD,&myGPIO);
myAFGPIO.GPIO_Pin =AFGPIO_Pin_0|AFGPIO_Pin_1|AFGPIO_Pin_4|AFGPIO_Pin_5|AFGPIO_Pin_11|AFGPIO_Pin_12|AFGPIO_Pin_14|AFGPIO_Pin_15;
myAFGPIO.GPIO_AF =AFGPIO_AF12;
AFGPIO_Init(GPIOD,&myAFGPIO);
myAFGPIO.GPIO_Pin =AFGPIO_Pin_7|AFGPIO_Pin_8|AFGPIO_Pin_9|AFGPIO_Pin_10;
AFGPIO_Init(GPIOE,&myAFGPIO);
myAFGPIO.GPIO_Pin =AFGPIO_Pin_9;
AFGPIO_Init(GPIOG,&myAFGPIO);
}
void NAND_FsmcInit()
{
FSMC_Bank3 ->PCR3 =0;
FSMC_Bank3 ->PCR3|=(UINT32)(1<<13); //ALE To RE Delay
FSMC_Bank3 ->PCR3|=(UINT32)(1<<9); //CLE To RE Delay
//FSMC_Bank3 ->PCR3|=(1<<1); //en wait
//FSMC_Bank3 ->PCR3|=(1<<17); //ecc 512
//FSMC_Bank3 ->PCR3|=(1<<6); //en ecc
FSMC_Bank3 ->PMEM3 =0;
FSMC_Bank3 ->PMEM3|=(UINT32)(1<<24); //Mem HiZ Hold =1
FSMC_Bank3 ->PMEM3|=(UINT32)(2<<16); //Mem Hold time =2
FSMC_Bank3 ->PMEM3|=(UINT32)(3<<8); //Mem Wait time =3
FSMC_Bank3 ->PMEM3|=(UINT32)(1<<0); //Mem Setup time =1
FSMC_Bank3 ->PATT3 =0;
FSMC_Bank3 ->PATT3|=(UINT32)(1<<24);
FSMC_Bank3 ->PATT3|=(UINT32)(2<<16);
FSMC_Bank3 ->PATT3|=(UINT32)(3<<8);
FSMC_Bank3 ->PATT3|=(UINT32)(1<<0);
FSMC_Bank3 ->PCR3|=(UINT32)(1<<3); //NANDFLASH
FSMC_Bank3 ->PCR3|=(UINT32)(1<<2); //NANDFLASH Enable
NAND_GpioInit();
// NAND_Reset();
}
void NAND_Reset()
{
NAND_WrCmd(0xff);
NAND_Busy();
}
UINT32 NAND_ReadID()
{
UINT32 id =0;
NAND_WrCmd(0x90);
NAND_WrAdr(0x00);
id =NAND_RdByte() <<24;
NAND_WrAdr(0x01);
id|=NAND_RdByte() <<16;
NAND_WrAdr(0x02);
id|=NAND_RdByte() <<8;
NAND_WrAdr(0x03);
id|=NAND_RdByte() <<0;
return id;
}
UINT8 NAND_ReadSR()
{
static UINT8 sr=0;
NAND_WrCmd(0x70);
NAND_Busy();
sr =NAND_RdByte();
return sr;
}
UINT8 NAND_BlockErase(UINT32 bladr)
{
bladr <<=5;
NAND_WrCmd(0x60);
NAND_WrAdr(bladr);
NAND_WrAdr(bladr>>8);
NAND_WrAdr(bladr>>16);
NAND_WrCmd(0xD0);
NAND_Busy();
if((NAND_ReadSR()&0x01) !=NAND_OK)return NAND_FAIL;
return NAND_OK;
}
void NAND_PageRead(UINT32 padr,UINT8 *Buf)
{
UINT16 i;
NAND_WrCmd(0x00);
NAND_WrAdr(0);
NAND_WrAdr(padr);
NAND_WrAdr(padr>>8);
NAND_WrAdr(padr>>16);
NAND_Busy();
for(i=0;i<512;i++)Buf=NAND_RdByte();
}
UINT8 NAND_PageWrite(UINT32 padr,UINT8 *Buf)
{
UINT16 i;
NAND_WrCmd(0x80);
NAND_WrAdr(0);
NAND_WrAdr(padr);
NAND_WrAdr(padr>>8);
NAND_WrAdr(padr>>16);
Delay_ms(1);
for(i=0;i<512;i++)NAND_WrByte(Buf);
NAND_WrCmd(0x10);
NAND_Busy();
if((NAND_ReadSR()&0x01)!=NAND_OK)return NAND_FAIL;
return NAND_OK;
}
//include
#define NAND_OK 0
#define NAND_FAIL 1
#define CMD_AREA ((UINT32)0x010000) /* A16 = CLE high */
#define ADDR_AREA ((UINT32)0x020000) /* A17 = ALE high */
#define DATA_AREA ((UINT32)0x000000)
#define Bank_NAND_ADDR ((UINT32)0x80000000)
#define NAND_WrCmd(Cmd) (*(UINT8 *)(Bank_NAND_ADDR | CMD_AREA)) =Cmd
#define NAND_WrAdr(Adr) (*(UINT8 *)(Bank_NAND_ADDR | ADDR_AREA)) =Adr
#define NAND_WrByte(Dat) (*(UINT8 *)(Bank_NAND_ADDR | DATA_AREA)) =Dat
#define NAND_RdByte() (*(UINT8 *)(Bank_NAND_ADDR | DATA_AREA))
#define NAND_Busy() while((GPIOG ->IDR & (1<<6))==0)
//main函数
NAND_FsmcInit();
tmp =NAND_ReadID(); //可以正常读出ID号
res =NAND_BlockErase(0); //块擦除返回OK
NAND_PageRead(0,buf); //读出擦除的数据全是0,读取数据错误
目前可以确定是FSMC配置问题,因为我用IO模拟时序的时候读写NANDFLASH块的数据都是正确的,IO模拟时将下面4个宏改成4个函数,分别写了IO模拟时序。
#define NAND_WrCmd(Cmd) (*(UINT8 *)(Bank_NAND_ADDR | CMD_AREA)) =Cmd
#define NAND_WrAdr(Adr) (*(UINT8 *)(Bank_NAND_ADDR | ADDR_AREA)) =Adr
#define NAND_WrByte(Dat) (*(UINT8 *)(Bank_NAND_ADDR | DATA_AREA)) =Dat
#define NAND_RdByte() (*(UINT8 *)(Bank_NAND_ADDR | DATA_AREA))
用下面的IO模拟时序时数据是正确的,所以可以肯定是FSMC配置的问题,但我实在是找不出问题来。
UINT8 NAND_RdByte()
{
UINT8 tmp;
NAND_GPIO_OUT(0xff);
NAND_CLE_CLR();
NAND_ALE_CLR();
NAND_CS_CLR();
Delay_us(100);
NAND_RE_CLR();
Delay_us(200);
tmp =NAND_GPIO_IN();
NAND_RE_SET();
Delay_us(100);
NAND_CLE_SET();
NAND_ALE_SET();
NAND_CS_SET();
return tmp;
}
void NAND_WrByte(UINT8 Dat)
{
NAND_CLE_CLR();
NAND_ALE_CLR();
NAND_CS_CLR();
NAND_GPIO_OUT(Dat);
Delay_us(500);
NAND_WE_CLR();
Delay_us(100);
NAND_WE_SET();
Delay_us(100);
NAND_CLE_SET();
NAND_ALE_SET();
NAND_CS_SET();
}
void NAND_WrCmd(UINT8 Cmd)
{
NAND_ALE_CLR();
NAND_CS_CLR();
NAND_GPIO_OUT(Cmd);
Delay_us(500);
NAND_WE_CLR();
Delay_us(100);
NAND_WE_SET();
Delay_us(100);
NAND_ALE_SET();
NAND_CS_SET();
}
void NAND_WrAdr(UINT8 Adr)
{
NAND_CLE_CLR();
NAND_CS_CLR();
NAND_GPIO_OUT(Adr);
Delay_us(500);
NAND_WE_CLR();
Delay_us(100);
NAND_WE_SET();
Delay_us(100);
NAND_CLE_SET();
NAND_CS_SET();
}
麻烦大虾们帮我看看配置时序哪里有问题,可以正常读出ID,然后就是页读函数
void NAND_PageRead(UINT32 padr,UINT8 *Buf)
{
UINT16 i;
NAND_WrCmd(0x00);
NAND_WrAdr(0);
NAND_WrAdr(padr);
NAND_WrAdr(padr>>8);
NAND_WrAdr(padr>>16);
NAND_Busy();
for(i=0;i<512;i++)Buf=NAND_RdByte(); //我发现当运行到这里的时候NAND的数据总线是处于高阻态的,NANDFLASH没有数据返回,读取的数据是GPIO数据端口的最后状态
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
楼主是不是地址发送的不对啊,分享一下问题所在啊!!
这个欲等待处理我实际是将NANDFLASH的片选信号单独用软件控制实现的,我实际FSMC硬件是旁路了片选信号,因为没搞懂STM32的欲等待机制也懒得搞。实际使用时只要注意就没影响,这个方法同样适用于FSMC片选信号不够的场合。
一周热门 更多>