打印
[应用相关]

IO模拟SPI _读写 SPI FLASH-25Q32

[复制链接]
4513|34
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ADZ2016|  楼主 | 2018-9-3 14:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/******************** (C) COPYRIGHT ********************
* 文件名  :spi_flash.c
* 描述    :spi 底层应用函数库      
* 硬件连接 ----------------------------
*         | PC8-SPI2-NSS  : W25X40-CS  |
*         | PD14-SPI2-SCK  : W25X40-CLK |
*         | PC7-SPI2-MISO : W25X40-DO  |
*         | PD13-SPI2-MOSI : W25X40-DIO |
*         | PC6-WRITE    : W25X40-DIO |
*         | PD15-HOLD    : W25X40-DIO |
*          ----------------------------
* 库版本  :ST3.0.0
*
* 作者    :
* 博客    :
**********************************************************************************/
#include "spi_flash.h"
#include "gpio.h"

/* Private typedef -----------------------------------------------------------*/
//#define SPI_FLASH_PageSize      4096
#define SPI_FLASH_PageSize      256
#define SPI_FLASH_PerWritePageSize      256

/* Private define ------------------------------------------------------------*/
#define W25X_WriteEnable                      0x06
#define W25X_WriteDisable                      0x04
#define W25X_ReadStatusReg                    0x05
#define W25X_WriteStatusReg                    0x01
#define W25X_ReadData                                0x03
#define W25X_FastReadData                      0x0B
#define W25X_FastReadDual                      0x3B
#define W25X_PageProgram                      0x02
#define W25X_BlockErase                              0xD8
#define W25X_SectorErase                      0x20
#define W25X_ChipErase                              0xC7
#define W25X_PowerDown                              0xB9
#define W25X_ReleasePowerDown            0xAB
#define W25X_DeviceID                                0xAB
#define W25X_ManufactDeviceID           0x90
#define W25X_JedecDeviceID                    0x9F

#define WIP_Flag                  0x01  /* Write In Progress (WIP) flag */

#define Dummy_Byte                0xFF


沙发
ADZ2016|  楼主 | 2018-9-3 14:48 | 只看该作者
void SPI_FLASH_Write_Protect_ENABLE(void)//flash 打开写保护
{
  SPI_FLASH_Write_Protect_Assert();
}

使用特权

评论回复
板凳
ADZ2016|  楼主 | 2018-9-3 14:48 | 只看该作者
void SPI_FLASH_Write_Protect_DISABLE(void)//flash 关闭写保护
{
  SPI_FLASH_Write_Protect_Deassert();
}

使用特权

评论回复
地板
ADZ2016|  楼主 | 2018-9-3 14:48 | 只看该作者
void SPI_FLASH_Hold_ENABLE(void)//flash HOLD ENABLE
{
  SPI_FLASH_Hold_Assert();
}

使用特权

评论回复
5
ADZ2016|  楼主 | 2018-9-3 14:49 | 只看该作者
void SPI_FLASH_Hold_DISABLE(void)//flash HOLD DISABLE
{
  SPI_FLASH_Hold_Deassert();
}

使用特权

