日韩一区二区三区精品,欧美疯狂xxxxbbbb牲交,热99re久久免费视精品频,人妻互换 综合,欧美激情肉欲高潮视频

GD32F303固件庫開發(fā)(16)----移植兆易創(chuàng)新SPI Nor Flash之GD25Q64Flash

發(fā)布者:superstar11最新更新時間:2024-12-05 來源: elecfans關鍵字:GD32F303  固件庫開發(fā)  SPI  Nor  Flash 手機看文章 掃描二維碼
隨時隨地手機看文章

spi概述

SPI是串行外設接口(Serial Peripheral Interface)的縮寫,是一種高速的,全雙工,同步的通信總線,并且在芯片的管腳上只占用四根線,節(jié)約了芯片的管腳,同時為PCB的布局上節(jié)省空間,提供方便,正是出于這種簡單易用的特性,越來越多的芯片集成了這種通信協(xié)議,比如 EEPROM,F(xiàn)LASH,實時時鐘,AD轉換器。 W25Q64 是一款SPI接口的Flash芯片,其存儲空間為 64Mbit,相當于8M字節(jié)。W25Q64可以支持 SPI 的模式 0 和模式 3,也就是 CPOL=0/CPHA=0 和CPOL=1/CPHA=1 這兩種模式。 
在這里插入圖片描述

視頻教程

https://www.bilibili.com/video/BV16W4y147R1/


樣品申請

https://www.wjx.top/vm/wFGhGPF.aspx#

csdn課程

課程更加詳細。
https://download.csdn.net/course/detail/37144

生成例程

這里準備了自己繪制的開發(fā)板進行驗證。
在這里插入圖片描述

SPI配置

在開發(fā)板中有arduino接口,配置這幾個接口為spi。
在這里插入圖片描述
本次實驗使用的SPI與Flash通信,配置如下。 SPI的通信原理很簡單,它以主從方式工作,這種模式通常有一個主設備和一個或多個從設備,需要至少4根線,事實上3根也可以(單向傳輸時)。也是所有基于SPI的設備共有的,它們是MISO(主設備數(shù)據(jù)輸入)、MOSI(主設備數(shù)據(jù)輸出)、SCLK(時鐘)、CS(片選)。 (1)MISO– Master Input Slave Output,主設備數(shù)據(jù)輸入,從設備數(shù)據(jù)輸出; (2)MOSI– Master Output Slave Input,主設備數(shù)據(jù)輸出,從設備數(shù)據(jù)輸入; (3)SCLK – Serial Clock,時鐘信號,由主設備產(chǎn)生; (4)CS – Chip Select,從設備使能信號,由主設備控制。

在這里插入圖片描述

負責通訊的3根線了。通訊是通過數(shù)據(jù)交換完成的,這里先要知道SPI是串行通訊協(xié)議,也就是說數(shù)據(jù)是一位一位的傳輸?shù)摹_@就是SCLK時鐘線存在的原因,由SCLK提供時鐘脈沖,SDI,SDO則基于此脈沖完成數(shù)據(jù)傳輸。數(shù)據(jù)輸出通過 SDO線,數(shù)據(jù)在時鐘上升沿或下降沿時改變,在緊接著的下降沿或上升沿被讀取。完成一位數(shù)據(jù)傳輸,輸入也使用同樣原理。因此,至少需要8次時鐘信號的改變(上沿和下沿為一次),才能完成8位數(shù)據(jù)的傳輸。 時鐘信號線SCLK只能由主設備控制,從設備不能控制。同樣,在一個基于SPI的設備中,至少有一個主設備。這樣的傳輸方式有一個優(yōu)點,在數(shù)據(jù)位的傳輸過程中可以暫停,也就是時鐘的周期可以為不等寬,因為時鐘線由主設備控制,當沒有時鐘跳變時,從設備不采集或傳送數(shù)據(jù)。SPI還是一個數(shù)據(jù)交換協(xié)議:因為SPI的數(shù)據(jù)輸入和輸出線獨立,所以允許同時完成數(shù)據(jù)的輸入和輸出。芯片集成的SPI串行同步時鐘極性和相位可以通過寄存器配置,IO模擬的SPI串行同步時鐘需要根據(jù)從設備支持的時鐘極性和相位來通訊。 最后,SPI接口的一個缺點:沒有指定的流控制,沒有應答機制確認是否接收到數(shù)據(jù)。

NOR Flash

NOR Flash是一種非易失閃存技術,是Intel在1988年創(chuàng)建。是市場上兩種主要的非易失閃存技術之一。 以GD25Q64E為例,該 Flash為64M-bit大小,即8192K-Byte。

在這里插入圖片描述

W25Q64將8M的容量分為127個塊(Block),每個塊大小為64K字節(jié),每個塊又分為16個扇區(qū)(Sector),每個扇區(qū)4K個字節(jié)。W25Q64的最小擦除單位為一個扇區(qū),也就是每次必須擦除4K個字節(jié)。 即4K16128=8192K=8M

在這里插入圖片描述

