STM32
直播中

ejlwj

8年用户 913经验值
擅长:处理器/DSP
私信 关注
[问答]

如何去实现stm32的W25Q64程序代码呢

如何去实现STM32的W25Q64程序代码呢?

回帖(1)

余正成

2021-12-17 11:45:51
W25Q64





















SPI配置步骤

1.使能SPI时钟
2.使能GPIO端口时钟
3.初始化GPIO,配置引脚模式
4.初始化SPI
5.使能SPI
6.SPI读写数据
7.查看SPI传输状态








举例









































  typedef struct
  {
  uint16_t SPI_Direction;
  uint16_t SPI_Mode;
  uint16_t SPI_DataSize; //数据帧格式
  uint16_t SPI_CPOL; //时钟极性
  uint16_t SPI_CPHA; //时钟相位
  uint16_t SPI_NSS; //软件从设备管理
  uint16_t SPI_BaudRatePrescaler; //波特率控制
  uint16_t SPI_FirstBit; //帧格式
  uint16_t SPI_CRCPolynomial; //CRC多项式寄存器
  }SPI_InitTypeDef;
  #define EN25X_WriteEnable 0x06
  #define EN25X_WriteDisable 0x04
  #define EN25X_ReadStatusReg 0x05
  #define EN25X_WriteStatusReg 0x01
  #define EN25X_ReadData 0x03
  #define EN25X_FastReadData 0x0B
  #define EN25X_FastReadDual 0x3B
  #define EN25X_PageProgram 0x02
  #define EN25X_BlockErase 0xD8
  #define EN25X_SectorErase 0x20
  #define EN25X_ChipErase 0xC7
  #define EN25X_PowerDown 0xB9
  #define EN25X_Continue_Read 0xFF
  #define EN25X_ReleasePowerDown 0xAB
  #define EN25X_DeviceID 0xAB
  #define EN25X_ManufactDeviceID 0x90
  #define EN25X_JedecDeviceID 0x9F
  void SPI_init()
  {
  GPIO_InitTypeDef gpio =
  {
  GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15,
  GPIO_Speed_50MHz,
  GPIO_Mode_AF_PP
  };
  SPI_InitTypeDef spi =
  {
  SPI_Direction_2Lines_FullDuplex,
  SPI_Mode_Master, //0x0104
  SPI_DataSize_8b,
  SPI_CPOL_High,
  SPI_CPHA_2Edge,
  SPI_NSS_Soft,
  SPI_BaudRatePrescaler_256,
  SPI_FirstBit_MSB,
  7
  };
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); //使能SPI时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIO端口时钟
  GPIO_Init(GPIOB, &gpio); //初始化GPIO,配置引脚模式
  SPI_Init(SPI2, &spi); //初始化SPI
  SPI_Cmd(SPI2, ENABLE); //使能SPI
  }
  void SPI2_SetSpeed(u8 rate)
  {
  SPI2-》CR1 &= 0xFFC7;
  SPI2-》CR1 |= rate;
  SPI_Cmd(SPI2, ENABLE);
  }
  void EN25Q64_init()
  {
  GPIO_InitTypeDef gpiob =
  {
  GPIO_Pin_12,
  GPIO_Speed_50MHz,
  GPIO_Mode_Out_PP
  };
  GPIO_InitTypeDef gpiog13 =
  {
  GPIO_Pin_13,
  GPIO_Speed_50MHz,
  GPIO_Mode_Out_PP
  };
  GPIO_InitTypeDef gpiog14 =
  {
  GPIO_Pin_13,
  GPIO_Speed_50MHz,
  GPIO_Mode_Out_PP
  };
  GPIO_InitTypeDef gpiof =
  {
  GPIO_Pin_9,
  GPIO_Speed_50MHz,
  GPIO_Mode_Out_PP
  };
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOG | RCC_APB2Periph_GPIOF, ENABLE);
  GPIO_Init(GPIOB, &gpiob);
  SPI2_NSS = 1; //以太网模块片选(拉高,防止干扰)
  GPIO_Init(GPIOG, &gpiog13);
  FLASH_CS = 1; //FLASH片选
  GPIO_Init(GPIOG, &gpiog14);
  SD_CS = 1; //SD卡模块片选
  GPIO_Init(GPIOF, &gpiof);
  TUB_4 = 1; //NRF24L01模块片选
  SPI_init();
  }
  u8 SPI_read_write(u16 d) //SPI读写数据
  {
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) != SET);
  SPI_I2S_SendData(SPI2, d);
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) != SET);
  return SPI_I2S_ReceiveData(SPI2);
  }
  u16 EN25Q64_read_id()
  {
  u16 r;
  FLASH_CS = 0;
  SPI_read_write(EN25X_ManufactDeviceID);
  SPI_read_write(0); //dummy
  SPI_read_write(0);
  SPI_read_write(0);
  r = SPI_read_write(EN25X_Continue_Read) 《《 8;
  r = SPI_read_write(EN25X_Continue_Read);
  FLASH_CS = 1;
  return r;
  }
  void EN25Q64_read_unique_id(u8 *id)
  {
  int i = 0;
  FLASH_CS = 0;
  SPI_read_write(0x4B);
  SPI_read_write(0); //dummy
  SPI_read_write(0);
  SPI_read_write(0);
  SPI_read_write(0);
  for(i = 0; i 《 8; i++)
  {
  id[i] = SPI_read_write(0xFF);
  }
  FLASH_CS = 1;
  }
  u8 EN25Q64_read_status()
  {
  u8 r;
  FLASH_CS = 0;
  SPI_read_write(EN25X_ReadStatusReg);
  r = SPI_read_write(EN25X_Continue_Read);
  FLASH_CS = 1;
  return r;
  }
  void EN25Q64_read(u8 *buf, u32 addr, u16 num)
  {
  u16 i = 0;
  FLASH_CS = 0;
  SPI_read_write(EN25X_ReadData);
  SPI_read_write((u8)(addr) 》》 16); //24bit地址
  SPI_read_write((u8)(addr) 》》 8);
  SPI_read_write((u8)addr);
  for(i = 0; i 《 num; i++)
  {
  buf[i] = SPI_read_write(EN25X_Continue_Read);
  }
  FLASH_CS = 1;
  }
  void EN25Q64_write_enable()
  {
  FLASH_CS = 0;
  SPI_read_write(EN25X_WriteEnable);
  FLASH_CS = 1;
  }
  void EN25Q64_write_disable()
  {
  FLASH_CS = 0;
  SPI_read_write(EN25X_WriteEnable);
  FLASH_CS = 1;
  }
  void EN25Q64_write_status(u8 s)
  {
  FLASH_CS = 0;
  SPI_read_write(EN25X_WriteDisable);
  SPI_read_write(s);
  FLASH_CS = 1;
  }
  void EN25Q64_is_busy()
  {
  while((EN25Q64_read_status() & 0x01) == 0x01); //BUSY
  }
  void EN25Q64_write_page(u8 *buf, u32 addr, u16 num) //页写
  {
  u16 i = 0;
  EN25Q64_write_enable();
  FLASH_CS = 0;
  SPI_read_write(EN25X_PageProgram); //Page Program
  SPI_read_write(addr 》》 16);
  SPI_read_write(addr 》》 8);
  SPI_read_write(addr);
  for(i = 0; i 《 num; i++)
  {
  SPI_read_write(buf[i]);
  }
  FLASH_CS = 1;
  EN25Q64_is_busy();
  }
  void EN25Q64_write_nocheck(u8 *buf, u32 addr, u16 num)
  {
  u8 *b = buf;
  u32 a = addr;
  u16 n = num;
  n = 256 - (num % 256); //写满一页
  while(1)
  {
  EN25Q64_write_page(b, a, n);
  if(n == num)
  {
  break;
  }
  b += n;
  a += n;
  num -= n;
  if(num 》 256)
  {
  n = 256;
  }
  else
  {
  n = num;
  }
  }
  }
  void EN25Q64_sector_erase(u32 a)
  {
  EN25Q64_write_enable();
  EN25Q64_is_busy();
  FLASH_CS = 0;
  SPI_read_write(EN25X_SectorErase);
  SPI_read_write((u8)a 》》 16);
  SPI_read_write((u8)a 》》 8);
  SPI_read_write(a);
  FLASH_CS = 1;
  EN25Q64_is_busy();
  }
  u8 EN25QXX_BUF[4096];
  void EN25Q64_write(u8 *buf, u32 addr, u16 num)
  {
  u16 i;
  u32 pos;
  u16 offset;
  u16 n;
  u8 *b = buf;
  pos = addr / 4096; //扇区位置
  offset = addr % 4096;
  n = 4096 - offset ; //写满扇区
  if(num 《= n)
  {
  n = num;
  }
  while(1)
  {
  EN25Q64_read(EN25QXX_BUF, pos * 4096, 4096); //读出整个扇区
  EN25Q64_sector_erase(pos); //擦除整个扇区
  for(i = 0; i 《 n; i++)
  {
  EN25QXX_BUF[i + offset] = b[i];
  }
  EN25Q64_write_nocheck(EN25QXX_BUF, pos * 4096, 4096); //写入整个扇区
  if(n == num)
  {
  break;
  }
  pos++;
  num -= n;
  offset = 0;
  b += n;
  if(num 》 4096)
  {
  n = 4096;
  }
  else
  {
  n = num;
  }
  }
  }
  void EN25Q64_chip_erase()
  {
  EN25Q64_write_enable();
  EN25Q64_is_busy();
  FLASH_CS = 0;
  SPI_read_write(EN25X_ChipErase);
  FLASH_CS = 1;
  EN25Q64_is_busy();
  }
  void EN25Q64_power_down()
  {
  FLASH_CS = 0;
  SPI_read_write(EN25X_PowerDown);
  FLASH_CS = 1;
  delay_us(3);
  }
  void EN25Q64_release_power_down()
  {
  FLASH_CS = 0;
  SPI_read_write(EN25X_ReleasePowerDown);
  FLASH_CS = 1;
  delay_us(3);
  }

举报

更多回帖

发帖
×
20
完善资料,
赚取积分