评论回复
6
ADZ2016|  楼主 | 2018-9-3 14:49 | 只看该作者
/*******************************************************************************
* Function Name  : SPI_FLASH_Init
* Description    : Initializes the peripherals used by the SPI FLASH driver.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_Init(void)
{
#ifdef _BOARD  //DEMO Board

GpioInitTypeDef gpioInitStr;   
   
    // 初始化模拟SPI的IO口
    // SPI_FLASH_SCK_S  PA5
        gpioInitStr.GpioPin = SPI_FLASH_SCK_PIN_S;
        gpioInitStr.GpioSpeed = GpioSpeed2MHz;
        gpioInitStr.GpioMode = Gpio_Mode_Out_PP;
        GpioInit(SPI_FLASH_SCK_PORT_S, &gpioInitStr);
    // SPI_FLASH_MOSI_S PA7
           gpioInitStr.GpioPin = SPI_FLASH_MOSI_PIN_S;
        GpioInit(SPI_FLASH_MOSI_PORY_S, &gpioInitStr);
    // SPI_FLASH_NSS_S  PA4
    gpioInitStr.GpioPin = SPI_FLASH_NSS_PIN_S;
        GpioInit(SPI_FLASH_NSS_PORT_S, &gpioInitStr);
   
    // SPI_FLASH_MISO_S PA6
           gpioInitStr.GpioPin = SPI_FLASH_MISO_PIN_S;
        gpioInitStr.GpioMode = Gpio_Mode_IN_FLOATING;
      //gpioInitStr.GpioMode = Gpio_Mode_IPU;
        GpioInit(SPI_FLASH_MISO_PORY_S, &gpioInitStr);
        
#else  
#ifdef SPI_FLASH_HAL  
  
  SPI_InitTypeDef  SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  
  /* Enable SPI1 and GPIO clocks */
  /*!< SPI_FLASH_SPI_CS_GPIO, SPI_FLASH_SPI_MOSI_GPIO,
       SPI_FLASH_SPI_MISO_GPIO, SPI_FLASH_SPI_DETECT_GPIO
       and SPI_FLASH_SPI_SCK_GPIO Periph clock enable */
  // spi2管脚重映射
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD, ENABLE);

  /*!< SPI_FLASH_SPI Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
  /*!< AFIO Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
  
  
  /*!< Configure SPI_FLASH_SPI pins: SCK */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOD, &GPIO_InitStructure);

  /*!< Configure SPI_FLASH_SPI pins: MISO */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  /*!< Configure SPI_FLASH_SPI pins: MOSI */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
  GPIO_Init(GPIOD, &GPIO_InitStructure);

  /*!< Configure SPI_FLASH_SPI_CS_PIN pin: SPI_FLASH Card CS pin */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  /* Deselect the FLASH: Chip Select high */
  SPI_FLASH_CS_HIGH();

  /* SPI1 configuration */
  // W25X40: data input on the DIO pin is sampled on the rising edge of the CLK.
  // Data on the DO and DIO pins are clocked out on the falling edge of CLK.
  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(SPI2, &SPI_InitStructure);

  /* Enable SPI1  */
  SPI_Cmd(SPI2, ENABLE);
  
#else
    GpioInitTypeDef gpioInitStr;   
   
    // 初始化模拟SPI的IO口
    // SPI_FLASH_SCK_S  PD14
        gpioInitStr.GpioPin = SPI_FLASH_SCK_PIN_S;
        gpioInitStr.GpioSpeed = GpioSpeed2MHz;
        gpioInitStr.GpioMode = Gpio_Mode_Out_PP;
        GpioInit(SPI_FLASH_SCK_PORT_S, &gpioInitStr);
    // SPI_FLASH_MOSI_S PD13
           gpioInitStr.GpioPin = SPI_FLASH_MOSI_PIN_S;
        GpioInit(SPI_FLASH_MOSI_PORY_S, &gpioInitStr);
    // SPI_FLASH_NSS_S  PC8
    gpioInitStr.GpioPin = SPI_FLASH_NSS_PIN_S;
        GpioInit(SPI_FLASH_NSS_PORT_S, &gpioInitStr);
   
    // SPI_FLASH_MISO_S PC7
           gpioInitStr.GpioPin = SPI_FLASH_MISO_PIN_S;
        gpioInitStr.GpioMode = Gpio_Mode_IN_FLOATING;
      //gpioInitStr.GpioMode = Gpio_Mode_IPU;
        GpioInit(SPI_FLASH_MISO_PORY_S, &gpioInitStr);
#endif   
  
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);
      //Write_Protect PC6
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;       
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOC, &GPIO_InitStructure);
      //Hold  PD15
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;       
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOD, &GPIO_InitStructure);
        
        SPI_FLASH_Write_Protect_DISABLE();//flash 关闭写保护
        SPI_FLASH_Hold_DISABLE();//flash HOLD DISABLE
#endif        
        
}

使用特权

评论回复
7
ADZ2016|  楼主 | 2018-9-3 14:49 | 只看该作者
/*******************************************************************************
* Function Name  : SPI_FLASH_SectorErase
* Description    : Erases the specified FLASH sector.
* Input          : SectorAddr: address of the sector to erase.
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_SectorErase(u32 SectorAddr)
{
  /* Send write enable instruction */
  SPI_FLASH_WriteEnable();
  SPI_FLASH_WaitForWriteEnd();
  /* Sector Erase */
  /* Select the FLASH: Chip Select low */
  SPI_FLASH_CS_LOW();
  /* Send Sector Erase instruction */
  SPI_FLASH_SendByte(W25X_SectorErase);
  /* Send SectorAddr high nibble address byte */
  SPI_FLASH_SendByte((SectorAddr & 0xFF0000) >> 16);
  /* Send SectorAddr medium nibble address byte */
  SPI_FLASH_SendByte((SectorAddr & 0xFF00) >> 8);
  /* Send SectorAddr low nibble address byte */
  SPI_FLASH_SendByte(SectorAddr & 0xFF);
  /* Deselect the FLASH: Chip Select high */
  SPI_FLASH_CS_HIGH();
  /* Wait the end of Flash writing */
  SPI_FLASH_WaitForWriteEnd();
}

