发新帖我要提问
12
返回列表
打印
[应用相关]

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

[复制链接]
楼主: ADZ2016
手机看帖
扫描二维码
随时随地手机跟帖
21
ADZ2016|  楼主 | 2018-9-3 15:03 | 只看该作者 回帖奖励 |倒序浏览
/*******************************************************************************
* Function Name  : SPI_FLASH_WriteEnable
* Description    : Enables the write access to the FLASH.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_WriteEnable(void)
{
  /* Select the FLASH: Chip Select low */
  SPI_FLASH_CS_LOW();

  /* Send "Write Enable" instruction */
  SPI_FLASH_SendByte(W25X_WriteEnable);

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

使用特权

评论回复
22
ADZ2016|  楼主 | 2018-9-3 15:04 | 只看该作者
/*******************************************************************************
* Function Name  : SPI_FLASH_WaitForWriteEnd
* Description    : Polls the status of the Write In Progress (WIP) flag in the
*                  FLASH's status  register  and  loop  until write  opertaion
*                  has completed.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SPI_FLASH_WaitForWriteEnd(void)
{
  u8 FLASH_Status = 0;

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

  /* Send "Read Status Register" instruction */
  SPI_FLASH_SendByte(W25X_ReadStatusReg);

  /* Loop as long as the memory is busy with a write cycle */
  do
  {
#ifdef SPI_FLASH_ANALOG
    //SPI_FLASH_SendByte(Dummy_Byte);
    FLASH_Status = SPI_FLASH_ReadByte();//模拟SPI 读取
#else
    /* Send a dummy byte to generate the clock needed by the FLASH
    and put the value of the status register in FLASH_Status variable */
    FLASH_Status = SPI_FLASH_SendByte(Dummy_Byte);   
#endif
  }
  while ((FLASH_Status & WIP_Flag) == SET); /* Write in progress */

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

使用特权

