基于stm32f10c8t6 硬件spi 通信的w25q64的驱动读写及测试代码
时间: 2024-01-12 18:04:52 浏览: 26
以下是基于STM32F10C8T6硬件SPI通信的W25Q64驱动读写及测试代码:
```
#include "stm32f10x.h"
#include "SPI.h"
#include "W25Q64.h"
#define W25Q64_CS_HIGH() GPIO_SetBits(GPIOB, GPIO_Pin_12)
#define W25Q64_CS_LOW() GPIO_ResetBits(GPIOB, GPIO_Pin_12)
void W25Q64_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_5 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);
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);
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_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_Cmd(SPI1, ENABLE);
}
uint8_t W25Q64_ReadStatusRegister(uint8_t reg)
{
uint8_t data[] = {0x05, reg, 0x00};
uint8_t status;
W25Q64_CS_LOW();
SPI_Transfer(SPI1, data, &status, 3);
W25Q64_CS_HIGH();
return status;
}
void W25Q64_WriteStatusRegister(uint8_t reg, uint8_t value)
{
uint8_t data[] = {0x01, reg, value};
W25Q64_CS_LOW();
SPI_Transfer(SPI1, data, NULL, 3);
W25Q64_CS_HIGH();
}
void W25Q64_EraseChip(void)
{
uint8_t data[] = {0xC7, 0x94, 0x80, 0x9A};
W25Q64_WriteStatusRegister(0x01, 0x00);
W25Q64_CS_LOW();
SPI_Transfer(SPI1, data, NULL, 4);
W25Q64_CS_HIGH();
}
void W25Q64_EraseBlock(uint32_t address)
{
uint8_t data[] = {0xD8, (address >> 16) & 0xFF, (address >> 8) & 0xFF, address & 0xFF};
W25Q64_WriteStatusRegister(0x01, 0x00);
W25Q64_CS_LOW();
SPI_Transfer(SPI1, data, NULL, 4);
W25Q64_CS_HIGH();
}
void W25Q64_WritePage(uint32_t address, uint8_t *data, uint16_t length)
{
uint8_t cmd[] = {0x02, (address >> 16) & 0xFF, (address >> 8) & 0xFF, address & 0xFF};
W25Q64_WriteStatusRegister(0x01, 0x00);
W25Q64_CS_LOW();
SPI_Transfer(SPI1, cmd, NULL, 4);
SPI_Transfer(SPI1, data, NULL, length);
W25Q64_CS_HIGH();
}
void W25Q64_ReadData(uint32_t address, uint8_t *data, uint16_t length)
{
uint8_t cmd[] = {0x03, (address >> 16) & 0xFF, (address >> 8) & 0xFF, address & 0xFF};
W25Q64_CS_LOW();
SPI_Transfer(SPI1, cmd, NULL, 4);
SPI_Transfer(SPI1, NULL, data, length);
W25Q64_CS_HIGH();
}
void W25Q64_Test(void)
{
uint8_t data[] = "Hello, world!";
uint8_t readData[14];
W25Q64_EraseChip();
W25Q64_WritePage(0x000000, data, sizeof(data));
W25Q64_ReadData(0x000000, readData, sizeof(readData));
if (memcmp(data, readData, sizeof(data)) == 0)
{
printf("W25Q64 test successful!\n");
}
else
{
printf("W25Q64 test failed!\n");
}
}
int main(void)
{
W25Q64_Init();
W25Q64_Test();
while (1);
}
```
代码中,W25Q64_Init()函数用于初始化硬件SPI及GPIO;W25Q64_ReadStatusRegister()和W25Q64_WriteStatusRegister()函数用于读写状态寄存器;W25Q64_EraseChip()函数用于擦除整个芯片;W25Q64_EraseBlock()函数用于擦除一个块;W25Q64_WritePage()函数用于写入一页数据;W25Q64_ReadData()函数用于读取数据;W25Q64_Test()函数用于测试W25Q64,首先擦除整个芯片,然后写入数据并读取,最后比较读取的数据与写入的数据是否一致。
在主函数中,首先调用W25Q64_Init()函数进行初始化,然后调用W25Q64_Test()函数进行测试。