NAND Flash K60 Using

NAND Flash K60 Using

本系统使用了Freescale(NXP)的MK60D系列芯片+Keil的IDE编译环境+YANDLD编写的K60库

硬件接法

SPI Flash接法

程序

*初始化、读取芯片信息

     /* 初始化SPI接口 */
    SPI_QuickInit(SPI2_SCK_PD12_SOUT_PD13_SIN_PD14, kSPI_CPOL0_CPHA0, 30*1000*1000);

    /* 初始化片选*/
    PORT_PinMuxConfig(HW_GPIOD, 15, kPinAlt2); /* SPI2_PCS1 */

    /* 获取SPI-Flash信息 */

    if(w25qxx_init(HW_SPI2, HW_SPI_CS1))
    {
        printf("w25qxx device no found!\r\n");
    }
    else
    {
        struct w25qxx_attr_t w25qxx;
        w25qxx_get_attr(&w25qxx);
        printf("%s(0x%X) detected!\r\n", w25qxx.name, w25qxx.id);
        printf("total size:%dKB\r\n", w25qxx.size/1024);
        printf("block size:%dKB\r\n", w25qxx.block_size/1024);
        printf("sector size:%d\r\n", w25qxx.sector_size);
        printf("page size:%d\r\n", w25qxx.page_size);

        buf_size = sizeof(buf);
        block = w25qxx.size/buf_size;
    }

w25qxx_attr_t类型的结构体,在w25qxx.h中定义:

struct w25qxx_attr_t
{
    const char* name;
    uint32_t size;
    uint16_t id;
    uint32_t page_size;
    uint32_t sector_size;
    uint32_t block_size;
};

w25qxx_init(HW_SPI2, HW_SPI_CS1)函数中包括SPI选择、SPI模式、SPI片选、w25qxx_probe()获取芯片的信息:

//芯片初始化
int w25qxx_init(uint32_t instance, uint32_t cs)
{
    w25_dev.spi_instance = instance;
    w25_dev.spi_cs = cs; 
    SPI_CTARConfig(instance, HW_CTAR0, kSPI_CPOL0_CPHA0, 8, kSPI_MSB, 30*1000*1000);

    return w25qxx_probe();
}

再来看其中的w25qxx_probe()如何获取芯片信息:

//芯片探测
static int w25qxx_probe(void)
{
    uint32_t i;
    uint16_t id;
    uint8_t buf[2];

    /* read id */
    spi_xfer(W25X_ManufactDeviceID, kSPI_PCS_KeepAsserted);
    spi_xfer(0, kSPI_PCS_KeepAsserted);
    spi_xfer(0, kSPI_PCS_KeepAsserted);
    spi_xfer(0, kSPI_PCS_KeepAsserted);
    buf[0] = spi_xfer(0, kSPI_PCS_KeepAsserted);
    buf[1] = spi_xfer(0, kSPI_PCS_ReturnInactive);
    id = ((buf[0]<<8) + buf[1]);
    W25QXX_TRACE("ID:0x%X\r\n", id);
    //see if we find a match
    for(i = 0; i< ARRAY_SIZE(w25qxx_tbl);i++)
    {
        if(w25qxx_tbl[i].id == id)
        {
            /* find a match */
            w25_dev.attr = w25qxx_tbl[i];
            w25qxx_power_up();
            buf[0] = w25qxx_read_sr();
            W25QXX_TRACE("SR:0x%X\r\n", buf[0]);
            buf[0] = w25qxx_read_sr2();
            W25QXX_TRACE("SR2:0x%X\r\n", buf[0]);
            // enable full access to all memory regin, something like unlock chip.
            w25qxx_write_sr(0x00);
            return 0; 
        }
    }
    return 1;
}

通过:

    /* read id */
    spi_xfer(W25X_ManufactDeviceID, kSPI_PCS_KeepAsserted);
    spi_xfer(0, kSPI_PCS_KeepAsserted);
    spi_xfer(0, kSPI_PCS_KeepAsserted);
    spi_xfer(0, kSPI_PCS_KeepAsserted);
    buf[0] = spi_xfer(0, kSPI_PCS_KeepAsserted);
    buf[1] = spi_xfer(0, kSPI_PCS_ReturnInactive);
    id = ((buf[0]<<8) + buf[1]);
    W25QXX_TRACE("ID:0x%X\r\n", id);

获取芯片的ID信息,ID信息通过SPI访问芯片内部预先写好的寄存器

#define W25X_DeviceID           0xAB

然后根据ID查表,进行进一步匹配来获取芯片的其他信息:

//W25系列芯片信息
static const struct w25qxx_attr_t w25qxx_tbl[] = 
{
    {"W25Q10",    128*1024, 0xEF10, 256, 4096, (64*1024)},
    {"W25Q20",    256*1024, 0xEF11, 256, 4096, (64*1024)},
    {"W25Q40",    512*1024, 0xEF12, 256, 4096, (64*1024)},
    {"W25Q80",   1024*1024, 0xEF13, 256, 4096, (64*1024)},
    {"W25Q16",   2048*1024, 0xEF14, 256, 4096, (64*1024)},
    {"W25Q32",   4096*1024, 0xEF15, 256, 4096, (64*1024)},
    {"W25Q64",   8192*1024, 0xEF16, 256, 4096, (64*1024)},
    {"W25Q128", 16384*1024, 0xEF17, 256, 4096, (64*1024)}, 
};

读写Flash

预先设置两个buff,buf用来写入Flash,buf2用来读取Flash

static uint8_t buf[4*512];
static uint8_t buf2[4*512];

再对buf进行赋初值:

 for(j=0;j<sizeof(buf);j++)
   {
       buf[j] = j % 0xFF;
   }

新建两个变量:block,buf_size

uint32_t block,buf_size;
buf_size = sizeof(buf);
block = w25qxx.size/buf_size;

此处,block不是Flash的硬件Block,而是指将整个Flash根据Buf的大小,分为几块,故block = w25qxx.size/buf_size;
再写入数据,写入第3个block:

w25qxx_write(3*block, buf, buf_size);

再读取数据,并显示:

w25qxx_read(3*block, buf2, buf_size);
for(j=0;j<sizeof(buf2);j++)
{
    printf("writeData %d:%d------",j,buf[j]);
    printf("readData %d:%d\n\r",j,buf2[j]);
}

效果:

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值