STM32CubeMX学习--(5)SPI读写W25Q128

2020-05-14来源: eefocus关键字:STM32CubeMX  SPI读写  W25Q128

CUBE配置

SPI配置

引脚配置


参数配置


点击生成代码

代码修改

uint8_t Data1[4]={0x90,0x00,0x00,0x00};

uint8_t Data2[2]={0x00,0x00};

uint8_t RxData[2]={0x00,0x00};

/****************************/


  while (1)

  {

  HAL_GPIO_WritePin(SPI1_NSS_GPIO_Port,SPI1_NSS_Pin,GPIO_PIN_RESET);

  HAL_SPI_Transmit(&hspi1,Data1,4,100);

  HAL_SPI_TransmitReceive(&hspi1,Data2,RxData,2,100);

  HAL_GPIO_WritePin(SPI1_NSS_GPIO_Port,SPI1_NSS_Pin,GPIO_PIN_SET);

HAL_Delay(500);

    /* USER CODE END WHILE */


    /* USER CODE BEGIN 3 */

  }


上述程序发送读取W25Q128的ID,Debug下看到RxData为{0xEF,0x17}。即为其ID号,说明SPI读取成功,接下来根据W25Q128手册编写应用程序即可。

添加W25Q128代码

W25Qxx.c

/*********************************************************************************************************

*

* File                : ws_W25Qx.c

* Hardware Environment: 

* Build Environment   : RealView MDK-ARM  Version: 4.20

* Version             : V1.0

* By                  : 

*

*                                  (c) Copyright 2005-2011, WaveShare

*                                       http://www.waveshare.net

*                                          All Rights Reserved

*

*********************************************************************************************************/


#include "W25QXX.h"


/**

  * @brief  Initializes the W25Q128FV interface.

  * @retval None

  */

uint8_t BSP_W25Qx_Init(void)

/* Reset W25Qxxx */

BSP_W25Qx_Reset();

return BSP_W25Qx_GetStatus();

}


/**

  * @brief  This function reset the W25Qx.

  * @retval None

  */

static void BSP_W25Qx_Reset(void)

{

uint8_t cmd[2] = {RESET_ENABLE_CMD,RESET_MEMORY_CMD};

W25Qx_Enable();

/* Send the reset command */

HAL_SPI_Transmit(&hspi1, cmd, 2, W25Qx_TIMEOUT_VALUE);

W25Qx_Disable();


}


/**

  * @brief  Reads current status of the W25Q128FV.

  * @retval W25Q128FV memory status

  */

static uint8_t BSP_W25Qx_GetStatus(void)

{

__align(4) uint8_t cmd[] = {READ_STATUS_REG1_CMD};

uint8_t status;

W25Qx_Enable();

/* Send the read status command */

HAL_SPI_Transmit(&hspi1, cmd, 1, W25Qx_TIMEOUT_VALUE);

/* Reception of the data */

HAL_SPI_Receive(&hspi1,&status, 1, W25Qx_TIMEOUT_VALUE);

W25Qx_Disable();

/* Check the value of the register */

if((status & W25Q128FV_FSR_BUSY) != 0)

{

return W25Qx_BUSY;

}

return W25Qx_OK;

}


/**

  * @brief  This function send a Write Enable and wait it is effective.

  * @retval None

  */

uint8_t BSP_W25Qx_WriteEnable(void)

{

uint8_t cmd[] = {WRITE_ENABLE_CMD};

uint32_t tickstart = HAL_GetTick();


/*Select the FLASH: Chip Select low */

W25Qx_Enable();

/* Send the read ID command */

HAL_SPI_Transmit(&hspi1, cmd, 1, W25Qx_TIMEOUT_VALUE);

/*Deselect the FLASH: Chip Select high */

W25Qx_Disable();

/* Wait the end of Flash writing */

while(BSP_W25Qx_GetStatus() == W25Qx_BUSY);

{

/* Check for the Timeout */

    if((HAL_GetTick() - tickstart) > W25Qx_TIMEOUT_VALUE)

    {        

return W25Qx_TIMEOUT;

    }

}

return W25Qx_OK;

}


/**

  * @brief  Read Manufacture/Device ID.

* @param  return value address

  * @retval None

  */

void BSP_W25Qx_Read_ID(uint8_t *ID)

{

uint8_t cmd[4] = {READ_ID_CMD,0x00,0x00,0x00};

W25Qx_Enable();

/* Send the read ID command */

HAL_SPI_Transmit(&hspi1, cmd, 4, W25Qx_TIMEOUT_VALUE);

/* Reception of the data */

HAL_SPI_Receive(&hspi1,ID, 2, W25Qx_TIMEOUT_VALUE);

W25Qx_Disable();

}


/**

  * @brief  Reads an amount of data from the QSPI memory.

  * @param  pData: Pointer to data to be read

  * @param  ReadAddr: Read start address

  * @param  Size: Size of data to read    

  * @retval QSPI memory status

  */

uint8_t BSP_W25Qx_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size)

