flash-W25Q32BV的读写

来源:互联网 发布:家装软件app 编辑:程序博客网 时间:2024/05/29 07:10

调试了两天的flash,测试应该是没问题的了。在调试中发现,1、擦除的是时候最小是4k擦除,擦除是擦除我们给的地址所在的4k空间;2、写入数据时,如果地址在4k空间的尾部时,当写入长度跨过了4k空间,到了下一个4k的空间时,写数据不成功(读出来不正确),刚刚想到也有可能是我的下一个4k空间没有擦除,导致我写入数据不正确;3、当我读数据读到当前4k空间的尾部时,如果要读取的长度超出到了下一空间,读出来的数据仍然是正确的。有三个结论:擦除时,擦除我们给的地址所在的4k空间(用4k擦除命令);写数据时,地址过到下一个4k空间时,数据不能正常写入(需要再次验证);读数据时,地址过到下一个4k空间时,数据能正常读出。

W25Q32BV是一款挺强大的flash,我只是弄了最简单的一种读取方式。搜索的时候发现没什么相关代码,我弄好了,就让我分享一下我自己的,让大家见笑了。有不对之处请大家海涵并指出。

下面是代码,我用的板子是AM824,硬件SPI。



/**
 *  flash检查是否能接收命令,并等待到能接收为止
 */
void check()
{
    
    uint8_t temp;
    
    do {
        flash_cs(0);
        spi_sent_byte(AMHW_LPC82X_SPI0, 0x05);
        temp = spi_sent_byte(AMHW_LPC82X_SPI0, 0x77);  
        flash_cs(1);
    } while (temp & 0x01);
}


/**
 * flash写使能,在擦除和写入数据前,要调用写使能
 */
void wri_en()
{
    flash_cs(0);
    am_udelay(10);
    spi_sent_byte(AMHW_LPC82X_SPI0, 0x06);  
    flash_cs(1);
}


/**
 * flash 擦除函数
 * addr : 要擦除的地址
 */
void erase(uint32_t addr)
{
    uint32_t temp;
    
    wri_en();
    temp = addr & 0x00ffffff;
    flash_cs(0);
    spi_sent_byte(AMHW_LPC82X_SPI0, 0x20); 
    temp = addr>>16;
    spi_sent_byte(AMHW_LPC82X_SPI0, temp);
    temp = addr>>8;
    spi_sent_byte(AMHW_LPC82X_SPI0, temp);
    temp = addr;
    spi_sent_byte(AMHW_LPC82X_SPI0, temp);
    flash_cs(1);


    check();
}
在写数据之前,要先对地址所在的扇区进行擦除,否则数据可能会出错。


/**
 *  flash写入数据
 * addr : 要存放在flash哪个地方
 * buff : 要写入flash的数据缓存
 * lenth :要写入的数据长度
 */
int write(uint32_t addr,uint8_t *buff, uint8_t lenth)
{
    uint8_t temp = 0;
    uint8_t i = 0;
    
    if (buff == NULL || lenth == 0) {
        return -1;
    }
    
    temp = addr & 0x00ffffff;
    wri_en();
    
    flash_cs(0);
    am_udelay(10);
    spi_sent_byte(AMHW_LPC82X_SPI0, 0x02);
    temp = addr>>16;
    spi_sent_byte(AMHW_LPC82X_SPI0, temp);
    temp = addr>>8;
    spi_sent_byte(AMHW_LPC82X_SPI0, temp);
    temp = addr;
    spi_sent_byte(AMHW_LPC82X_SPI0, temp);
    
    for (i = 0; i < lenth; i++) {
        spi_sent_byte(AMHW_LPC82X_SPI0, buff[i]);
    }
  
    flash_cs(1);


    check();
    
    return 0;
}


/**
 * flash读数据
 * addr : 地址
 * buff : 将读出的数据保存在数组里
 * lenth :要读出的数据长度
 */
int read(uint32_t addr, uint8_t *buff, uint8_t lenth)
{
    uint8_t temp = 0;
    uint8_t i = 0;
    
    if (buff == NULL || lenth == 0) {
        return -1;
    }
    
    temp = addr & 0x00ffffff;
 
    flash_cs(0);
    am_udelay(10);
    spi_sent_byte(AMHW_LPC82X_SPI0, 0x03);
    temp = addr>>16;
    spi_sent_byte(AMHW_LPC82X_SPI0, temp);
    temp = addr>>8;
    spi_sent_byte(AMHW_LPC82X_SPI0, temp);
    temp = addr;
    spi_sent_byte(AMHW_LPC82X_SPI0, temp);
    
    for (i = 0; i < lenth; i++) {
       buff[i] = spi_sent_byte(AMHW_LPC82X_SPI0, 0);
    }  
    
    flash_cs(1);
    
    check();    
    
    return 0;
}
0 0