发作品签到
专业版

Nand Flash验证模块

工程标签

2.7k
0
0
3

简介

为了验证TSOP-48 不同厂家 不同公司的Nand的芯片,验证存储功能,设计了一个通用的Nand模块,引出功能引脚,可以验证Nand时序、页、块读写,便于模块化调试。

简介:为了验证TSOP-48 不同厂家 不同公司的Nand的芯片,验证存储功能,设计了一个通用的Nand模块,引出功能引脚,可以验证Nand时序、页、块读写,便于模块化调试。

开源协议

Public Domain

创建时间:2022-10-09 09:20:23更新时间:2022-10-13 09:59:57

描述

适用于STM32和FPGA时序验证的通用NandFlash模块

 

题目分析

Nand的不同厂家不同品牌不同工艺,其内部存储器的堆叠形式大相径庭,传统硬件开发需要先完成方案设计工作,但Nand的多样性会给后续项目的软件编写产生困难,为了验证时序或存储方式,存储结构是否适合本项目,于是乎本设计完成了一个方案验证板,用于测试不同厂家的Nand,并以常用的三星、冷门的意法半导体的Nand为例,简要地说明时序以及程序编写中遇到的一些问题,为嵌入式工程师之后的设计提供一种可行的解决方案。


iKmzXf1Hc5JlA6dKhHPLTH5ttXoD8IQSBLGJcJXZ.png

图1 ST NAND的结构

不同的Nand容量和块数量不相同,对每一个NAND都需要查看它的结构,进行编程

原理图设计说明

验证板的电路图比较简单,主要将芯片的功能引脚引出。

EQP0UYD7gEM6YEuxcFMRNtkljKeT4blDID8uhCsw.png

图2 方案验证版的原理图

  在验证板中U1为TSSOP-48封装的Nand,用该封装的Nand功能引脚都相同,所以验证版上的各个Nand可以相互替换,在含Nand的开发板中,为了保证存储功能的稳定,还使用的更多的滤波电容和上下拉电阻,本验证版为了考虑与STM32和FPGA板子的兼容性,减少了上下拉电阻,如需要可在STM32GPIO中配置。右侧为2x10PIN 2.54mm的插座,用于将功能引脚引出,D1为电源指示灯。电路中VCC的典型值根据芯片选择,常用的有3.3V,低电压的Nand芯片采用1.6V供电。

Ie11EqEZ8VCvOJhfjLjpIgVMgA7m1ePCFMdO9WNw.png

图3 立创商城买的ST Nand

这个Nand属于冷门Nand,比较难购买,本次购买的型号是ST NAND02GW3B2DN6E,该芯片拥有2G bit的存储空间,当然了也可以用其他厂家的NAND进行替换,如镁光、三星等,1G-8G bit满足日常项目的存储需求。再大一点的存储需求可以考虑SD卡,或者速度更快的EMMC,容量小的存储需求可考虑NOR Flash,如W25Q128、W25Q256等,数据更可靠。两者之间的区别不再赘述。

 

PCB设计说明

DbCXmJlMCP2qUspNQOSJTTRfaxrYWXYZOdMPQLc4.png

图4 PCB打样的图片

xapdiizp9GvREfv7HP9amgHBDjAhLqm7PKHsF116.png

图5 立创EDA画的板子

不得不说EDA软件十分好用,对于布线,器件选型特别友好,新手可以提供友好的界面和简单的设计流程,对于我们这些老工程师来说,减少了找器件封装所需要的时间,极大的提升了设计的效率,原理图到PCB和备件,一站式配齐,缩短了产品迭代时间。

板子的话没什么好说的,双面板,铺地铜,电源线30mil

 

软件说明

 

DdhXpcUVVMG25fPyfz6oivzvtzfgj7jWTlsU8TkA.png

图6 STM32CubeMX的FMC控制器