使用特权

评论回复
8
ADZ2016|  楼主 | 2018-9-3 14:54 | 只看该作者
/*******************************************************************************
* Function Name  : SPI_FLASH_SectorErase
* Description    : Erases the specified FLASH sector.
* Input          : SectorAddr: address of the sector to erase.
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_SectorErase(u32 SectorAddr)
{
  /* Send write enable instruction */
  SPI_FLASH_WriteEnable();
  SPI_FLASH_WaitForWriteEnd();
  /* Sector Erase */
  /* Select the FLASH: Chip Select low */
  SPI_FLASH_CS_LOW();
  /* Send Sector Erase instruction */
  SPI_FLASH_SendByte(W25X_SectorErase);
  /* Send SectorAddr high nibble address byte */
  SPI_FLASH_SendByte((SectorAddr & 0xFF0000) >> 16);
  /* Send SectorAddr medium nibble address byte */
  SPI_FLASH_SendByte((SectorAddr & 0xFF00) >> 8);
  /* Send SectorAddr low nibble address byte */
  SPI_FLASH_SendByte(SectorAddr & 0xFF);
  /* Deselect the FLASH: Chip Select high */
  SPI_FLASH_CS_HIGH();
  /* Wait the end of Flash writing */
  SPI_FLASH_WaitForWriteEnd();
}

使用特权

评论回复
9
ADZ2016|  楼主 | 2018-9-3 14:59 | 只看该作者
/*******************************************************************************
* Function Name  : SPI_FLASH_BulkErase
* Description    : Erases the entire FLASH.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_BulkErase(void)
{
  /* Send write enable instruction */
  SPI_FLASH_WriteEnable();

  /* Bulk Erase */
  /* Select the FLASH: Chip Select low */
  SPI_FLASH_CS_LOW();
  /* Send Bulk Erase instruction  */
  SPI_FLASH_SendByte(W25X_ChipErase);
  /* Deselect the FLASH: Chip Select high */
  SPI_FLASH_CS_HIGH();

  /* Wait the end of Flash writing */
  SPI_FLASH_WaitForWriteEnd();
}

使用特权

评论回复
10
ADZ2016|  楼主 | 2018-9-3 14:59 | 只看该作者
/*******************************************************************************
* Function Name  : SPI_FLASH_PageWrite
* Description    : Writes more than one byte to the FLASH with a single WRITE
*                  cycle(Page WRITE sequence). The number of byte can't exceed
*                  the FLASH page size.
* Input          : - pBuffer : pointer to the buffer  containing the data to be
*                    written to the FLASH.
*                  - WriteAddr : FLASH's internal address to write to.
*                  - NumByteToWrite : number of bytes to write to the FLASH,
*                    must be equal or less than "SPI_FLASH_PageSize" value.
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
{
  /* Enable the write access to the FLASH */
  SPI_FLASH_WriteEnable();

  /* Select the FLASH: Chip Select low */
  SPI_FLASH_CS_LOW();
  /* Send "Write to Memory " instruction */
  SPI_FLASH_SendByte(W25X_PageProgram);
  /* Send WriteAddr high nibble address byte to write to */
  SPI_FLASH_SendByte((WriteAddr & 0xFF0000) >> 16);
  /* Send WriteAddr medium nibble address byte to write to */
  SPI_FLASH_SendByte((WriteAddr & 0xFF00) >> 8);
  /* Send WriteAddr low nibble address byte to write to */
  SPI_FLASH_SendByte(WriteAddr & 0xFF);

  if(NumByteToWrite > SPI_FLASH_PerWritePageSize)
  {
     NumByteToWrite = SPI_FLASH_PerWritePageSize;
     //printf("\n\r Err: SPI_FLASH_PageWrite too large!");
  }

  /* while there is data to be written on the FLASH */
  while (NumByteToWrite--)
  {
    /* Send the current byte */
    SPI_FLASH_SendByte(*pBuffer);
    /* Point on the next byte to be written */
    pBuffer++;
  }

  /* Deselect the FLASH: Chip Select high */
  SPI_FLASH_CS_HIGH();

  /* Wait the end of Flash writing */
  SPI_FLASH_WaitForWriteEnd();
}