{

uint8_t cmd[4];


/* Configure the command */

cmd[0] = READ_CMD;

cmd[1] = (uint8_t)(ReadAddr >> 16);

cmd[2] = (uint8_t)(ReadAddr >> 8);

cmd[3] = (uint8_t)(ReadAddr);

W25Qx_Enable();

/* Send the read ID command */

HAL_SPI_Transmit(&hspi1, cmd, 4, W25Qx_TIMEOUT_VALUE);

/* Reception of the data */

if (HAL_SPI_Receive(&hspi1, pData,Size,W25Qx_TIMEOUT_VALUE) != HAL_OK)

  {

    return W25Qx_ERROR;

  }

W25Qx_Disable();

return W25Qx_OK;

}


/**

  * @brief  Writes an amount of data to the QSPI memory.

  * @param  pData: Pointer to data to be written

  * @param  WriteAddr: Write start address

  * @param  Size: Size of data to write,No more than 256byte.    

  * @retval QSPI memory status

  */

uint8_t BSP_W25Qx_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size)

{

uint8_t cmd[4];

uint32_t end_addr, current_size, current_addr;

uint32_t tickstart = HAL_GetTick();

/* Calculation of the size between the write address and the end of the page */

  current_addr = 0;


  while (current_addr <= WriteAddr)

  {

    current_addr += W25Q128FV_PAGE_SIZE;

  }

  current_size = current_addr - WriteAddr;


  /* Check if the size of the data is less than the remaining place in the page */

  if (current_size > Size)

  {

    current_size = Size;

  }


  /* Initialize the adress variables */

  current_addr = WriteAddr;

  end_addr = WriteAddr + Size;

  /* Perform the write page by page */

  do

  {

/* Configure the command */

cmd[0] = PAGE_PROG_CMD;

cmd[1] = (uint8_t)(current_addr >> 16);

cmd[2] = (uint8_t)(current_addr >> 8);

cmd[3] = (uint8_t)(current_addr);


/* Enable write operations */

BSP_W25Qx_WriteEnable();

W25Qx_Enable();

    /* Send the command */

    if (HAL_SPI_Transmit(&hspi1,cmd, 4, W25Qx_TIMEOUT_VALUE) != HAL_OK)

    {

      return W25Qx_ERROR;

    }

    

    /* Transmission of the data */

    if (HAL_SPI_Transmit(&hspi1, pData,current_size, W25Qx_TIMEOUT_VALUE) != HAL_OK)

    {

      return W25Qx_ERROR;

    }

W25Qx_Disable();

    /* Wait the end of Flash writing */

while(BSP_W25Qx_GetStatus() == W25Qx_BUSY);

{

/* Check for the Timeout */

if((HAL_GetTick() - tickstart) > W25Qx_TIMEOUT_VALUE)

{        

return W25Qx_TIMEOUT;

}

}

    

    /* Update the address and size variables for next page programming */

    current_addr += current_size;

    pData += current_size;

    current_size = ((current_addr + W25Q128FV_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : W25Q128FV_PAGE_SIZE;

  } while (current_addr < end_addr);


return W25Qx_OK;

}


/**

  * @brief  Erases the specified block of the QSPI memory. 

  * @param  BlockAddress: Block address to erase  

  * @retval QSPI memory status

  */

uint8_t BSP_W25Qx_Erase_Block(uint32_t Address)

{

uint8_t cmd[4];

uint32_t tickstart = HAL_GetTick();

cmd[0] = SECTOR_ERASE_CMD;

cmd[1] = (uint8_t)(Address >> 16);

cmd[2] = (uint8_t)(Address >> 8);

cmd[3] = (uint8_t)(Address);

/* Enable write operations */

BSP_W25Qx_WriteEnable();

/*Select the FLASH: Chip Select low */

W25Qx_Enable();

/* Send the read ID command */

HAL_SPI_Transmit(&hspi1, cmd, 4, W25Qx_TIMEOUT_VALUE);

/*Deselect the FLASH: Chip Select high */

W25Qx_Disable();

/* Wait the end of Flash writing */

while(BSP_W25Qx_GetStatus() == W25Qx_BUSY);

{

/* Check for the Timeout */

    if((HAL_GetTick() - tickstart) > W25Q128FV_SECTOR_ERASE_MAX_TIME)

    {        

return W25Qx_TIMEOUT;

    }

}

return W25Qx_OK;

}


/**

  * @brief  Erases the entire QSPI memory.This function will take a very long time.

  * @retval QSPI memory status

  */

uint8_t BSP_W25Qx_Erase_Chip(void)

{

__align(4) uint8_t cmd[4];

uint32_t tickstart = HAL_GetTick();

cmd[0] = SECTOR_ERASE_CMD;

/* Enable write operations */

BSP_W25Qx_WriteEnable();

/*Select the FLASH: Chip Select low */

W25Qx_Enable();

/* Send the read ID command */

HAL_SPI_Transmit(&hspi1, cmd, 1, W25Qx_TIMEOUT_VALUE);

/*Deselect the FLASH: Chip Select high */

W25Qx_Disable();

/* Wait the end of Flash writing */

while(BSP_W25Qx_GetStatus() != W25Qx_BUSY);

{

/* Check for the Timeout */

if((HAL_GetTick() - tickstart) > W25Q128FV_BULK_ERASE_MAX_TIME)

{        

return W25Qx_TIMEOUT;

}

}

return W25Qx_OK;

}


W25Qxx.h

/*********************************************************************************************************

*

* File                : W25Qx.h

* Hardware Environment: 

* Build Environment   : RealView MDK-ARM  Version: 5.15

* Version             : V1.0

* By                  : 

*

*                                  (c) Copyright 2005-2015, WaveShare

*                                       http://www.waveshare.net

*                                          All Rights Reserved

*

****************************

[1] [2]
关键字:STM32CubeMX  SPI读写  W25Q128 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic497153.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32CubeMX学习--(6)USB大容量存储设备
下一篇:STM32CubeMX学习--(4)CAN使用

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

STM32CubeMX学习教程之一:GPIO输出之跑马灯
完整源码下载:https://github.com/simonliu009/STM32CubeMX-GPIO-Control软件版本:STM32CubeMX V4.25.0 System Workbench V2.4固件库版本:STM32Cube FW_F1 V1.6.1硬件:OneNet 麒麟座V2.3在STM32CubeMX中新建项目,选择正确的MCU型号首先设置RCC和SYS,如下图然后根据板子实际情况设置时钟(麒麟座外部晶振是12M,STM32F103x的最高主频是72M),如下图GPIO设置 PC7, PC8, PA12和 PC10为GPIO_OUTPUT, (这是麒麟座V2.3的四个LED管脚),如下图
发表于 2020-05-04
STM32CubeMX学习教程之一:GPIO输出之跑马灯
STM32CubeMX学习--(3)串口通信
Cube配置USART配置在Connectivity中选中USART1MODE = AsynchronousHardware Flow Control = DisableParameter Settings中配置Baud Rate = 115200Word Length = 8bitParity = NoneStop Bits =1Data Direction = Receive and TransmitOver Sampling = 16 SamplesNVIC Setting勾选Enable,Preemption Priority =2生成代码修改代码生成代码后,即可使用HAL_UART_Transmit_IT(&
发表于 2020-04-29
STM32CubeMX系列教程 5.0版本环境开发——2.Uart串行通信功能
;                         PS:在明白原理的情况下建议自己手写一次模拟UART。明白了之后,代码重复的事就由STM32芯片的硬件功能来实现就可以了,你只需要会看逻辑分析仪或者示波器分析数据便可。 所谓硬件功能 就是你把数据填充到寄存器,然后配置好相关参数,他会自动帮你发送出去。通俗点说,自己手写整个协议代码实现实现就像你自己把一个快件送到到别人那里再回来,而硬件功能则是你把快件给快递员,快递员帮你送过去。  明显 后者会帮你节省大量时间和精力。它是一个硬件组成,并且你也为此付费
发表于 2020-04-29
STM32CubeMX系列教程 5.0版本环境开发——2.Uart串行通信功能
【STM32CubeMX】 串口通信(USART) Printf重定向
STM32CubeMX: Version 4.26.1MDK-ARM: Version 5.24.2开发板: 中移onenet 麒麟座MINI板芯片: STM32F103CBT61.STM32CubeMX设置设置外部时钟源设置Debug设置串口 使用USART1 PA9,PA10设置时钟频率设置USART1详细参数生成MDK-ARM工程2.重定向Printf 及 Scanf主要用到两个函数HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout
发表于 2020-04-29
【STM32CubeMX】 串口通信(USART) Printf重定向
STM32CubeMX学习教程之六:USART串口输出和printf( )重定向到串口
软件:STM32CubeMX V4.25.0  System Workbench V2.4固件库版本:STM32Cube FW_F1 V1.6.1硬件:OneNet 麒麟座V2.3在STM32CubeMX中新建项目,选择正确的MCU型号首先设置RCC和SYS,如下图然后根据板子实际情况设置时钟(麒麟座外部晶振是12M,STM32F103x的最高主频是72M),如下图配置USART1为Asychronous模式可以看到PA9和PA10被配置为了USART1_TX, USART1_RX。UART1配置用默认的115200,8, None和1就好。Project - setting ,ToolChain/IDE选择
发表于 2020-04-27
STM32CubeMX学习教程之六:USART串口输出和printf( )重定向到串口
stm32cubeMX学习三、串口打印Hello world
上一节入门了stm32cubeMX按键的配置,这节我们来学习下编写一个串口打印hello world的程序。本程序编写基于秉火霸道STM32F103ZET6开发板进行。一、打开stm32cubeMX软件二、选择芯片型号首先点击File,然后选择New Project,在弹出的页面中搜索您要配置的芯片型号,然后鼠标双击选择stm32f103ZETx这时候会弹出另外一个页面如下,开始做芯片的硬件资源配置工作。三、配置时钟频率选择Clock Configuration,然后在如下图所示的方框中配置好时钟频率,stm32cubeMX会自动把分频系统等配置好,不用人为一个一个去设置。四、查看串口相关的引脚并配置4.1 打开电路图,找相关
发表于 2020-04-27
stm32cubeMX学习三、串口打印Hello world
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved