OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2575|回复: 3

stm32f103zet6使用fsmc读写nandflash,debug调试读出id正确,运行时id错误,这是什么原因

[复制链接]

8

主题

42

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2019-3-17
在线时间
45 小时
发表于 2019-3-24 11:11:17 | 显示全部楼层 |阅读模式
1金钱
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--;
}



这是配置代码,很奇怪的问题。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

109

主题

5564

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
10572
金钱
10572
注册时间
2017-2-18
在线时间
1914 小时
发表于 2019-3-24 20:17:33 | 显示全部楼层
回复

使用道具 举报

8

主题

42

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2019-3-17
在线时间
45 小时
 楼主| 发表于 2019-3-25 09:30:33 | 显示全部楼层

谢了谢了
回复

使用道具 举报

8

主题

42

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
202
金钱
202
注册时间
2019-3-17
在线时间
45 小时
 楼主| 发表于 2019-3-25 15:03:06 | 显示全部楼层

大神时序怎么计算,可能时序计算错了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-24 08:13

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表