采用ST官方的FMC控制器使得编程简单了许多,控制NAND不需要接触底层的NAND时序,只需要编写存储结构和逻辑即可。按照CUBE上进行接线测试nand功能即可,完整代码贴附件了,
代码块:

        if(Trans_flag==0)                    //Ä£ÄâÕýÏÒ²¨²úÉú
        {
        Sine();
//            for(i=0;i<2048;i++)
//            RxBuffer[i]=0XAA;
            Trans_flag=1;
        }
        else if(Trans_flag==1)   //¿ªÊ¼¶ÔNand½øÐÐдÈë
        {
            HAL_NAND_Write_Page_8b(&hnand1,&WriteReadAddr,RxBuffer,1);//дÈëÒ³
            if(WriteReadAddr.Block%100==0)
            {
            block_temp[0]=WriteReadAddr.Block/1000%10+48;
            block_temp[1]=WriteReadAddr.Block/100%10+48;
            block_temp[2]=WriteReadAddr.Block/10%10+48;
            block_temp[3]=WriteReadAddr.Block%10+48;
            HAL_UART_Transmit(&huart1,block_temp,4,500);
            }
            Trans_flag=0;
            if(++WriteReadAddr.Page>63)                //дÈëÒ³×Ô¼Ó
            {
                WriteReadAddr.Page=0;
                WriteReadAddr.Block=WriteReadAddr.Block+1;
                if(WriteReadAddr.Block>1020)
                {
                    Trans_flag=5;
                    HAL_UART_Transmit(&huart1,text1,12,500);  //дÈëÍ£Ö¹
                }
            }
        }
        else if(Trans_flag==2)    //¿ªÊ¼¶ÔNand¶ÁÈ¡
        {
            if(First_data==0)            //»Ö¸´³õʼµØÖ·
            {
                First_data=1;
                WriteReadAddr.Block=0;
                WriteReadAddr.Page=0;
                WriteReadAddr.Plane=1;
            }

        HAL_NAND_Read_Page_8b(&hnand1,&WriteReadAddr,RxBuffer_u8,1);  //¶Ánand
//                    HAL_UART_Transmit(&huart1,text7,12,500);
//            page_temp[0]=WriteReadAddr.Page/10+48;
//            page_temp[1]=WriteReadAddr.Page%10+48;
//                    HAL_UART_Transmit(&huart1,page_temp,2,500);
//                    HAL_UART_Transmit(&huart1,text3,13,500);

            if(WriteReadAddr.Block%30==0&&WriteReadAddr.Page==0)
            {
            block_temp[0]=WriteReadAddr.Block/100%10+48;
            block_temp[1]=WriteReadAddr.Block/10%10+48;
            block_temp[2]=WriteReadAddr.Block%10+48;
                    HAL_UART_Transmit(&huart1,block_temp,3,500);                
            }

        USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS,RxBuffer_u8,2048);        //USB·¢ËÍ
//                    HAL_UART_Transmit(&huart1,RxBuffer_u8,2048,500);
                        if(++WriteReadAddr.Page>64)            //µØÖ·×Ô¼Ó
            {
                WriteReadAddr.Page=0;
                WriteReadAddr.Block=WriteReadAddr.Block+1;
                    if(WriteReadAddr.Block>1020)
                    {
                        Trans_flag=5;
                        HAL_UART_Transmit(&huart1,text1,12,500);
                    }
            }

        }
        else if(Trans_flag==3)   //²Á³ýNand FlashËùÓпé
        {
        HAL_UART_Transmit(&huart1,text4,13,500);
            for(j=0;j<1020;j++)
            {
        WriteReadAddr.Block=j;
        HAL_NAND_Erase_Block(&hnand1,&WriteReadAddr);
            }
            Trans_flag=5;
        HAL_UART_Transmit(&huart1,text4,13,500);
                                    WriteReadAddr.Block=0;
                        WriteReadAddr.Page=0;
                        WriteReadAddr.Plane=1;

        }

在各个部分分别实现对Nand的擦除,写入和读取的功能

实物展示说明

csAGnGEUVhNBwGydLy2F8DLj1wby8k4PFrGcsyqp.png

1206的贴片电阻,电容和电源指示灯

L51WaDoAukljWCSFf0FLnTBrAGXUS7u1Ew2KyRVn.png

Nand Flash验证板与正点原子的STM32F103核心板相连接(焊接的灯白色没加限流电阻太亮了)

 

 

设计图

未生成预览图,请在编辑器重新保存一次

BOM

暂无BOM

附件

序号文件名称下载次数
1
E1%UL_`TG)ONK]}]UL@MMT6.jpg
27
2
~1CTTTAVJ3O1GK}XGK5Z(_V.jpg
9
3
nand连续可读写.zip
148
4
NAND02G-B2D (1).pdf
29
5
MEMORY存储芯片NAND02GW3B2DN6E中文规格书.pdf
32
6
datasheet.pdf
26
克隆工程
添加到专辑
0
0
分享
侵权投诉

工程成员

评论

全部评论(1
按时间排序|按热度排序
粉丝0|获赞0
相关工程
暂无相关工程

底部导航