一、W25Q64 是华邦公司推出的大容量
SPI FLASH 产品,W25Q64 的容量为 64Mbit(8M),该系列还有 W25Q80/16/32 等。W25Q16,W25Q32,W25Q64分别有8192,16384,32768个可编程页,每页256字节,用扇区擦除指令每次可以擦除16页,用块擦除指令每次可以擦除256页,用整片擦除指令既可以擦除整个芯片,W25Q16,W25Q32,W25Q64分别有512,1024,2048个可擦除扇区,或者32,64,128个可擦除的块。
W25Q64 的擦写周期多达 10W 次,具有 20 年的数据保存期限,支持电压为 2.7~3.6V,
W25Q64 支持标准的 SPI,还支持双输出/四输出的 SPI,最大 SPI 时钟可以到 80Mhz(双输出时相当于 160Mhz,四输出时相当于 320M)。
指令如下:
读芯片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();
}
例如W25Q16的SPI Flash 16Mbit(2M)
一、芯片引脚