使用特权

评论回复
11
ADZ2016|  楼主 | 2018-9-3 15:00 | 只看该作者
/*******************************************************************************
* Function Name  : SPI_FLASH_BufferWrite
* Description    : Writes block of data to the FLASH. In this function, the
*                  number of WRITE cycles are reduced, using Page WRITE sequence.
* Input          : - pBuffer : pointer to the buffer  containing the data to be
*                    written to the FLASH.
*                  - WriteAddr : FLASH's internal address to write to.
*                  - NumByteToWrite : number of bytes to write to the FLASH.
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_BufferWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
{
  u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0;

  Addr = WriteAddr % SPI_FLASH_PageSize;
  count = SPI_FLASH_PageSize - Addr;
  NumOfPage =  NumByteToWrite / SPI_FLASH_PageSize;
  NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;

  if (Addr == 0) /* WriteAddr is SPI_FLASH_PageSize aligned  */
  {
    if (NumOfPage == 0) /* NumByteToWrite < SPI_FLASH_PageSize */
    {
      SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
    }
    else /* NumByteToWrite > SPI_FLASH_PageSize */
    {
      while (NumOfPage--)
      {
        SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);
        WriteAddr +=  SPI_FLASH_PageSize;
        pBuffer += SPI_FLASH_PageSize;
      }

      SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);
    }
  }
  else /* WriteAddr is not SPI_FLASH_PageSize aligned  */
  {
    if (NumOfPage == 0) /* NumByteToWrite < SPI_FLASH_PageSize */
    {
      if (NumOfSingle > count) /* (NumByteToWrite + WriteAddr) > SPI_FLASH_PageSize */
      {
        temp = NumOfSingle - count;

        SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);
        WriteAddr +=  count;
        pBuffer += count;

        SPI_FLASH_PageWrite(pBuffer, WriteAddr, temp);
      }
      else
      {
        SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumByteToWrite);
      }
    }
    else /* NumByteToWrite > SPI_FLASH_PageSize */
    {
      NumByteToWrite -= count;
      NumOfPage =  NumByteToWrite / SPI_FLASH_PageSize;
      NumOfSingle = NumByteToWrite % SPI_FLASH_PageSize;

      SPI_FLASH_PageWrite(pBuffer, WriteAddr, count);
      WriteAddr +=  count;
      pBuffer += count;

      while (NumOfPage--)
      {
        SPI_FLASH_PageWrite(pBuffer, WriteAddr, SPI_FLASH_PageSize);
        WriteAddr +=  SPI_FLASH_PageSize;
        pBuffer += SPI_FLASH_PageSize;
      }

      if (NumOfSingle != 0)
      {
        SPI_FLASH_PageWrite(pBuffer, WriteAddr, NumOfSingle);
      }
    }
  }
}

使用特权

评论回复
12
ADZ2016|  楼主 | 2018-9-3 15:01 | 只看该作者
/*******************************************************************************
* Function Name  : SPI_FLASH_BufferRead
* Description    : Reads a block of data from the FLASH.
* Input          : - pBuffer : pointer to the buffer that receives the data read
*                    from the FLASH.
*                  - ReadAddr : FLASH's internal address to read from.
*                  - NumByteToRead : number of bytes to read from the FLASH.
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)
{
  /* Select the FLASH: Chip Select low */
  SPI_FLASH_CS_LOW();

  /* Send "Read from Memory " instruction */
  SPI_FLASH_SendByte(W25X_ReadData);

  /* Send ReadAddr high nibble address byte to read from */
  SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
  /* Send ReadAddr medium nibble address byte to read from */
  SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
  /* Send ReadAddr low nibble address byte to read from */
  SPI_FLASH_SendByte(ReadAddr & 0xFF);

  while (NumByteToRead--) /* while there is data to be read */
  {
#ifdef SPI_FLASH_ANALOG
    //SPI_FLASH_SendByte(Dummy_Byte);
    *pBuffer = SPI_FLASH_ReadByte();//模拟SPI 读取
#else
    /* Read a byte from the FLASH */
    *pBuffer = SPI_FLASH_SendByte(Dummy_Byte);
#endif
    /* Point to the next location where the byte read will be saved */
    pBuffer++;
  }

  /* Deselect the FLASH: Chip Select high */
  SPI_FLASH_CS_HIGH();
}

