打印

stm32f407 nand flash

[复制链接]
247|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
无幻|  楼主 | 2018-7-7 07:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
刚接触stm32,参考的f429的例程修改的nand flash用的是MT29F8G16ADADA的芯片,就是对例程引脚配置进行修改,读id始终不成功,有人能帮看看是什么问题吗?


nand.c
nand_attriute nand_dev;             //nand重要参数结构体
               
//初始化NAND FLASH
u8 NAND_Init(void)
{
                GPIO_InitTypeDef GPIO_Initure;
                FSMC_NANDInitTypeDef NAND_Handler;    //NAND FLASH句柄
    FSMC_NAND_PCCARDTimingInitTypeDef ComSpaceTiming,AttSpaceTiming;
                RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD|RCC_AHB1Periph_GPIOE|RCC_AHB1Periph_GPIOG, ENABLE);//使能PD,PE,PF,PG时钟  
                RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC,ENABLE);//使能FSMC时钟  

                RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
        
        
                GPIO_Initure.GPIO_Pin = (3<<0)|(3<<4)|(0XF<<7)|(7<<10)|(3<<14);
                GPIO_Initure.GPIO_Mode = GPIO_Mode_AF;//复用输出
                GPIO_Initure.GPIO_OType = GPIO_OType_PP;//推挽输出
                GPIO_Initure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
                GPIO_Initure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
                GPIO_Init(GPIOD, &GPIO_Initure);//初始化  

        
                GPIO_Initure.GPIO_Pin = (0X1F<<7)|(0XF<<12);
                GPIO_Initure.GPIO_Mode = GPIO_Mode_AF;//复用输出
                GPIO_Initure.GPIO_OType = GPIO_OType_PP;//推挽输出
                GPIO_Initure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
                GPIO_Initure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
                GPIO_Init(GPIOE, &GPIO_Initure);//初始化
           

                GPIO_Initure.GPIO_Pin = GPIO_Pin_6;
                GPIO_Initure.GPIO_Mode = GPIO_Mode_AF;//复用输出
                GPIO_Initure.GPIO_OType = GPIO_OType_PP;//推挽输出
                GPIO_Initure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
                GPIO_Initure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
                GPIO_Init(GPIOG, &GPIO_Initure);//初始化

                GPIO_PinAFConfig(GPIOD,GPIO_PinSource0,GPIO_AF_FSMC);//PD0,AF12
                GPIO_PinAFConfig(GPIOD,GPIO_PinSource1,GPIO_AF_FSMC);//PD1,AF12
                GPIO_PinAFConfig(GPIOD,GPIO_PinSource4,GPIO_AF_FSMC);
                GPIO_PinAFConfig(GPIOD,GPIO_PinSource5,GPIO_AF_FSMC);
                GPIO_PinAFConfig(GPIOD,GPIO_PinSource7,GPIO_AF_FSMC);
                GPIO_PinAFConfig(GPIOD,GPIO_PinSource8,GPIO_AF_FSMC);
                GPIO_PinAFConfig(GPIOD,GPIO_PinSource9,GPIO_AF_FSMC);
                GPIO_PinAFConfig(GPIOD,GPIO_PinSource10,GPIO_AF_FSMC);
                GPIO_PinAFConfig(GPIOD,GPIO_PinSource11,GPIO_AF_FSMC);
                GPIO_PinAFConfig(GPIOD,GPIO_PinSource12,GPIO_AF_FSMC);
                GPIO_PinAFConfig(GPIOD,GPIO_PinSource14,GPIO_AF_FSMC);
                GPIO_PinAFConfig(GPIOD,GPIO_PinSource15,GPIO_AF_FSMC);//PD15,AF12
         
                GPIO_PinAFConfig(GPIOE,GPIO_PinSource7,GPIO_AF_FSMC);//PE7,AF12
                GPIO_PinAFConfig(GPIOE,GPIO_PinSource8,GPIO_AF_FSMC);
                GPIO_PinAFConfig(GPIOE,GPIO_PinSource9,GPIO_AF_FSMC);
                GPIO_PinAFConfig(GPIOE,GPIO_PinSource10,GPIO_AF_FSMC);
                GPIO_PinAFConfig(GPIOE,GPIO_PinSource11,GPIO_AF_FSMC);
                GPIO_PinAFConfig(GPIOE,GPIO_PinSource12,GPIO_AF_FSMC);
                GPIO_PinAFConfig(GPIOE,GPIO_PinSource13,GPIO_AF_FSMC);
                GPIO_PinAFConfig(GPIOE,GPIO_PinSource14,GPIO_AF_FSMC);
                GPIO_PinAFConfig(GPIOE,GPIO_PinSource15,GPIO_AF_FSMC);//PE15,AF12
                 
                GPIO_PinAFConfig(GPIOG,GPIO_PinSource6,GPIO_AF_FSMC);



    ComSpaceTiming.FSMC_SetupTime=2;         //建立时间
    ComSpaceTiming.FSMC_WaitSetupTime=3;     //等待时间
    ComSpaceTiming.FSMC_HoldSetupTime=2;     //保持时间
    ComSpaceTiming.FSMC_HiZSetupTime=1;      //高阻态时间

    AttSpaceTiming.FSMC_SetupTime=2;         //建立时间
    AttSpaceTiming.FSMC_WaitSetupTime=3;     //等待时间
    AttSpaceTiming.FSMC_HoldSetupTime=2;     //保持时间
    AttSpaceTiming.FSMC_HiZSetupTime=1;      //高阻态时间


  //  NAND_Handler.Instance=FMC_NAND_DEVICE;
    //NAND_Handler.Init.NandBank=FMC_NAND_BANK3;                          //NAND挂在BANK3上
                NAND_Handler.FSMC_Bank=FSMC_Bank2_NAND;                          //NAND挂在BANK2上
    NAND_Handler.FSMC_Waitfeature=FSMC_Waitfeature_Disable;    //关闭等待特性
    NAND_Handler.FSMC_MemoryDataWidth=FSMC_MemoryDataWidth_16b;     //16位数据宽度
    NAND_Handler.FSMC_ECC=FSMC_ECC_Disable;              //不使用ECC
    NAND_Handler.FSMC_ECCPageSize=FSMC_ECCPageSize_512Bytes;      //ECC页大小为2K
    NAND_Handler.FSMC_TCLRSetupTime=0;                                  //设置TCLR(tCLR=CLE到RE的延时)=(TCLR+TSET+2)*THCLK,THCLK=1/180M=5.5ns
    NAND_Handler.FSMC_TARSetupTime=1;                                   //设置TAR(tAR=ALE到RE的延时)=(TAR+TSET+2)*THCLK,THCLK=1/180M=5.5n。   
                NAND_Handler.FSMC_CommonSpaceTimingStruct=&ComSpaceTiming;
                NAND_Handler.FSMC_AttributeSpaceTimingStruct=&AttSpaceTiming;
        
        


   // HAL_NAND_Init(&NAND_Handler,&ComSpaceTiming,&AttSpaceTiming);
         FSMC_NANDInit(&NAND_Handler);
         FSMC_NANDCmd(FSMC_Bank2_NAND,ENABLE);

         
    NAND_Reset();                               //复位NAND
    delay_ms(100);
    nand_dev.id=NAND_ReadID();                //读取ID
                NAND_ModeSet(4);                                //设置为MODE4,高速模式
    if(nand_dev.id==MT29F16G08ABABA)    //NAND为MT29F16G08ABABA
    {
        nand_dev.page_totalsize=4320;          //nand一个page的总大小(包括spare区)     
        nand_dev.page_mainsize=4096;           //nand一个page的有效数据区大小   
        nand_dev.page_sparesize=224;        //nand一个page的spare区大小
        nand_dev.block_pagenum=128;                //nand一个block所包含的page数目
        nand_dev.plane_blocknum=2048;        //nand一个plane所包含的block数目
        nand_dev.block_totalnum=4096;          //nand的总block数目  
    }
    else if(nand_dev.id==MT29F4G08ABADA)//NAND为MT29F4G08ABADA
    {
        nand_dev.page_totalsize=2112;        //nand一个page的总大小(包括spare区)
        nand_dev.page_mainsize=2048;         //nand一个page的有效数据区大小
        nand_dev.page_sparesize=64;                //nand一个page的spare区大小
        nand_dev.block_pagenum=64;                //nand一个block所包含的page数目
        nand_dev.plane_blocknum=2048;        //nand一个plane所包含的block数目
        nand_dev.block_totalnum=4096;         //nand的总block数目
    }
                else if(nand_dev.id==MT29F8G16ADADA)//NAND为MT29F8G16ADADA
    {
        nand_dev.page_totalsize=2112;        //nand一个page的总大小(包括spare区)
        nand_dev.page_mainsize=2048;         //nand一个page的有效数据区大小
        nand_dev.page_sparesize=64;                //nand一个page的spare区大小
        nand_dev.block_pagenum=64;                //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;
    u32 data = 0;        
    *(vu8*)(NAND_ADDRESS|NAND_CMD)=NAND_READID; //发送读取ID命令
    *(vu8*)(NAND_ADDRESS|NAND_ADDR)=0X00;
        //ID一共有5个字节
          data = *(vu32 *)(NAND_ADDRESS | DATA_AREA);
    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];
          //deviceid[1]  = ADDR_1st_CYCLE (data);
        //        deviceid[2]  = ADDR_2nd_CYCLE (data);
        //        deviceid[3]  = ADDR_3rd_CYCLE (data);
        //        deviceid[4]  = ADDR_4th_CYCLE (data);
        
                //id=((u32)deviceid[1])|((u32)deviceid[2])|((u32)deviceid[3])|deviceid[4];
        
        
        
    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;//发送读状态命令
                data++;data++;data++;data++;data++;        //加延时,防止-O2优化,导致的错误.
                data=*(vu8*)NAND_ADDRESS;                        //读取状态值
    return data;
}
//等待NAND准备好
//返回值:NSTA_TIMEOUT 等待超时了
//      NSTA_READY    已经准备好
u8 NAND_WaitForReady(void)
{
    u8 status=0;
    vu32 time=0;
        while(1)                                                //等待ready
        {
                status=NAND_ReadStatus();        //获取状态值
                if(status&NSTA_READY)break;
                time++;
                if(time>=0X1FFFF)return NSTA_TIMEOUT;//超时
        }  
    return NSTA_READY;//准备好
}  
//复位NAND
//返回值:0,成功;
//    其他,失败
u8 NAND_Reset(void)
{
    *(vu8*)(NAND_ADDRESS|NAND_CMD)=NAND_RESET;        //复位NAND
    if(NAND_WaitForReady()==NSTA_READY)return 0;//复位成功
    else return 1;                                                                //复位失败
}

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

431

主题

436

帖子

0

粉丝