基于ST MCU( STM32L431RCTx) SPI模块外接SPI FALSH的案例
【摘要】
文章目录
1.相关开发环境2.SPI1 外接SPI FLASH3.SPI FLASH初始化3.1 SPI FLASH支持SPI MODE0/3的通讯控制3.2 SPI 硬件CRC 不需要D...
1.相关开发环境
硬件版本:STM32L431RCTx
开发软件:KEIL
2.SPI1 外接SPI FLASH
MCU SPI1 外接SPI FLASH
#define CS_PORT GPIOB
#define CS_PIN GPIO_PIN_11
#define FLASH_CS_ENABLE() HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_RESET)
#define FLASH_CS_DISABLE() HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET)
- 1
- 2
- 3
- 4
- 5
3.SPI FLASH初始化
根据 FLASH 芯片的说明,它支持 SPI模式 0及模式 3,支持双线全双工,使用 MSB先行模式,支持最高通讯时钟为 104MHz,数据帧长度为 8 位。我们要把 STM32 的 SPI 外设中的这些参数配置一致。
SPI 1初始化 Init的具体定义如下:
static void st_SPI1_Init(void)
{
/* SPI1 parameter configuration*/
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
// hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
// hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 7;
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
3.1 SPI FLASH支持SPI MODE0/3的通讯控制
// hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
// hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
- 1
- 2
- 3
- 4
- 5
3.2 SPI 硬件CRC 不需要DISABLE即可
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
3.3 SPI CS 软件GPIO控制即可
hspi1.Init.NSS = SPI_NSS_SOFT;
4.SPI FLASH 的读 写 等操作验证代码
4.1 SPI FLASH ID读取
uint32_t stmcu_W25Q64_ReadDeviceID(void)
{
uint8_t command = FLASH_READ_DEVICE_ID;
uint32_t usFlashId = 0;
uint8_t temp_buff[3] = {0};
FLASH_CS_ENABLE();
HAL_SPI_Transmit(&hspi1, &command, 1, 1); // 90h
HAL_SPI_Transmit(&hspi1, temp_buff, 3, 3); //写入24位地址;假地址
HAL_SPI_Receive(&hspi1, temp_buff, 2, 2);
FLASH_CS_DISABLE();
//usFlashId = (uint32_t)temp_buff[2]|(temp_buff[1] << 8) | (temp_buff[0] << 16);
usFlashId = (uint16_t)(temp_buff[1]) | (temp_buff[0] << 8);
return usFlashId;
}
uint32_t stmcu_W25Q64_ReadDeviceID_JEDEC(void)
{
uint8_t command = FLASH_READ_JEDEC_ID;
uint32_t usFlashId = 0;
uint8_t temp_buff[3] = {0};
FLASH_CS_ENABLE();
HAL_SPI_Transmit(&hspi1, &command, 1, 1); // 9Fh
// HAL_SPI_Transmit(&hspi1, temp_buff, 3, 3); //写入24位地址;假地址
HAL_SPI_Receive(&hspi1, temp_buff, 3, 3);
FLASH_CS_DISABLE();
usFlashId = (uint32_t)temp_buff[2]|(temp_buff[1] << 8) | (temp_buff[0] << 16);
return usFlashId;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
4.2 SPI FLASH 读写
void stmcu_W25Q64_WriteEnable(void)
{
uint8_t command = FLASH_WRITE_ENABLE_CMD;
FLASH_CS_ENABLE();
HAL_SPI_Transmit(&hspi1, &command, 1, 1);
FLASH_CS_DISABLE();
}
void stmcu_W25Q64_WriteDisable(void)
{
uint8_t command = FLASH_WRITE_DISABLE_CMD;
FLASH_CS_ENABLE();
HAL_SPI_Transmit(&hspi1, &command, 1, 1);
FLASH_CS_DISABLE();
}
uint8_t stmcu_W25Q64_ReadSR(void)
{
uint8_t ucTmpVal = 0;
uint8_t command = FLASH_READ_SR_CMD;
FLASH_CS_ENABLE();
HAL_SPI_Transmit(&hspi1, &command, 1, 1);
HAL_SPI_Receive(&hspi1, &ucTmpVal, 1, 1);
FLASH_CS_DISABLE();
return ucTmpVal;
}
void stmcu_W25Q64_WriteSR(uint8_t _ucByte)
{
uint8_t CMD[2] = {FLASH_WRITE_SR_CMD, 0};
CMD[1] = _ucByte;
stmcu_W25Q64_WriteEnable();
stmcu_W25Q64_WaitNobusy();
FLASH_CS_ENABLE();
HAL_SPI_Transmit(&hspi1, CMD, 2, 2);
FLASH_CS_DISABLE();
stmcu_W25Q64_WaitNobusy();
}
void stmcu_W25Q64_WaitNobusy(void)
{
while (((stmcu_W25Q64_ReadSR()) & 0x01) == 0x01) //等待BUSY位清空
{
osDelay(1);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
void stmcu_W25Q64_ReadData(uint32_t Addr, uint8_t *Buffer, uint16_t NByte)
{
uint8_t temp_buff[4] = {0};
if (Buffer == NULL)
{
return;
}
temp_buff[0] = FLASH_READ_DATA;
temp_buff[1] = (uint8_t)(Addr >> 16);
temp_buff[2] = (uint8_t)(Addr >> 8);
temp_buff[3] = (uint8_t)(Addr >> 0);
FLASH_CS_ENABLE();
HAL_SPI_Transmit(&hspi1, temp_buff, 4, 4);
HAL_SPI_Receive(&hspi1, Buffer, NByte, NByte);
FLASH_CS_DISABLE();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
void stmcu_W25Q64_WriteData(uint32_t Addr, uint8_t *Buffer, uint16_t NByte)
{
uint8_t temp_buff[4] = {0};
if (Buffer == NULL)
{
return;
}
temp_buff[0] = FLASH_WRITE_PAGE;
temp_buff[1] = (uint8_t)(Addr >> 16);
temp_buff[2] = (uint8_t)(Addr >> 8);
temp_buff[3] = (uint8_t)(Addr >> 0);
stmcu_W25Q64_WriteEnable();
stmcu_W25Q64_WaitNobusy();
FLASH_CS_ENABLE();
HAL_SPI_Transmit(&hspi1, temp_buff, 4, 4);
HAL_SPI_Transmit(&hspi1, Buffer, NByte, NByte);
FLASH_CS_DISABLE();
stmcu_W25Q64_WaitNobusy();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
5.参考
本文引用《STM32库开发实战指南》
obusy();
FLASH_CS_ENABLE();
HAL_SPI_Transmit(&hspi1, temp_buff, 4, 4);
HAL_SPI_Transmit(&hspi1, Buffer, NByte, NByte);
FLASH_CS_DISABLE();
stmcu_W25Q64_WaitNobusy();
- 1
- 2
- 3
- 4
- 5
- 6
}
## 5.参考
本文引用《STM32库开发实战指南》
##
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
文章来源: blog.csdn.net,作者:悟空胆好小,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/xushx_bigbear/article/details/125137942
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)