
试验目的:芯片采用F0芯片,通过配置SPI1完成W25X16的读写。片选CS为PA1,SCK为PB3,MISO为PB4,MOSI为PB5 具体配置: ![]() ![]() 由于没有使用中断和DMA,所以中断配置不选。 ![]() 程序分析: 首先要读取W25X16的ID号,需要发送0x90,加2个伪数据+0x00。同时由于ID号为2个8位数据构成,并且ST的F0芯片的SPI是要读取时需要先写,所以定义 uint8_t Data1[4] = {0x90,0x00,0x00,0x00} uint8_t Data2[2]= {0x00,0x00} uint8_t Rxdata[2]; $ Q2 G! w8 J k0 }7 a 然后主程序中使能SPI端口:HAL_SPI_MspInit(&hspi1); 最后就是读取ID命令了,如下图 ![]() 此时Rxdata=0xEF14,这个就是W25X16的ID号。 读取ID正确了,剩下的就是对Flash的操作了。 / v2 P' T9 S- n4 R6 o+ s & P. r m* j# R0 w2 ]; f" O3 y* ` 0 q, @5 C8 M3 m, n4 ^ |
void SPI_FLASH_WriteEnable(void)
{
SPI_FLASH_CS_LOW();
HAL_SPI_Transmit(&hspi1, &W25X_WriteEnable, 1, 100);
SPI_FLASH_CS_HIGH();! C. e0 Z, P; [- ?
}; {. E5 [) D& i" _* E: E
uint8_t SPI_FLASH_SendByte(uint8_t byte)
{5 V+ D5 l4 t0 l7 e/ S
uint8_t temp;
uint8_t temp1[1];
HAL_SPI_TransmitReceive(&hspi1, &byte, &temp1[0], 1,100);% Q* l N7 u7 C+ N
temp=temp1[0];7 [) `( [6 e+ R) D/ Z% u/ h, v$ E
return temp;. R8 j+ R3 ~/ O+ E6 W. b' r9 [; w
}( L* T% k, _. G% x
void SPI_FLASH_WaitForWriteEnd(void) ' H! T8 v, O% f5 }, D, d! ~
{ " p+ W9 [9 E( c; J) z% h
uint8_t FLASH_Status=0;% C5 r9 L# I0 d* }
uint8_t temp1[1];. l' t! l' p6 f z0 t. M: Z
SPI_FLASH_CS_LOW();
HAL_SPI_Transmit(&hspi1, &W25X_ReadStatusReg, 1, 100);
do
{
HAL_SPI_TransmitReceive(&hspi1, &Dummy_Byte, &temp1[0], 1,100);
FLASH_Status = temp1[0];3 L/ k3 \5 v) g7 L
}/ a& L u8 L3 i+ B$ @" F& S
while ((FLASH_Status & WIP_Flag) == SET);
SPI_FLASH_CS_HIGH();# N+ m8 x! j' N7 @3 ?' q9 S
} 9 ?0 E3 N4 |( i; f
这是用调用到的函数
SPI的引脚配置可以这样设置吗? /**SPI1 GPIO Configuration
PB3 ------> SPI1_SCK
PB4 ------> SPI1_MISO
PB5 ------> SPI1_MOSI ) N, T! h) ^' ^1 `, O, N& R ~+ v
*/
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;/ u+ p! ]- P, h+ K6 x
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;- ]( c [5 W' f+ X
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
void SPI_FLASH_SectorErase(uint32_t SectorAddr)
{
SPI_FLASH_WriteEnable();
SPI_FLASH_CS_LOW();) S& k' A. Q1 S/ f: l3 ]
SPI_FLASH_SendByte(W25X_SectorErase);
SPI_FLASH_SendByte((SectorAddr & 0xFF0000) >> 16);
SPI_FLASH_SendByte((SectorAddr & 0xFF00) >> 8);$ T- _$ `/ n/ P" Z! Q3 w
SPI_FLASH_SendByte(SectorAddr & 0xFF);" b- T {8 Q" [# o: O% Q, r
SPI_FLASH_CS_HIGH();5 _' O% }8 a6 D g
SPI_FLASH_WaitForWriteEnd();
}
äºååèæ°ï½å¤§éª
一般不应该是0,如果读不到,应该是FF