基于stm32f10c8t6 硬件spi 通信的w25q64的驱动读写及测试代码
时间: 2024-01-12 20:04:53 浏览: 132
下面是基于stm32f10c8t6硬件spi通信的w25q64的驱动读写及测试代码:
驱动代码:
#include "stm32f10x.h"
#define W25Q64_CS_PIN GPIO_Pin_4
#define W25Q64_CS_PORT GPIOA
void W25Q64_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = W25Q64_CS_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(W25Q64_CS_PORT, &GPIO_InitStructure);
GPIO_SetBits(W25Q64_CS_PORT, W25Q64_CS_PIN);
}
void W25Q64_ChipSelect(uint8_t select)
{
if (select == 0)
{
GPIO_ResetBits(W25Q64_CS_PORT, W25Q64_CS_PIN);
}
else
{
GPIO_SetBits(W25Q64_CS_PORT, W25Q64_CS_PIN);
}
}
uint8_t W25Q64_SendByte(uint8_t txData)
{
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI1, txData);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
return SPI_I2S_ReceiveData(SPI1);
}
void W25Q64_WriteEnable(void)
{
W25Q64_ChipSelect(0);
W25Q64_SendByte(0x06);
W25Q64_ChipSelect(1);
}
void W25Q64_WriteDisable(void)
{
W25Q64_ChipSelect(0);
W25Q64_SendByte(0x04);
W25Q64_ChipSelect(1);
}
void W25Q64_EraseSector(uint32_t sectorAddr)
{
W25Q64_WriteEnable();
W25Q64_ChipSelect(0);
W25Q64_SendByte(0x20);
W25Q64_SendByte((sectorAddr>>16) & 0xff);
W25Q64_SendByte((sectorAddr>>8) & 0xff);
W25Q64_SendByte(sectorAddr & 0xff);
W25Q64_ChipSelect(1);
while ((W25Q64_ReadStatus() & 0x01) == 0x01);
}
void W25Q64_WritePage(uint32_t pageAddr, uint8_t *pData, uint32_t size)
{
W25Q64_WriteEnable();
W25Q64_ChipSelect(0);
W25Q64_SendByte(0x02);
W25Q64_SendByte((pageAddr>>16) & 0xff);
W25Q64_SendByte((pageAddr>>8) & 0xff);
W25Q64_SendByte(pageAddr & 0xff);
while (size--)
{
W25Q64_SendByte(*pData++);
}
W25Q64_ChipSelect(1);
while ((W25Q64_ReadStatus() & 0x01) == 0x01);
}
void W25Q64_ReadData(uint32_t addr, uint8_t *pData, uint32_t size)
{
W25Q64_ChipSelect(0);
W25Q64_SendByte(0x03);
W25Q64_SendByte((addr>>16) & 0xff);
W25Q64_SendByte((addr>>8) & 0xff);
W25Q64_SendByte(addr & 0xff);
while (size--)
{
*pData++ = W25Q64_SendByte(0xff);
}
W25Q64_ChipSelect(1);
}
uint8_t W25Q64_ReadStatus(void)
{
uint8_t status;
W25Q64_ChipSelect(0);
W25Q64_SendByte(0x05);
status = W25Q64_SendByte(0xff);
W25Q64_ChipSelect(1);
return status;
}
void W25Q64_WriteStatus(uint8_t status)
{
W25Q64_WriteEnable();
W25Q64_ChipSelect(0);
W25Q64_SendByte(0x01);
W25Q64_SendByte(status);
W25Q64_ChipSelect(1);
while ((W25Q64_ReadStatus() & 0x01) == 0x01);
}
测试代码:
#include "stm32f10x.h"
#include "w25q64.h"
int main(void)
{
uint8_t data[256];
uint32_t i;
uint8_t status;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
W25Q64_Init();
W25Q64_EraseSector(0x000000);
for (i = 0; i < 256; i++)
{
data[i] = i;
}
W25Q64_WritePage(0x000000, data, 256);
W25Q64_ReadData(0x000000, data, 256);
for (i = 0; i < 256; i++)
{
if (data[i] != i)
{
while (1);
}
}
status = W25Q64_ReadStatus();
status &= ~0x02;
status |= 0x02;
W25Q64_WriteStatus(status);
while (1);
}
阅读全文