评论回复
23
ADZ2016|  楼主 | 2018-9-3 15:05 | 只看该作者
//进入掉电模式
void SPI_Flash_PowerDown(void)   
{
  /* Select the FLASH: Chip Select low */
  SPI_FLASH_CS_LOW();

  /* Send "Power Down" instruction */
  SPI_FLASH_SendByte(W25X_PowerDown);

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

使用特权

评论回复
24
ADZ2016|  楼主 | 2018-9-3 15:05 | 只看该作者
//唤醒
void SPI_Flash_WAKEUP(void)   
{
  /* Select the FLASH: Chip Select low */
  SPI_FLASH_CS_LOW();

  /* Send "Power Down" instruction */
  SPI_FLASH_SendByte(W25X_ReleasePowerDown);

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

使用特权

评论回复
25
ADZ2016|  楼主 | 2018-9-3 15:05 | 只看该作者
#ifndef __SPI_FLASH_H
#define __SPI_FLASH_H
#define SPI_FLASH_ANALOG  /*SPI_FLASH_HAL*/
#define _BOARD  //DEMO Board   测试
#include "stm32f10x.h"

#ifdef SPI_FLASH_HAL  /* 硬件SPI配置 */
#define SPI_FLASH_SPI                           SPI2
#define SPI_FLASH_SPI_CLK                       RCC_APB2Periph_SPI2
#define SPI_FLASH_SPI_SCK_PIN                   GPIO_Pin_14                  /* PD.14 */
#define SPI_FLASH_SPI_SCK_GPIO_PORT             GPIOD                       /* GPIOD */
#define SPI_FLASH_SPI_SCK_GPIO_CLK              RCC_APB2Periph_GPIOD
#define SPI_FLASH_SPI_MISO_PIN                  GPIO_Pin_7                  /* PC.07 */
#define SPI_FLASH_SPI_MISO_GPIO_PORT            GPIOC                       /* GPIOC */
#define SPI_FLASH_SPI_MISO_GPIO_CLK             RCC_APB2Periph_GPIOC
#define SPI_FLASH_SPI_MOSI_PIN                  GPIO_Pin_13                  /* PD.13 */
#define SPI_FLASH_SPI_MOSI_GPIO_PORT            GPIOD                       /* GPIOD */
#define SPI_FLASH_SPI_MOSI_GPIO_CLK             RCC_APB2Periph_GPIOD
#define SPI_FLASH_CS_PIN                        GPIO_Pin_8                  /* PC.08 */
#define SPI_FLASH_CS_GPIO_PORT                  GPIOC                       /* GPIOC */
#define SPI_FLASH_CS_GPIO_CLK                   RCC_APB2Periph_GPIOC

#else   /* 模拟SPI配置 */
#ifdef FIRE_BOARD
// SPI_SCK
#define SPI_FLASH_SCK_S        GPIO_PORT_A,GPIO_PIN_5
#define SPI_FLASH_SCK_PORT_S   GPIO_PORT_A
#define SPI_FLASH_SCK_PIN_S    GPIO_PIN_5

// SPI_MISO
#define SPI_FLASH_MISO_S       GPIO_PORT_A,GPIO_PIN_6
#define SPI_FLASH_MISO_PORY_S  GPIO_PORT_A
#define SPI_FLASH_MISO_PIN_S   GPIO_PIN_6

// SPI_MOSI
#define SPI_FLASH_MOSI_S       GPIO_PORT_A,GPIO_PIN_7
#define SPI_FLASH_MOSI_PORY_S  GPIO_PORT_A
#define SPI_FLASH_MOSI_PIN_S   GPIO_PIN_7

// NSS
#define SPI_FLASH_NSS_S            GPIO_PORT_A,GPIO_PIN_4
#define SPI_FLASH_NSS_PORT_S       GPIO_PORT_A
#define SPI_FLASH_NSS_PIN_S        GPIO_PIN_4

// io ctrl
#define SPI_FLASH_SCK_S_1      {GPIOA->BSRR = GPIO_Pin_5;}
#define SPI_FLASH_SCK_S_0      {GPIOA->BRR = GPIO_Pin_5;}

#define SPI_FLASH_MISO_S_G     (GPIOA->IDR & GPIO_Pin_6)

#define SPI_FLASH_MOSI_S_1     {GPIOA->BSRR = GPIO_Pin_7;}
#define SPI_FLASH_MOSI_S_0     {GPIOA->BRR = GPIO_Pin_7;}

#define SPI_FLASH_NSS_S_1     {GPIOA->BSRR = GPIO_Pin_4;}
#define SPI_FLASH_NSS_S_0     {GPIOA->BRR = GPIO_Pin_4;}

#else
// SPI_SCK
#define SPI_FLASH_SCK_S        GPIO_PORT_D,GPIO_PIN_14
#define SPI_FLASH_SCK_PORT_S   GPIO_PORT_D
#define SPI_FLASH_SCK_PIN_S    GPIO_PIN_14

// SPI_MISO
#define SPI_FLASH_MISO_S       GPIO_PORT_C,GPIO_PIN_7
#define SPI_FLASH_MISO_PORY_S  GPIO_PORT_C
#define SPI_FLASH_MISO_PIN_S   GPIO_PIN_7

// SPI_MOSI
#define SPI_FLASH_MOSI_S       GPIO_PORT_D,GPIO_PIN_13
#define SPI_FLASH_MOSI_PORY_S  GPIO_PORT_D
#define SPI_FLASH_MOSI_PIN_S   GPIO_PIN_13

// NSS
#define SPI_FLASH_NSS_S            GPIO_PORT_C,GPIO_PIN_8
#define SPI_FLASH_NSS_PORT_S       GPIO_PORT_C
#define SPI_FLASH_NSS_PIN_S        GPIO_PIN_8

// io ctrl
#define SPI_FLASH_SCK_S_1      {GPIOD->BSRR = GPIO_Pin_14;}
#define SPI_FLASH_SCK_S_0      {GPIOD->BRR = GPIO_Pin_14;}

#define SPI_FLASH_MISO_S_G     (GPIOC->IDR & GPIO_Pin_7)

#define SPI_FLASH_MOSI_S_1     {GPIOD->BSRR = GPIO_Pin_13;}
#define SPI_FLASH_MOSI_S_0     {GPIOD->BRR = GPIO_Pin_13;}

#define SPI_FLASH_NSS_S_1     {GPIOC->BSRR = GPIO_Pin_8;}
#define SPI_FLASH_NSS_S_0     {GPIOC->BRR = GPIO_Pin_8;}
#endif   /*SPI配置 */

#endif   /*SPI配置 */

// NSS
#define SPI_FLASH_CS_LOW()       GPIO_ResetBits(GPIOC, GPIO_Pin_8)
#define SPI_FLASH_CS_HIGH()      GPIO_SetBits(GPIOC, GPIO_Pin_8)

//Write_Protect
#define SPI_FLASH_Write_Protect_Assert()      GPIO_ResetBits(GPIOC, GPIO_Pin_6)
#define SPI_FLASH_Write_Protect_Deassert()      GPIO_SetBits(GPIOC, GPIO_Pin_6)

//Hold
#define SPI_FLASH_Hold_Assert()      GPIO_ResetBits(GPIOD, GPIO_Pin_15)
#define SPI_FLASH_Hold_Deassert()      GPIO_SetBits(GPIOD, GPIO_Pin_15)

void SPI_FLASH_Write_Protect_ENABLE(void);//flash 关闭写保护
void SPI_FLASH_Write_Protect_DISABLE(void);//flash 打开写保护
void SPI_FLASH_Hold_ENABLE(void);//flash HOLD ENABLE
void SPI_FLASH_Hold_DISABLE(void);//flash HOLD DISABLE

void SPI_FLASH_Init(void);
void SPI_FLASH_SectorErase(u32 SectorAddr);
void SPI_FLASH_BulkErase(void);
void SPI_FLASH_PageWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite);
void SPI_FLASH_BufferWrite(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite);
void SPI_FLASH_BufferRead(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead);
u32 SPI_FLASH_ReadID(void);
u32 SPI_FLASH_ReadDeviceID(void);
void SPI_FLASH_StartReadSequence(u32 ReadAddr);
void SPI_Flash_PowerDown(void);
void SPI_Flash_WAKEUP(void);

#ifdef SPI_FLASH_ANALOG
void SPI_FLASH_SendByte(u8 byte);
#else
u8 SPI_FLASH_SendByte(u8 byte);
#endif

u8 SPI_FLASH_ReadByte(void);
u16 SPI_FLASH_SendHalfWord(u16 HalfWord);
void SPI_FLASH_WriteEnable(void);
void SPI_FLASH_WaitForWriteEnd(void);

#endif /* __SPI_FLASH_H */

使用特权

评论回复
26
ADZ2016|  楼主 | 2018-9-3 15:06 | 只看该作者
/* 获取缓冲区的长度 */
#define TxBufferSize1   (countof(TxBuffer1) - 1)
#define RxBufferSize1   (countof(TxBuffer1) - 1)
#define countof(a)      (sizeof(a) / sizeof(*(a)))
#define  BufferSize (countof(Tx_Buffer)-1)

#define  FLASH_WriteAddress     0x00000
#define  FLASH_ReadAddress      FLASH_WriteAddress
#define  FLASH_SectorToErase    FLASH_WriteAddress
#define  sFLASH_ID              0xEF3013  //0x00300000  //0xEF3015

void FLSASH_Test_Ctrl(void);
// 函数原型声明
void Delay(__IO uint32_t nCount);

使用特权

评论回复
27
ADZ2016|  楼主 | 2018-9-3 15:06 | 只看该作者
//#include "stm32f10x.h"
#include "spi_flash.h"
#include "debug.h"
#include "spi_flash_ctrl.h"
typedef enum { FAILED = 0, PASSED = !FAILED} TestStatus;
/* 发送缓冲区初始化 */
u8 Tx_Buffer[] = "OK!";
u8 Rx_Buffer[BufferSize];

u8 DeviceID = 0;
volatile u32 FlashID = 0;
volatile TestStatus TransferStatus1 = FAILED;

TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength);

