片外FLASH(W25Q)和EEPROM(AT24c02)比较

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言


一、W25QXX

1、基本概念

  1. W25QXX系列FLASH芯片的容量:

1块=16扇区;1扇区=16页;1页=256字节;
W25Q64的最小擦除单位为一个扇区,也就是每次必须擦除4K个字节。所以,这需要给W25Q64开辟一个至少4K的缓存区,这样必须要求芯片有4K以上的SRAM才能有很好的操作。

在这里插入图片描述

  1. W25QXX系列FLASH芯片不同型号的ID
型号ID
W25Q800XEF13
W25Q160XEF14
W25Q320XEF15
W25Q640XEF16
W25Q1280XEF17
W25Q2560XEF18
W25Q5120XEF19
  1. FLASH芯片只能按扇区、块为单位擦除,或者是全片擦除。写可以1~256字节写,一次最多写256字节 。
  2. W25Q16、W25Q32、W25Q64、W25Q128的内存地址为3字节(3x8=24bit);但是W25Q256和W25Q512的内存空间地址为4字节(4x8=32bit);需要注意:因为这个内存空间地址字节数不同,我们在写W25Q256和W25Q512的驱动时,前面的几种型号芯片程序就无法和这两个芯片的驱动直接兼容,需要修改指令后跟的地址(由原来的三字节改为四字节)才行。

2、芯片引脚介绍与原理图

在这里插入图片描述
在这里插入图片描述

编号标识功能
1/CS片选
2DO
3/WP写保护(低电平有效)
4GND
5VCC
6/HOLD保持端输入,允许芯片暂停工作(低电平有效)
7CLK
8DI

3、SPI工作原理

  • 硬件上为4根线。
  • 主机和从机都有一个串行移位寄存器,主机通过向它的SPI串行寄存器写入一个字节来发起一次传输。
  • 串行移位寄存器通过MOSI信号线将字节传送给从机,从机也将自己的串行移位寄存器中的内容通过 - MISO信号线返回给主机。这样,两个移位寄存器中的内容就被交换
  • 外设的写操作和读操作是同步完成的。如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输

待更新。。。。。。

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是stm32f103c8t6模拟iIC驱动at24c02和模拟spi驱动的w25q64的代码示例: 模拟iIC驱动at24c02代码: ``` #include "stm32f10x.h" #define ADDR_AT24C02 0xA0 void I2C1_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE); } void I2C1_Mode_Config(void) { I2C_InitTypeDef I2C_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); I2C_DeInit(I2C1); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = 0x00; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = 100000; I2C_Init(I2C1, &I2C_InitStructure); I2C_Cmd(I2C1, ENABLE); } uint8_t I2C1_WriteByte(uint8_t dev_addr, uint8_t reg_addr, uint8_t data) { I2C_GenerateSTART(I2C1, ENABLE); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1, dev_addr, I2C_Direction_Transmitter); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C1, reg_addr); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_SendData(I2C1, data); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTOP(I2C1, ENABLE); return 0; } uint8_t I2C1_ReadByte(uint8_t dev_addr, uint8_t reg_addr) { uint8_t data; I2C_GenerateSTART(I2C1, ENABLE); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1, dev_addr, I2C_Direction_Transmitter); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C1, reg_addr); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTART(I2C1, ENABLE); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1, dev_addr, I2C_Direction_Receiver); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); I2C_AcknowledgeConfig(I2C1, DISABLE); I2C_GenerateSTOP(I2C1, ENABLE); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); data = I2C_ReceiveData(I2C1); return data; } void AT24C02_Write(uint8_t addr, uint8_t data) { I2C1_WriteByte(ADDR_AT24C02, addr, data); } uint8_t AT24C02_Read(uint8_t addr) { return I2C1_ReadByte(ADDR_AT24C02, addr); } int main() { I2C1_GPIO_Config(); I2C1_Mode_Config(); uint8_t data = 0x55; AT24C02_Write(0x00, data); data = AT24C02_Read(0x00); while (1); } ``` 模拟spi驱动的w25q64代码: ``` #include "stm32f10x.h" #include "spi.h" #include "w25q64.h" void W25Q64_Init(void) { SPI2_Init(); GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB, GPIO_Pin_12); } uint8_t W25Q64_ReadSR1(void) { uint8_t cmd = W25Q64_CMD_READ_SR1; uint8_t sr1; GPIO_ResetBits(GPIOB, GPIO_Pin_12); SPI2_WriteByte(cmd); sr1 = SPI2_ReadByte(); GPIO_SetBits(GPIOB, GPIO_Pin_12); return sr1; } void W25Q64_WriteEnable(void) { uint8_t cmd = W25Q64_CMD_WRITE_ENABLE; GPIO_ResetBits(GPIOB, GPIO_Pin_12); SPI2_WriteByte(cmd); GPIO_SetBits(GPIOB, GPIO_Pin_12); } void W25Q64_EraseChip(void) { uint8_t cmd = W25Q64_CMD_ERASE_CHIP; W25Q64_WriteEnable(); GPIO_ResetBits(GPIOB, GPIO_Pin_12); SPI2_WriteByte(cmd); GPIO_SetBits(GPIOB, GPIO_Pin_12); while (W25Q64_ReadSR1() & 0x01); } void W25Q64_WritePage(uint32_t addr, uint8_t *data, uint16_t len) { uint8_t cmd[4]; uint32_t i; cmd[0] = W25Q64_CMD_PAGE_PROGRAM; cmd[1] = (addr >> 16) & 0xFF; cmd[2] = (addr >> 8) & 0xFF; cmd[3] = addr & 0xFF; W25Q64_WriteEnable(); GPIO_ResetBits(GPIOB, GPIO_Pin_12); for (i = 0; i < 4; i++) { SPI2_WriteByte(cmd[i]); } for (i = 0; i < len; i++) { SPI2_WriteByte(data[i]); } GPIO_SetBits(GPIOB, GPIO_Pin_12); while (W25Q64_ReadSR1() & 0x01); } void W25Q64_ReadData(uint32_t addr, uint8_t *data, uint16_t len) { uint8_t cmd[4]; uint32_t i; cmd[0] = W25Q64_CMD_READ_DATA; cmd[1] = (addr >> 16) & 0xFF; cmd[2] = (addr >> 8) & 0xFF; cmd[3] = addr & 0xFF; GPIO_ResetBits(GPIOB, GPIO_Pin_12); for (i = 0; i < 4; i++) { SPI2_WriteByte(cmd[i]); } for (i = 0; i < len; i++) { data[i] = SPI2_ReadByte(); } GPIO_SetBits(GPIOB, GPIO_Pin_12); } int main() { W25Q64_Init(); uint8_t data[256]; uint32_t i; for (i = 0; i < 256; i++) { data[i] = i; } W25Q64_EraseChip(); for (i = 0; i < 65536; i += 256) { W25Q64_WritePage(i, data, 256); } for (i = 0; i < 65536; i += 256) { W25Q64_ReadData(i, data, 256); /* do something with data */ } while (1); } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值