关于W25Q32JVSSIQ的详细内容在之前的两篇文章中已经详细介绍,本文不做太多赘述,如果对芯片的了解有缺失的话,可以参考:
SPI协议——对外部SPI Flash操作-CSDN博客
SPI协议——读取外部SPI Flash ID_spi flash 读取id-CSDN博客
目录
一、代码编写
1.发送/接收单/多个字节的函数
2.实现扇区擦除
3.实现跨页写
4.读取数据
二、运行结果
一、代码编写
1.发送/接收单/多个字节的函数
这样设计代码可以随意选择自己是否忽略发送/接受的数据
void SPI_FLASH_Xfer(uint8_t *snd_buf, uint8_t *recv_buf, int bytes)
{int i;uint8_t send_data, recv_data;for(i = 0; i < bytes; i ++){send_data = (snd_buf != NULL) ? snd_buf[i] : 0xFF;recv_data = SPI_FLASH_SendByte(send_data);if( recv_buf != NULL ){recv_buf[i] = recv_data;}printf("Sending: 0x%02X, Received: 0x%02X\n", send_data, recv_data);}HAL_Delay(1);
}
2.实现扇区擦除
int New_SPI_FLASH_SectorErase(uint32_t addr, uint32_t size)
{uint32_t sector, first, last;uint32_t address;int rv;first = addr / Sector_Size;last = (addr + size - 1) / Sector_Size;/* Start to erase all sectors */for (sector = first; sector <= last; sector++){address = sector * Sector_Size;printf("Norflash Erase Sector@%lx ...\r\n", address);SPI1_FLASH_WaitEnd();SPI1_FLASH_WriteEnable();cs_low();SPI_FLASH_SendByte(0x20); // 发送扇区擦除命令/* Send the addr */SPI_FLASH_SendByte((address & 0xFF0000) >> 16);SPI_FLASH_SendByte((address & 0xFF00) >> 8);SPI_FLASH_SendByte(address & 0xFF);cs_high();// 确保擦除完成SPI1_FLASH_WaitEnd();HAL_Delay(10); // 增加延时,确保擦除完成}// 检查整个擦除区域是否已擦除rv = SPI_FLASH_VerifyErase(addr, size);if (rv != 0){printf("Erase the sector error\n");return -1;}else{printf("Erase ok\n");}return 0;
}
3.实现跨页写
int New_SPI_FLASH_PageWrite( uint32_t addr, uint8_t *data, uint32_t size)
{uint32_t first, last, page;uint32_t address, ofset, len;uint8_t buf[Page_Size+5];int bytes = 0;if( addr + size > 0x400000 )return -1;/* find the fist and the last page */first = addr / Page_Size;last = ( addr + size - 1 ) / Page_Size;printf("Norflash Write %ld Bytes to addr@0x%lx Begin...\r\n", size, addr );/*Initial address in page and offset in buffer */address = addr;ofset = 0;/* Start to write to all pages */for( page = first; page <= last; page ++){len = Page_Size - ( address % Page_Size );len = len > size ? size : len;bytes = 0;printf("Norflash write addr@0x%lx, %lu bytes,and the data is %s \r\n", addr, len, data);buf[bytes++] = 0x02;buf[bytes++] = (addr & 0xFF0000) >> 16 ;buf[bytes++] = (addr & 0xFF00) >> 8 ;buf[bytes++] = (addr & 0xFF);/* send command and data */memcpy(&buf[bytes], data+ofset, len);bytes += len;printf("Norflash write addr@0x%lx, %lu bytes, data : ", address, len);for( int i = 4; i < bytes; i++ ){printf("0x%02x", buf[i]);printf("\n");}SPI1_FLASH_WriteEnable();cs_low();SPI_FLASH_Xfer(buf, NULL, bytes);cs_high();SPI1_FLASH_WaitEnd();addr += len;ofset += len;size -= len;}HAL_Delay(10);printf("Norflash WriteByte@0x%lx done.\r\n", addr);return 0;}
4.读取数据
void New_SPI_FLASH_BufferRead(uint32_t addr, uint8_t *buffer, uint32_t size)
{uint8_t cmd[4];cmd[0] = 0x03; // Read Data commandcmd[1] = (addr >> 16) & 0xFF;cmd[2] = (addr >> 8) & 0xFF;cmd[3] = addr & 0xFF;cs_low();//发送读取命令和地址SPI_FLASH_Xfer(cmd, NULL, 4);//读取数据SPI_FLASH_Xfer(NULL, buffer, size);cs_high();// 调试输出,可选项,用于验证发送的命令和接收到的数据
/* printf("SPI Flash Read: Address = 0x%lx, Data: ", addr);for (int i = 0; i < size; i++){printf("0x%02x ", buffer[i]);}printf("\n");*/
}
二、运行结果