使用特权

评论回复
13
ADZ2016|  楼主 | 2018-9-3 15:01 | 只看该作者
/*******************************************************************************
* Function Name  : SPI_FLASH_ReadID
* Description    : Reads FLASH identification.
* Input          : None
* Output         : None
* Return         : FLASH identification
*******************************************************************************/
u32 SPI_FLASH_ReadID(void)
{
  u32 Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;

  /* Select the FLASH: Chip Select low */
  SPI_FLASH_CS_LOW();

  /* Send "RDID " instruction */
  SPI_FLASH_SendByte(W25X_JedecDeviceID);

  
#ifdef SPI_FLASH_ANALOG
      /* Read a byte from the FLASH */
    //SPI_FLASH_SendByte(Dummy_Byte);
    Temp0 = SPI_FLASH_ReadByte();//模拟SPI 读取
  
  /* Read a byte from the FLASH */
    //SPI_FLASH_SendByte(Dummy_Byte);
    Temp1 = SPI_FLASH_ReadByte();//模拟SPI 读取
   
  /* Read a byte from the FLASH */
    //SPI_FLASH_SendByte(Dummy_Byte);
    Temp2 = SPI_FLASH_ReadByte();//模拟SPI 读取
#else   
  /* Read a byte from the FLASH */
  Temp0 = SPI_FLASH_SendByte(Dummy_Byte);

  
  /* Read a byte from the FLASH */
  Temp1 = SPI_FLASH_SendByte(Dummy_Byte);

   
  /* Read a byte from the FLASH */
  Temp2 = SPI_FLASH_SendByte(Dummy_Byte);
#endif

  /* Deselect the FLASH: Chip Select high */
  SPI_FLASH_CS_HIGH();

  Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;

  return Temp;
}

使用特权

评论回复
14
ADZ2016|  楼主 | 2018-9-3 15:01 | 只看该作者
/*******************************************************************************
* Function Name  : SPI_FLASH_ReadID
* Description    : Reads FLASH identification.
* Input          : None
* Output         : None
* Return         : FLASH identification
*******************************************************************************/
u32 SPI_FLASH_ReadDeviceID(void)
{
  u32 Temp = 0;

  /* Select the FLASH: Chip Select low */
  SPI_FLASH_CS_LOW();

  /* Send "RDID " instruction */
  SPI_FLASH_SendByte(W25X_DeviceID);
  SPI_FLASH_SendByte(Dummy_Byte);
  SPI_FLASH_SendByte(Dummy_Byte);
  SPI_FLASH_SendByte(Dummy_Byte);
#ifdef  SPI_FLASH_ANALOG
    //SPI_FLASH_SendByte(Dummy_Byte);
    Temp = SPI_FLASH_ReadByte();//模拟SPI 读取
#else   
  /* Read a byte from the FLASH */
  Temp = SPI_FLASH_SendByte(Dummy_Byte);
#endif
   
  /* Deselect the FLASH: Chip Select high */
  SPI_FLASH_CS_HIGH();

  return Temp;
}

使用特权

评论回复
15
ADZ2016|  楼主 | 2018-9-3 15:01 | 只看该作者
/*******************************************************************************
* Function Name  : SPI_FLASH_StartReadSequence
* Description    : Initiates a read data byte (READ) sequence from the Flash.
*                  This is done by driving the /CS line low to select the device,
*                  then the READ instruction is transmitted followed by 3 bytes
*                  address. This function exit and keep the /CS line low, so the
*                  Flash still being selected. With this technique the whole
*                  content of the Flash is read with a single READ instruction.
* Input          : - ReadAddr : FLASH's internal address to read from.
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_StartReadSequence(u32 ReadAddr)
{
  /* Select the FLASH: Chip Select low */
  SPI_FLASH_CS_LOW();

  /* Send "Read from Memory " instruction */
  SPI_FLASH_SendByte(W25X_ReadData);

  /* Send the 24-bit address of the address to read from -----------------------*/
  /* Send ReadAddr high nibble address byte */
  SPI_FLASH_SendByte((ReadAddr & 0xFF0000) >> 16);
  /* Send ReadAddr medium nibble address byte */
  SPI_FLASH_SendByte((ReadAddr& 0xFF00) >> 8);
  /* Send ReadAddr low nibble address byte */
  SPI_FLASH_SendByte(ReadAddr & 0xFF);
}