使用特权

评论回复
28
ADZ2016|  楼主 | 2018-9-3 15:07 | 只看该作者
/*
* 函数名:Buffercmp
* 描述  :比较两个缓冲区中的数据是否相等
* 输入  :-pBuffer1     src缓冲区指针
*         -pBuffer2     dst缓冲区指针
*         -BufferLength 缓冲区长度
* 输出  :无
* 返回  :-PASSED pBuffer1 等于   pBuffer2
*         -FAILED pBuffer1 不同于 pBuffer2
*/
TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength)
{
  while(BufferLength--)
  {
    if(*pBuffer1 != *pBuffer2)
    {
      return FAILED;
    }

    pBuffer1++;
    pBuffer2++;
  }
  return PASSED;
}

使用特权

评论回复
29
ADZ2016|  楼主 | 2018-9-3 15:07 | 只看该作者
void Delay(__IO uint32_t nCount)
{
  for(; nCount != 0; nCount--);
}

使用特权

评论回复
30
ADZ2016|  楼主 | 2018-9-3 15:08 | 只看该作者
void FLSASH_Test_Ctrl(void)
{

  /* Get SPI Flash Device ID */
  DeviceID = SPI_FLASH_ReadDeviceID();
  
        Delay( 200 );

  /* Get SPI Flash ID */
  FlashID = SPI_FLASH_ReadID();

  printf("\r\n FlashID is 0x%X,  Manufacturer Device ID is 0x%X\r\n", FlashID, DeviceID);

  /* Check the SPI Flash ID */
  if (FlashID == sFLASH_ID)  /* #define  sFLASH_ID  0xEF3015 */
  {
  
    printf("\r\n 检测到串行flash W25X40 !\r\n");
   
    /* Erase SPI FLASH Sector to write on */
    SPI_FLASH_SectorErase(FLASH_SectorToErase);                  
   
    /* 将发送缓冲区的数据写到flash中 */
    SPI_FLASH_BufferWrite(Tx_Buffer, FLASH_WriteAddress, BufferSize);
                printf("\r\n 写入的数据为:%s \r\t", Tx_Buffer);

    /* 将刚刚写入的数据读出来放到接收缓冲区中 */
    SPI_FLASH_BufferRead(Rx_Buffer, FLASH_ReadAddress, BufferSize);
                printf("\r\n 读出的数据为:%s \r\n", Tx_Buffer);

    /* 检查写入的数据与读出的数据是否相等 */
    TransferStatus1 = Buffercmp(Tx_Buffer, Rx_Buffer, BufferSize);

    if( PASSED == TransferStatus1 )
    {   
        printf("\r\n 4M串行flash(W25X40)测试成功!\n\r");
    }
    else
    {        
        printf("\r\n 4M串行flash(W25X40)测试失败!\n\r");
    }
  }
  else
  {   
    printf("\r\n 获取不到 W25X40 ID!\n\r");
  }

  SPI_Flash_PowerDown();  
}

使用特权

评论回复
31
stm32jy| | 2018-9-3 20:20 | 只看该作者
也可以通过模拟SPI来驱动NRF24L01 模块吧

使用特权

评论回复
32
junpeng324| | 2018-9-3 21:10 | 只看该作者
自己曾写过模拟的SPI可是没成功,不知道什么原因

使用特权

评论回复
33
junpeng324| | 2018-9-3 21:12 | 只看该作者
现在一直用硬件SPI

使用特权

评论回复
34
八层楼| | 2018-9-4 08:57 | 只看该作者
用的什么芯片啊

使用特权

评论回复
35
幽竹静风思雨| | 2019-6-25 10:30 | 只看该作者
老哥你好,如果有时间可否发一份软件模拟spi读写flash的程序工程到我的邮箱1782963120@qq.com

使用特权

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

本版积分规则