基于ST MCU( STM32L431RCTx) SPI模块外接SPI FALSH的案例

举报
aiot_bigbear 发表于 2022/09/25 00:26:49 2022/09/25
【摘要】 文章目录 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

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。