K028 基于51/STM32 W25Q64模块读写测试 串口打印读取值
一. 实现功能
上电按在复位键后串口打印之前存储进去的数据
二. 硬件清单
- W25Q64模块
- STM32F103C8T6/STC89C52RC
- SWD或JLINK仿真器(直接用CH340串口模块烧录也行,不过注意配置BOOT)
- 杜邦线若干
三. 资料清单
程序代码
文档资料
四. 模块简介
1.基本参数
2.引脚说明
五. 接线
基于STM32 + W25Q64模块接线
模块---------------------------------- STM32
VCC-------------------------------------3.3V
GND-------------------------------------GND
CS----------------- ----------------- - -- GPIOA_4
MOSI ----------------- ----------------- - GPIOA_7
SCK ------------------ ----------------- - GPIOA_5
MISO ------------------ ----------------- GPIOA_6
基于51 + W25Q64模块接线
模块----------------------------------STC89C52RC
VCC-------------------------------------3.3V
GND-------------------------------------GND
CS----------------- ----------------- - --P1.0
MOSI ----------------- ----------------- - P1.1
SCK ------------------ ----------------- - P1.2
MISO ------------------ ----------------- P1.3
六.代码说明
以下以32代码为例
1. 引脚及硬件SPI配置
void SPI_FLASH_Init(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
FLASH_SPI_APBxClock_FUN ( FLASH_SPI_CLK, ENABLE );
FLASH_SPI_CS_APBxClock_FUN ( FLASH_SPI_CS_CLK|FLASH_SPI_SCK_CLK|
FLASH_SPI_MISO_PIN|FLASH_SPI_MOSI_PIN, ENABLE );
GPIO_InitStructure.GPIO_Pin = FLASH_SPI_CS_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(FLASH_SPI_CS_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FLASH_SPI_SCK_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(FLASH_SPI_SCK_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FLASH_SPI_MISO_PIN;
GPIO_Init(FLASH_SPI_MISO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FLASH_SPI_MOSI_PIN;
GPIO_Init(FLASH_SPI_MOSI_PORT, &GPIO_InitStructure);
SPI_FLASH_CS_HIGH();
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_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(FLASH_SPIx , &SPI_InitStructure);
SPI_Cmd(FLASH_SPIx , ENABLE);
}
2. 模块读写函数
u8 SPI_FLASH_ReadByte(void)
{
return (SPI_FLASH_SendByte(Dummy_Byte));
}
u8 SPI_FLASH_SendByte(u8 byte)
{
SPITimeout = SPIT_FLAG_TIMEOUT;
while (SPI_I2S_GetFlagStatus(FLASH_SPIx , SPI_I2S_FLAG_TXE) == RESET)
{
if((SPITimeout--) == 0) return SPI_TIMEOUT_UserCallback(0);
}
SPI_I2S_SendData(FLASH_SPIx , byte);
SPITimeout = SPIT_FLAG_TIMEOUT;
while (SPI_I2S_GetFlagStatus(FLASH_SPIx , SPI_I2S_FLAG_RXNE) == RESET)
{
if((SPITimeout--) == 0) return SPI_TIMEOUT_UserCallback(1);
}
return SPI_I2S_ReceiveData(FLASH_SPIx );
}
u16 SPI_FLASH_SendHalfWord(u16 HalfWord)
{
SPITimeout = SPIT_FLAG_TIMEOUT;
while (SPI_I2S_GetFlagStatus(FLASH_SPIx , SPI_I2S_FLAG_TXE) == RESET)
{
if((SPITimeout--) == 0) return SPI_TIMEOUT_UserCallback(2);
}
SPI_I2S_SendData(FLASH_SPIx , HalfWord);
SPITimeout = SPIT_FLAG_TIMEOUT;
while (SPI_I2S_GetFlagStatus(FLASH_SPIx , SPI_I2S_FLAG_RXNE) == RESET)
{
if((SPITimeout--) == 0) return SPI_TIMEOUT_UserCallback(3);
}
return SPI_I2S_ReceiveData(FLASH_SPIx );
}
3. 模块部分功能函数
u32 SPI_FLASH_ReadID(void)
{
u32 Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;
SPI_FLASH_CS_LOW();
SPI_FLASH_SendByte(W25X_JedecDeviceID);
Temp0 = SPI_FLASH_SendByte(Dummy_Byte);
Temp1 = SPI_FLASH_SendByte(Dummy_Byte);
Temp2 = SPI_FLASH_SendByte(Dummy_Byte);
SPI_FLASH_CS_HIGH();
Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;
return Temp;
}
u32 SPI_FLASH_ReadDeviceID(void)
{
u32 Temp = 0;
SPI_FLASH_CS_LOW();
SPI_FLASH_SendByte(W25X_DeviceID);
SPI_FLASH_SendByte(Dummy_Byte);
SPI_FLASH_SendByte(Dummy_Byte);
SPI_FLASH_SendByte(Dummy_Byte);
Temp = SPI_FLASH_SendByte(Dummy_Byte);
SPI_FLASH_CS_HIGH();
return Temp;
}
void SPI_FLASH_BulkErase(void)
{
SPI_FLASH_WriteEnable();
SPI_FLASH_CS_LOW();
SPI_FLASH_SendByte(W25X_ChipErase);
SPI_FLASH_CS_HIGH();
SPI_FLASH_WaitForWriteEnd();
}
void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
{
SPI_FLASH_WriteEnable();
SPI_FLASH_CS_LOW();
SPI_FLASH_SendByte(W25X_PageProgram);
SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16);
SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8);
SPI_FLASH_SendByte(WriteAddr & 0xFF);
if(NumByteToWrite > SPI_FLASH_PerWritePageSize)
{
NumByteToWrite = SPI_FLASH_PerWritePageSize;
FLASH_ERROR("SPI_FLASH_PageWrite too large!");
}
while (NumByteToWrite--)
{
SPI_FLASH_SendByte(*pBuffer);
pBuffer++;
}
SPI_FLASH_CS_HIGH();
SPI_FLASH_WaitForWriteEnd();
}
4. 主函数
int main(void)
{
LED_GPIO_Config();
LED_BLUE;
USART_Config();
printf("\r\n 这是一个8Mbyte串行flash(W25Q64)实验 \r\n");
SPI_FLASH_Init();
DeviceID = SPI_FLASH_ReadDeviceID();
Delay( 200 );
FlashID = SPI_FLASH_ReadID();
printf("\r\n FlashID is 0x%X,\
Manufacturer Device ID is 0x%X\r\n", FlashID, DeviceID);
if (FlashID == sFLASH_ID)
{
printf("\r\n 检测到串行flash W25Q64 !\r\n");
SPI_FLASH_SectorErase(FLASH_SectorToErase);
SPI_FLASH_BufferWrite(Tx_Buffer, FLASH_WriteAddress, BufferSize);
printf("\r\n 写入的数据为:%s \r\t", Tx_Buffer);
SPI_FLASH_BufferRead(Rx_Buffer, FLASH_ReadAddress, BufferSize);
printf("\r\n 读出的数据为:%s \r\n", Rx_Buffer);
TransferStatus1 = Buffercmp(Tx_Buffer, Rx_Buffer, BufferSize);
if( PASSED == TransferStatus1 )
{
LED_GREEN;
printf("\r\n 8M串行flash(W25Q64)测试成功!\n\r");
}
else
{
LED_RED;
printf("\r\n 8M串行flash(W25Q64)测试失败!\n\r");
}
}
else
{
LED_RED;
printf("\r\n 获取不到 W25Q64 ID!\n\r");
}
while(1);
}
七.资料获取
加群私聊群主可免费获得,也可加群学习交流 群号:1041406448。
|