WinBond FLASH WX25X存储芯片学习1

W25X64 是华邦公司推出的大容量
SPI FLASH 产品,W25X64 的容量为 64Mbit(8M),该系列还有 W25Q80/16/32 等。
W25X16,W25X32,W25X64分别有8192,16384,32768个可编程页,每页256字节,用扇区擦除指令每次可以擦除16页,用块擦除指令每次可以擦除256页,用整片擦除指令既可以擦除整个芯片,W25X16,W25X32,W25X64分别有512,1024,2048个可擦除扇区,或者32,64,128个可擦除的块。
W25Q64 的擦写周期多达 10W 次,具有 20 年的数据保存期限,支持电压为 2.7~3.6V,
W25Q64 支持标准的 SPI,还支持双输出/四输出的 SPI,最大 SPI 时钟可以到 80Mhz(双输出时相当于 160Mhz,四输出时相当于 320M)。
指令如下:
在这里插入图片描述
指令宏定义:
#define WINBOND_WRITE_ENABLE 0x06
#define WINBOND_READ_SR1 0x05
#define WINBOND_READ_SR2 0x35
#define WINBOND_WRITE_SR1 0x01
#define WINBOND_WRITE_SR2 0x31
#define WINBOND_READ_DATA 0x03
#define WINBOND_FAST_READ_DATA 0x0b
#define WINBOND_FAST_READ_DUAL_OUTPUT 0x3b
#define WINBOND_PAGE_PROGRAM 0x02
#define WINBOND_PAGE_ERASE 0x81
#define WINBOND_SECTOR_ERASE 0x20
#define WINBOND_BLOCK_ERASE 0xD8
#define WINBOND_CHIP_ERASE 0xC7
#define WINBOND_JEDEC_ID 0x9F

擦除枚举类型:
enum {
FLASH_PAGE_ERASER,//页擦除
FLASH_SECTOR_ERASER,//扇区擦除
FLASH_BLOCK_ERASER,//块擦除
FLASH_CHIP_ERASER,//整片擦除
};

在这里插入图片描述

读芯片ID:
static u32 _norflash_read_id()//读norflash芯片ID
{
u8 id[3];
spi_cs_l();
spi_write_byte(WINBOND_JEDEC_ID);//读ID指令
for (u8 i = 0; i < sizeof(id); i++) {
id[i] = spi_read_byte();
}
spi_cs_h();
return id[0] << 16 | id[1] << 8 | id[2];
}
读取芯片ID可以用来判断芯片容量。

3字节地址仅能表示16MB的地址空间
超过16MB需使用4字节表示地址
对norflash操作,发送地址
norflash有两种模式:3字节地址、4字节地址,3字节地址norflash最大16MB
static void _norflash_send_addr(u32 addr)//发送地址
{
if (is4byte_mode) {//4字节模式
spi_write_byte(addr >> 24);
}
spi_write_byte(addr >> 16);
spi_write_byte(addr >> 8);
spi_write_byte(addr);
}
使用标志来判断选择是24位地址还是32位地址。

以下两个函数用来配置芯片使用24位地址还是32位地址:
void norflash_enter_4byte_addr()//退出4字节模式
{
spi_cs_l();
spi_write_byte(0xb7);//B7指令表示配置norflash进入4字节模式
spi_cs_h();
}
void norflash_exit_4byte_addr()//进入4字节模式
{
spi_cs_l();
spi_write_byte(0xe9);//E9指令表示配置norflash退出4字节模式
spi_cs_h();
}
在这里插入图片描述
在这里插入图片描述
擦除操作:
int _norflash_eraser(u8 eraser, u32 addr)//擦除
{
u8 eraser_cmd;
switch (eraser) {
case FLASH_PAGE_ERASER://页擦除
eraser_cmd = WINBOND_PAGE_ERASE;//页擦除指令
addr = addr / 256 * 256;//计算页对齐地址
break;
case FLASH_SECTOR_ERASER://扇区擦除
eraser_cmd = WINBOND_SECTOR_ERASE;//扇区擦除指令
//r_printf(“>>>[test]:addr = %d\n”, addr);
addr = addr / 4096 * 4096;//计算扇区对齐地址
break;
case FLASH_BLOCK_ERASER://块擦除
eraser_cmd = WINBOND_BLOCK_ERASE;//块擦除指令
addr = addr / 65536 * 65536;//计算块对齐地址
break;
case FLASH_CHIP_ERASER://整片擦除
eraser_cmd = WINBOND_CHIP_ERASE;//整片擦除指令
break;
}
_norflash_send_write_enable();//使能写
spi_cs_l();//片选使能
spi_write_byte(eraser_cmd);//写指令
if (eraser_cmd != WINBOND_CHIP_ERASE) {//如果不是整片擦除
_norflash_send_addr(addr);//需要写入地址
}
spi_cs_h();//片选禁能
return _norflash_wait_ok();//等待完成
}
擦除有多种擦除:块、扇区、整片。
擦除时需要设置要擦除的地址。
擦除指令发送后,需要等待擦除完成。

等待函数如下:
//返回1表示忙
//返回0表示不忙
static int _norflash_wait_ok()//等待norflash操作完成
{
u32 timeout = 8 * 1000 * 1000 / 100;
while (timeout–) {
spi_cs_l();//片选拉低,选中spi外设
spi_write_byte(WINBOND_READ_SR1);//发送读状态寄存器命令
u8 reg_1 = spi_read_byte();//接收状态寄存器值
spi_cs_h();//片选拉高
if (!(reg_1 & BIT(0))) {//状态寄存器最低位0表示不忙,1表示忙
break;
}
delay(100);
}
if (timeout == 0) {
log_error(“norflash_wait_ok timeout!\r\n”);
return 1;
}
return 0;
}

擦除操作前必须写使能:
static void _norflash_send_write_enable()//写使能
{
spi_cs_l();
spi_write_byte(WINBOND_WRITE_ENABLE);//发送写使能指令
spi_cs_h();
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值