Nand Flash类型存储器使用接口形式与其他芯片实现信息交换。接口信息有三种类型,即命令信息、地址信息和数据信息。信息类型的区别通过控制引脚信号加以区别。现在单片机的FMC单元都具有Nand Flash控制功能。从编程角度来讲,把数据写到FMC控制单元的控制单元,发送的数据就是命令信息;数据写到FMC的地址单元,发送的数据就是地址信息;把数据写到FMC数据单元时,发送的就是数据信息。下面结合S34ML08G201TF1000芯片和STM32F429接口阐述以上三点的具体含义。
随着技术的发展单片机控制部件会越来越复杂,编程者已经很难直接编写单片机控制部件的初始化代码。编程者一般使用单片机生产厂家或第三方获取单片机部件初始化工具结合使用的接口芯片生成单片机控制部件的初始化代码。假定编程者已经通过STM公司提供的STM32CubeMX工具完成STM32F429控制S34ML08G201TF1000芯片的部件FMC的初始化。此时编程者只要使用FMC的存储空间操作S34ML08G201TF1000。STM32F429的FMC操作Nand Flash的存储空间分成两大类,一类是属性空间,另一类就是命令空间。这两类空间都有对应的存储器的基地址,也就是对芯片属性或命令空间的操作地址都是以这些为基础的,具体内容参见STM32F429数据手册1608页。无论属性空间还是命令空间,各自又进一步分成三个空间,注意这三个子空间地址都相对于各自的及地址。三个子空间分别为地址空间、命令空间和数据空间,具体内容参见STM32F429数据手册1609页。下面给出STM32F429控制S34ML08G201TF1000的代码片段。
1、写页数据
无论哪种存储操作都要三个信息,即地址、数据(数据总线)和命令。这三种信息不再使用总线实现,而是使用接口实现,即
//向Nand Flash芯片发送要访问的数据存储器芯片的内存地址
*(vu8 *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE0;
*(vu8 *)((uint32_t)(deviceaddress | ADDR_AREA)) = (u8)(ColNum);
*(vu8 *)((uint32_t)(deviceaddress | ADDR_AREA)) = (u8)(ColNum>>8);
*(vu8 *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
*(vu8 *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
*(vu8 *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
//本次使用FMC部件的Nand Flash的等待功能,不需要状态查询。
//向NAND Flash芯片发送数据
for(index=0; index < NumByteToWrite; index++)
{
*(vu8 *)deviceaddress=*(vu8 *)pBuffer++;
}
//向NAND Flash芯片发送写入操作命令(编程命令)
*(vu8 *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_WRITE_TRUE1;
//等待NAND Flash芯片完成代码片段
略
其中deviceaddress就是STM32F429存储空间基地址,对应于上面所述的FMC的属性空间或命令空间基地址;CMD_AREA、CMD_AREA和deviceaddress对应上面所述的FMC操作的三个子空间,即地址子空间、命令子空间和数据子空间。显然FMC发送地址给Nand Flash芯片使用了命令NAND_CMD_AREA_A,数据ColNum(存储器芯片页内偏移地址)和nandaddress(存储器芯片页地址)及命令NAND_CMD_AREA_TRUE1。FMC发送 NAND_CMD_WRITE_TRUE1命令就使NAND Flash芯片开始编程操作。
2、读页数据
存储器读操作也需要三个信息,它们也是通过接口实现的,即
//写地址
*(vu8 *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_A;
*(vu8 *)((uint32_t)(deviceaddress | ADDR_AREA)) = (u8)(ColNum);
*(vu8 *)((uint32_t)(deviceaddress | ADDR_AREA)) = (u8)(ColNum>>8);
*(vu8 *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandaddress);
*(vu8 *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandaddress);
*(vu8 *)((uint32_t)(deviceaddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandaddress);
*(vu8 *)((uint32_t)(deviceaddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
//本次使用FMC部件的Nand Flash的等待功能,所以不要查询状态
//读命令
NAND_WaitForReady(hnand);
*(__IO uint8_t *)((uint32_t)(deviceaddress | CMD_AREA)) = ((uint8_t)0x00);
__DSB();
//读数据
for(index=0; index < NumByteToRead; index++)
{
*(uint8_t *)pBuffer++ = *(uint8_t *)deviceaddress;
}
3、随机读取(略)
4、也拷贝
使用的S34ML08G201TFI000芯片页拷贝有点问题,即低页地址处的数据不能拷贝到高页地址处,是编程有问题还是其他什么问题?解决的最笨方法首先把要拷贝的页首先读出然后再写入既可以,但是这种解决方法相当费时!NAND Flashi页拷贝实质上是块拷贝,且只有同一个面上的页才能拷贝。