W25Q64的原理及應用

復位初始化

對于復位,需要發(fā)送0x66和0x99

在這里插入圖片描述

代碼中的初始化。


/* Reset Operations */

#define RESET_ENABLE_CMD                     0x66

#define RESET_MEMORY_CMD                     0x99

/**

  * @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 */    

    for(int i=0;i< 2;i++){

    spi_SendRcvByte(SPI0,cmd[i]);

}        

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

    W25Qx_Disable();

}


在這里插入圖片描述

ID

對于兆易創(chuàng)新W25Q64,主要有三種查詢ID方式。

在這里插入圖片描述

可以使用90H查詢設備ID,以判斷是否是W25Q64設備。

在這里插入圖片描述

/* Identification Operations */

#define READ_ID_CMD                          0x9F

/**

  * @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);

    for(int i=0;i< 4;i++)

        spi_SendRcvByte(SPI0,cmd[i]);

    for(int i=0;i< 2;i++)

    {

        ID[i]=spi_SendRcvByte(SPI0,0x00);

}

    W25Qx_Disable();        

}


在這里插入圖片描述

讀取數(shù)據(jù)

對于兆易創(chuàng)新W25Q64,讀取數(shù)據(jù)使用0x03指令,后面添加需要讀取的數(shù)據(jù)地址。 數(shù)據(jù)可以一直進行讀取,當不需要讀取數(shù)據(jù)時候將片選CS拉高,關閉時鐘SCLK即可。

在這里插入圖片描述

#define READ_CMD                             0x03


/**

  * @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];

    uint8_t status;

    /* 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);    

    for(int i= 0;i< 4;i++)

        spi_SendRcvByte(SPI0,cmd[i]);

    /* Reception of the data */

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

//  {

//    return W25Qx_ERROR;

//  }

    for(int i= 0;i< Size;i++)

        pData[i]=spi_SendRcvByte(SPI0,0x00);

    if (status != 0x00)

  {

    return W25Qx_ERROR;

  }

    W25Qx_Disable();

    return W25Qx_OK;

}

以讀取10個數(shù)據(jù)為例子,波形如下所示。


BSP_W25Qx_Read(rData2,0x1000,0x00a);


在這里插入圖片描述

擦除扇區(qū)

最小的擦除單位是扇區(qū),擦除指令為0x20和3字節(jié)的地址。

在這里插入圖片描述


#define SECTOR_ERASE_CMD                     0x20

/**

  * @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=0 ;

    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);    

    for(int i =0;i< 4;i++)

        spi_SendRcvByte(SPI0,cmd[i]);

    /*Deselect the FLASH: Chip Select high */

    W25Qx_Disable();

delay_1ms(1);

    /* Wait the end of Flash writing */

    while(BSP_W25Qx_GetStatus() == W25Qx_BUSY)

    {

    tickstart++;

        /* Check for the Timeout */

    if(tickstart > W25Q128FV_SECTOR_ERASE_MAX_TIME)

    {        

            return W25Qx_TIMEOUT;

    }

    }

    return W25Qx_OK;

}


在這里插入圖片描述

寫數(shù)據(jù)

對于寫數(shù)據(jù)到flash中,使用0x02指令進行寫數(shù)據(jù),后面還需要指定24位地址,才能進行寫數(shù)據(jù)。

在這里插入圖片描述

#define PAGE_PROG_CMD                        0x02

/**

  * @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 =0;


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

  current_addr = 0;


  while (current_addr <= WriteAddr)//判斷地址屬于哪一扇區(qū)開始

  {

    current_addr += W25Q128FV_PAGE_SIZE;//0x100- > 256 bytes

  }

  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;

//    }

        for(int i=0;i< 4;i++)

            spi_SendRcvByte(SPI0,cmd[i]);


    /* Transmission of the data */

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

//    {

//      return W25Qx_ERROR;

//    }

        for(int i=0;i< current_size;i++)

            spi_SendRcvByte(SPI0,pData[i]);


            W25Qx_Disable();

        /* Wait the end of Flash writing */

        while(BSP_W25Qx_GetStatus() == W25Qx_BUSY)

        {

            tickstart++;

            /* Check for the Timeout */

            if(tickstart > W25Qx_TIMEOUT_VALUE)

            {        

                return W25Qx_TIMEOUT;

            }

        }


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

    current_addr += current_size;

[1] [2] [3] [4] [5] [6]
關鍵字:GD32F303  固件庫開發(fā)  SPI  Nor  Flash 引用地址:GD32F303固件庫開發(fā)(16)----移植兆易創(chuàng)新SPI Nor Flash之GD25Q64Flash

上一篇:基于GD32E503主控芯片實現(xiàn)直流數(shù)控電源的設計
下一篇:STM32CUBEMX開發(fā)GD32F303(2)----讀保護與寫保護

小廣播
設計資源 培訓 開發(fā)板 精華推薦

最新單片機文章

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發(fā)圈

 
機器人開發(fā)圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業(yè)務審批[2006]字第258號函 京公網(wǎng)安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved