stm32f103zet6使用fsmc读写nandflash,debug调试读出id正确,运行时读出的id错误
u8 nand_flash_init(void)
{
FSMC_NANDInitTypeDef FSMC_NandInitTypeDef;
FSMC_NAND_PCCARDTimingInitTypeDef FSMC_NnadPccardTimingInitTypeDef;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOG, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_7|GPIO_Pin_11|GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_SetBits(GPIOD,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_7|GPIO_Pin_11|GPIO_Pin_12);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_SetBits(GPIOD,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_14|GPIO_Pin_15);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_SetBits(GPIOE,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOG, &GPIO_InitStructure);
FSMC_NnadPccardTimingInitTypeDef.FSMC_SetupTime = 0x01;
FSMC_NnadPccardTimingInitTypeDef.FSMC_WaitSetupTime = 0x03;
FSMC_NnadPccardTimingInitTypeDef.FSMC_HoldSetupTime = 0x02;
FSMC_NnadPccardTimingInitTypeDef.FSMC_HiZSetupTime = 0x02;
FSMC_NandInitTypeDef.FSMC_Bank = FSMC_Bank3_NAND;
FSMC_NandInitTypeDef.FSMC_Waitfeature = FSMC_Waitfeature_Enable;
FSMC_NandInitTypeDef.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;
FSMC_NandInitTypeDef.FSMC_ECC = FSMC_ECC_Enable;
FSMC_NandInitTypeDef.FSMC_ECCPageSize = FSMC_ECCPageSize_512Bytes;
FSMC_NandInitTypeDef.FSMC_TCLRSetupTime = 0x00;
FSMC_NandInitTypeDef.FSMC_TARSetupTime = 0x00;
FSMC_NandInitTypeDef.FSMC_CommonSpaceTimingStruct = &FSMC_NnadPccardTimingInitTypeDef;
FSMC_NandInitTypeDef.FSMC_AttributeSpaceTimingStruct = &FSMC_NnadPccardTimingInitTypeDef;
FSMC_NANDInit(&FSMC_NandInitTypeDef);
/* FSMC NAND Bank Cmd Test */
FSMC_NANDCmd(FSMC_Bank3_NAND, ENABLE);
NAND_Reset(); //复位NAND
delay_ms(100);
nand_dev.id=NAND_ReadID(); //读取ID
NAND_ModeSet(4); //设置为MODE4,高速模式
if(nand_dev.id==MT29F128G08CFABA) //NAND为MT29F16G08ABABA
{
nand_dev.page_totalsize=8936; //nand一个page的总大小(包括spare区)
nand_dev.page_mainsize=8192; //nand一个page的有效数据区大小
nand_dev.page_sparesize=744; //nand一个page的spare区大小
nand_dev.block_pagenum=256; //nand一个block所包含的page数目
nand_dev.plane_blocknum=2048; //nand一个plane所包含的block数目
nand_dev.block_totalnum=8192; //nand的总block数目
}
else return 1; //错误,返回
return 0;
}
//读取NAND FLASH的ID
//返回值:0,成功;
// 其他,失败
u8 NAND_ModeSet(u8 mode)
{
*(vu8*)(NAND_ADDRESS|NAND_CMD)=NAND_FEATURE;//发送设置特性命令
*(vu8*)(NAND_ADDRESS|NAND_ADDR)=0X01; //地址为0X01,设置mode
*(vu8*)NAND_ADDRESS=mode; //P1参数,设置mode
*(vu8*)NAND_ADDRESS=0;
*(vu8*)NAND_ADDRESS=0;
*(vu8*)NAND_ADDRESS=0;
if(NAND_WaitForReady()==NSTA_READY)return 0;//成功
else return 1; //失败
}
//读取NAND FLASH的ID
//不同的NAND略有不同,请根据自己所使用的NAND FALSH数据手册来编写函数
//返回值:NAND FLASH的ID值
u32 NAND_ReadID(void)
{
u8 deviceid[5];
u32 id;
*(vu8*)(NAND_ADDRESS|NAND_CMD)=NAND_READID; //发送读取ID命令
*(vu8*)(NAND_ADDRESS|NAND_ADDR)=0X00;
//ID一共有5个字节
deviceid[0]=*(vu8*)NAND_ADDRESS;
deviceid[1]=*(vu8*)NAND_ADDRESS;
deviceid[2]=*(vu8*)NAND_ADDRESS;
deviceid[3]=*(vu8*)NAND_ADDRESS;
deviceid[4]=*(vu8*)NAND_ADDRESS;
//镁光的NAND FLASH的ID一共5个字节,但是为了方便我们只取4个字节组成一个32位的ID值
//根据NAND FLASH的数据手册,只要是镁光的NAND FLASH,那么一个字节ID的第一个字节都是0X2C
//所以我们就可以抛弃这个0X2C,只取后面四字节的ID值。
id=((u32)deviceid[1])<<24|((u32)deviceid[2])<<16|((u32)deviceid[3])<<8|deviceid[4];
printf("%4x",id);
return id;
}
//读NAND状态
//返回值:NAND状态值
//bit0:0,成功;1,错误(编程/擦除/READ)
//bit6:0,Busy;1,Ready
u8 NAND_ReadStatus(void)
{
vu8 data=0;
*(vu8*)(NAND_ADDRESS|NAND_CMD)=NAND_READSTA;//发送读状态命令
NAND_Delay(NAND_TWHR_DELAY); //等待tWHR,再读取状态寄存器
data=*(vu8*)NAND_ADDRESS; //读取状态值
printf("nand status :%x",data);
return data;
}
u8 NAND_WaitForReady(void)
{
u8 status=0;
vu32 time=0;
while(1) //等待ready
{
status=NAND_ReadStatus(); //获取状态值
if(status&NSTA_READY)break;
time++;
if(time>=0X1FFFFFFF)return NSTA_TIMEOUT;//超时
}
return NSTA_READY;//准备好
}
u8 NAND_Reset(void)
{
*(vu8*)(NAND_ADDRESS|NAND_CMD)=NAND_RESET; //复位NAND
if(NAND_WaitForReady()==NSTA_READY)return 0;//复位成功
else return 1; //复位失败
}
//等待RB信号为某个电平
//rb:0,等待RB==0
// 1,等待RB==1
//返回值:0,成功
// 1,超时
u8 NAND_WaitRB(vu8 rb)
{
vu32 time=0;
while(time<0X1FFFFFF)
{
time++;
if(NAND_RB==rb)return 0;
}
return 1;
}
//NAND延时
//一个i++至少需要4ns
void NAND_Delay(vu32 i)
{
while(i>0)i--;
}
这是配置代码,很奇怪的问题。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
谢了谢了
一周热门 更多>