使用特权

评论回复
16
ADZ2016|  楼主 | 2018-9-3 15:02 | 只看该作者
#ifdef SPI_FLASH_HAL
/*******************************************************************************
* Function Name  : SPI_FLASH_ReadByte
* Description    : Reads a byte from the SPI Flash.
*                  This function must be used only if the Start_Read_Sequence
*                  function has been previously called.
* Input          : None
* Output         : None
* Return         : Byte Read from the SPI Flash.
*******************************************************************************/
u8 SPI_FLASH_ReadByte(void)
{
  return (SPI_FLASH_SendByte(Dummy_Byte));
}

使用特权

评论回复
17
ADZ2016|  楼主 | 2018-9-3 15:02 | 只看该作者
/*******************************************************************************
* Function Name  : SPI_FLASH_SendByte
* Description    : Sends a byte through the SPI interface and return the byte
*                  received from the SPI bus.
* Input          : byte : byte to send.
* Output         : None
* Return         : The value of the received byte.
*******************************************************************************/
u8 SPI_FLASH_SendByte(u8 byte)
{
  /* Loop while DR register in not emplty */
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);

  /* Send byte through the SPI1 peripheral */
  SPI_I2S_SendData(SPI2, byte);

  /* Wait to receive a byte */
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);

  /* Return the byte read from the SPI bus */
  return SPI_I2S_ReceiveData(SPI2);
  
/*
    while(SPI_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
    SPI_SendData(SPI2, byte);
   
    while(SPI_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
    return SPI_ReceiveData(SPI2);
*/  
}

使用特权

评论回复
18
ADZ2016|  楼主 | 2018-9-3 15:02 | 只看该作者
/*******************************************************************************
* Function Name  : SPI_FLASH_SendHalfWord
* Description    : Sends a Half Word through the SPI interface and return the
*                  Half Word received from the SPI bus.
* Input          : Half Word : Half Word to send.
* Output         : None
* Return         : The value of the received Half Word.
*******************************************************************************/
u16 SPI_FLASH_SendHalfWord(u16 HalfWord)
{
  /* Loop while DR register in not emplty */
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);

  /* Send Half Word through the SPI1 peripheral */
  SPI_I2S_SendData(SPI2, HalfWord);

  /* Wait to receive a Half Word */
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);

  /* Return the Half Word read from the SPI bus */
  return SPI_I2S_ReceiveData(SPI2);
}

#else

使用特权

评论回复
19
ADZ2016|  楼主 | 2018-9-3 15:03 | 只看该作者
//模拟SPI
/******************************************************************
- 功能描述:IO模拟SPI,发送一个字节
- 隶属模块:
- 函数属性:内部
- 参数说明:data 是要发送的字节
- 返回说明:无返回
- //注:
******************************************************************/

void SPI_FLASH_SendByte(u8 byte)
{
      unsigned char i;

    for(i=0; i<8; i++)
    {
        if(byte & 0x80)//((byte & 0x80)== 0x80)
        {
         SPI_FLASH_MOSI_S_1;
        }
        else
        {
            SPI_FLASH_MOSI_S_0;
        }
            SPI_FLASH_SCK_S_1;     //toggle clock high
            byte <<= 1;
         
            __NOP();__NOP();__NOP();__NOP();
            SPI_FLASH_SCK_S_0;
    }
   
}

使用特权

评论回复
20
ADZ2016|  楼主 | 2018-9-3 15:03 | 只看该作者
/******************************************************************
- 功能描述:IO模拟SPI,读取一个字节
- 隶属模块:
- 函数属性:内部
- 参数说明:无
- 返回说明:返回读到的字节
******************************************************************/

u8 SPI_FLASH_ReadByte(void) //SPI读一个字节
{
  u8 i;
    u8 byte;
   
    byte=0;
    for (i=0; i<8; i++)
    {
        byte <<= 1;
        SPI_FLASH_SCK_S_1;

        if(SPI_FLASH_MISO_S_G)
        {
            byte |= 1;        //Wait SDO to go Hi
        }
        SPI_FLASH_SCK_S_0;
    }
   
    return byte;

}
#endif

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

61

主题

1209

帖子

7

粉丝