日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【STM32H7】第3章 ThreadX FileX移植SDIO接口SD的基础知识

發布時間:2023/12/8 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【STM32H7】第3章 ThreadX FileX移植SDIO接口SD的基础知识 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

論壇原始地址(持續更新):http://www.armbbs.cn/forum.php?mod=viewthread&tid=100749

第3章?? ThreadX FileX移植SDIO接口SD的基礎知識

本章節為大家講解SDMMC(Secure digital input/output MultiMediaCard interface)總線的基礎知識和對應的HAL庫API。為下個章節SD卡的移植做準備。

目錄

第3章?? ThreadX FileX移植SDIO接口SD的基礎知識

3.1?? 初學者重要提示

3.2?? SDMMC總線基礎知識

3.2.1????? SDMMC總線的硬件框圖

3.2.2????? SDMMC時鐘

3.2.3????? SDMMC1和SDMMC2支持的RAM空間區別

3.2.4????? SDMMC支持的速度

3.2.5????? SDMMC支持UHS-I模式

3.2.6????? SDMMC自帶的DMA控制器IDMA

3.3?? SDMMC總線的HAL庫用法

3.3.1????? SDMMC總線結構體SD_TypeDef

3.3.2????? SDMMC總線初始化結構體SD_InitTypeDef

3.3.3????? SDMMC接SD卡信息結構體HAL_SD_CardInfoTypeDef

3.3.4????? SDMMC總線句柄結構體SD_HandleTypeDef

3.4?? SDMMC總線源文件stm32h7xx_hal_sd.c

3.4.1????? 函數HAL_SD_Init

3.4.2????? 函數HAL_SD_DeInit

3.4.3????? 函數HAL_SD_ReadBlocks

3.4.4????? 函數HAL_SD_WriteBlocks

3.4.5????? 函數HAL_SD_ReadBlocks_DMA

3.4.6????? 函數HAL_SD_WriteBlocks_DMA

3.4.7????? 函數HAL_SD_Erase

3.5?? 總結


?

3.1?? 初學者重要提示

  • ? 對于SDMMC控制SD卡或者eMMC,掌握本章的知識點就夠用了,更深入的認識可以看STM32H7的參考手冊。
  • ? 注意,操作SD卡是采用的函數HAL_SD_XXXX,而操作eMMC是采用的函數HAL_MMC_XXXX,也就是說他們采用的函數前綴是不同的。
  • ? SD卡官網: www.sdcard.org 。
  • ? SDMMC驅動eMMC支持1線,4線和8線模式,其中8線模式的最高速度可達208MB/S,實際速度受IO最大速度限制。
  • ? SDMMC驅動SD卡支持1線和4線模式。
  • ? STM32H7的SDMMC也支持eMMC:
    • ?【普及貼】各個廠家eMMC讀寫速度,鎂光,東芝,三星,ISSI和旺宏?? http://www.armbbs.cn/forum.php?mod=viewthread&tid=95954
    • ?H7的8線SDIO DMA驅動eMMC的裸機性能,讀43MB/S,寫18.8MB/S?? http://www.armbbs.cn/forum.php?mod=viewthread&tid=95953

    3.2?? SDMMC總線基礎知識

    3.2.1????? SDMMC總線的硬件框圖

    認識一個外設,最好的方式就是看它的框圖,方便我們快速的了解SDMMC的基本功能,然后再看手冊了解細節。

    通過這個框圖,我們可以得到如下信息:

    • ? sdmmc_ker_ck輸入

    SDMMC內核時鐘。

    • ? sdmmc_hclk輸入

    AHB時鐘。

    • ? sdmmc_it輸出

    SDMMC全局中斷。

    • ? sdmmc_dataend_trg輸出

    MDMA的SDMMC數據接收觸發信號。

    • ? SDMMC_CMD

    SD/SDIO/MMC卡雙向/響應信號。

    • ? SDMMC_D[7:0]

    SD/SDIO/MMC卡雙向數據線。

    • ? SDMMC_CKIN

    來自SD/SDIO/MMC卡的外部驅動器的時鐘反饋(用于SDR12,SDR25,SDR50和DDR50)。

    • ? SDMMC_CK

    SD/SDIO/MMC卡的時鐘。

    • ? SDMMC_CDIR

    SDMMC_CMD信號的SD/SDIO/MMC卡I/O方向指示。

    • ? SDMMC_D123DIR

    SDMMC_D[3:1]數據線的SD/SDIO/MMC卡I/O方向指示。

    • ? SDMMC_D0DIR

    SDMMC_D0數據線的SD/SDIO/MMC卡I/O方向指示。

    ?

    STM32H7有兩個SDMMC控制器,SDMMC1和SDMMC2,這兩個控制器支持的功能是一樣的。

    3.2.2????? SDMMC時鐘

    SDMMC控制器的時鐘來源:

    ?

    SDMMC1和SDMMC2時鐘源是一樣的:

    3.2.3????? SDMMC1和SDMMC2支持的RAM空間區別

    注:大家應用時要特別注意這個問題。

    使用STM32H7的SDIO1僅支持AXI SRAM,而SDIO2是AXI,SRAM1,SRAM2和SRAM3都支持的

    ?

    3.2.4????? SDMMC支持的速度

    驅動SD卡支持的最大總線速度:

    驅動eMMC支持的最大總線速度:

    關于這兩個數據表,注意以下幾點:

    • ? 驅動SD卡最大支持4bit,驅動eMMC最大支持8bit。
    • ? 針對信號電壓1.8V或者1.2V,STM32H7需要外接專門的PHY芯片才可以驅動。
    • ?最大IO翻轉限制說的是SDR50,SDR104這種高速通信。平時用的DS,HS這種,無壓力,刷滿速不成問題。

    3.2.5????? SDMMC支持UHS-I模式

    STM32H7的SDIO外接支持UHS-I 模式 (SDR12, SDR25, SDR50, SDR104和DDR50)需要1.8的電平轉換器。STM32H7參考手冊給了一個型號ST6G3244ME:

    ?

    3.2.6????? SDMMC自帶的DMA控制器IDMA

    STM32H7的SDMMC自帶了專用的DMA控制器IDMA,支持突發,也支持雙緩沖。為什么要自帶DMA控制器? 主要原因是STM32H7的通用DMA1和DMA2已經無法滿足SDMMC高速通信速度。在本教程的第62章專門為大家測試過。通過讓SDMMC自帶控制器,這個問題就迎刃而解。

    3.3?? SDMMC總線的HAL庫用法

    3.3.1????? SDMMC總線結構體SD_TypeDef

    SDMMC總線相關的寄存器是通過HAL庫中的結構體SD_TypeDef定義,在stm32h743xx.h中可以找到這個類型定義:

    #define SD_TypeDef SDMMC_TypeDef typedef struct {__IO uint32_t POWER; /*!< SDMMC power control register, Address offset: 0x00 */__IO uint32_t CLKCR; /*!< SDMMC clock control register, Address offset: 0x04 */__IO uint32_t ARG; /*!< SDMMC argument register, Address offset: 0x08 */__IO uint32_t CMD; /*!< SDMMC command register, Address offset: 0x0C */__I uint32_t RESPCMD; /*!< SDMMC command response register, Address offset: 0x10 */__I uint32_t RESP1; /*!< SDMMC response 1 register, Address offset: 0x14 */__I uint32_t RESP2; /*!< SDMMC response 2 register, Address offset: 0x18 */__I uint32_t RESP3; /*!< SDMMC response 3 register, Address offset: 0x1C */__I uint32_t RESP4; /*!< SDMMC response 4 register, Address offset: 0x20 */__IO uint32_t DTIMER; /*!< SDMMC data timer register, Address offset: 0x24 */__IO uint32_t DLEN; /*!< SDMMC data length register, Address offset: 0x28 */__IO uint32_t DCTRL; /*!< SDMMC data control register, Address offset: 0x2C */__I uint32_t DCOUNT; /*!< SDMMC data counter register, Address offset: 0x30 */__I uint32_t STA; /*!< SDMMC status register, Address offset: 0x34 */__IO uint32_t ICR; /*!< SDMMC interrupt clear register, Address offset: 0x38 */__IO uint32_t MASK; /*!< SDMMC mask register, Address offset: 0x3C */__IO uint32_t ACKTIME; /*!< SDMMC Acknowledgement timer register, Address offset: 0x40 */uint32_t RESERVED0[3]; /*!< Reserved, 0x44 - 0x4C - 0x4C */__IO uint32_t IDMACTRL; /*!< SDMMC DMA control register, Address offset: 0x50 */__IO uint32_t IDMABSIZE; /*!< SDMMC DMA buffer size register, Address offset: 0x54 */__IO uint32_t IDMABASE0; /*!< SDMMC DMA buffer 0 base address register, Address offset: 0x58 */__IO uint32_t IDMABASE1; /*!< SDMMC DMA buffer 1 base address register, Address offset: 0x5C */uint32_t RESERVED1[8]; /*!< Reserved, 0x60-0x7C */__IO uint32_t FIFO; /*!< SDMMC data FIFO register, Address offset: 0x80 */uint32_t RESERVED2[222]; /*!< Reserved, 0x84-0x3F8 */__IO uint32_t IPVR; /*!< SDMMC data FIFO register, Address offset: 0x3FC */ } SDMMC_TypeDef;

    這個結構體的成員名稱和排列次序和CPU的寄存器是一 一對應的。

    __IO表示volatile, 這是標準C語言中的一個修飾字,表示這個變量是非易失性的,編譯器不要將其優化掉。core_m7.h 文件定義了這個宏:

    #define __O volatile /*!< Defines 'write only' permissions */ #define __IO volatile /*!< Defines 'read / write' permissions */

    下面我們看下SDMMC的定義,在stm32h743xx.h文件。

    #define PERIPH_BASE (0x40000000UL) #define D1_AHB1PERIPH_BASE (PERIPH_BASE + 0x12000000UL) #define D2_AHB2PERIPH_BASE (PERIPH_BASE + 0x08020000UL)#define SDMMC1_BASE (D1_AHB1PERIPH_BASE + 0x7000UL) #define SDMMC2_BASE (D2_AHB2PERIPH_BASE + 0x2400UL)#define SDMMC1 ((SDMMC_TypeDef *) SDMMC1_BASE) #define SDMMC2 ((SDMMC_TypeDef *) SDMMC2_BASE) <----- 展開這個宏,(SDMMC_TypeDef *)0x48022400

    我們訪問SDMMC1的CMD寄存器可以采用這種形式:SDMMC1->CMD = 0。

    3.3.2????? SDMMC總線初始化結構體SD_InitTypeDef

    下面是SDMMC總線的初始化結構體:

    #define SD_InitTypeDef SDMMC_InitTypeDef typedef struct {uint32_t ClockEdge; uint32_t ClockPowerSave; uint32_t BusWide; uint32_t HardwareFlowControl; uint32_t ClockDiv; #if (USE_SD_TRANSCEIVER != 0U)uint32_t TranceiverPresent; #endif }SDMMC_InitTypeDef;

    下面將結構體成員逐一做個說明:

    • ?ClockEdge

    用于設置SDMMC的數據或者命令變化的時鐘沿。

    #define SDMMC_CLOCK_EDGE_RISING ((uint32_t)0x00000000U) #define SDMMC_CLOCK_EDGE_FALLING SDMMC_CLKCR_NEGEDGE
    • ? ClockPowerSave

    用于設置空閑狀態,是否輸出時鐘。

    #define SDMMC_CLOCK_POWER_SAVE_DISABLE ((uint32_t)0x00000000U) #define SDMMC_CLOCK_POWER_SAVE_ENABLE SDMMC_CLKCR_PWRSAV
    • ? BusWide

    用于設置SDMMC總線位寬。

    #define SDMMC_BUS_WIDE_1B ((uint32_t)0x00000000U) #define SDMMC_BUS_WIDE_4B SDMMC_CLKCR_WIDBUS_0 #define SDMMC_BUS_WIDE_8B SDMMC_CLKCR_WIDBUS_1
    • ? HardwareFlowControl

    用于設置時候使能硬件流控制。

    #define SDMMC_HARDWARE_FLOW_CONTROL_DISABLE ((uint32_t)0x00000000U) #define SDMMC_HARDWARE_FLOW_CONTROL_ENABLE SDMMC_CLKCR_HWFC_EN
    • ?ClockDiv

    用于設置SDMMC時鐘分頻,參數范圍0到1023。

    • ? TranceiverPresent

    用于設置是否帶1.8V收發器。

    #define SDMMC_TRANSCEIVER_UNKNOWN ((uint32_t)0x00000000U) #define SDMMC_TRANSCEIVER_NOT_PRESENT ((uint32_t)0x00000001U) #define SDMMC_TRANSCEIVER_PRESENT ((uint32_t)0x00000002U)

    3.3.3????? SDMMC接SD卡信息結構體HAL_SD_CardInfoTypeDef

    下面是SDMMC總線的卡信息結構體:

    typedef struct {uint32_t CardType; /*!< Specifies the card Type */uint32_t CardVersion; /*!< Specifies the card version */uint32_t Class; /*!< Specifies the class of the card class */uint32_t RelCardAdd; /*!< Specifies the Relative Card Address */uint32_t BlockNbr; /*!< Specifies the Card Capacity in blocks */uint32_t BlockSize; /*!< Specifies one block size in bytes */uint32_t LogBlockNbr; /*!< Specifies the Card logical Capacity in blocks */uint32_t LogBlockSize; /*!< Specifies logical block size in bytes */uint32_t CardSpeed; /*!< Specifies the card Speed */ }HAL_SD_CardInfoTypeDef;

    下面將結構體成員逐一做個說明:

    • ? CardType

    卡類型。

    /*!< SD Standard Capacity <2Go */ #define CARD_SDSC ((uint32_t)0x00000000U) /*!< SD High Capacity <32Go, SD Extended Capacity <2To */ #define CARD_SDHC_SDXC ((uint32_t)0x00000001U) #define CARD_SECURED ((uint32_t)0x00000003U)
    • ? CardVersion

    卡版本。

    #define CARD_V1_X ((uint32_t)0x00000000U) #define CARD_V2_X ((uint32_t)0x00000001U)
    • ? Class

    卡類型。

    • ? RelCardAdd

    卡相對地址。

    • ? BlockNbr

    整個卡的塊數。

    • ? BlockSize

    每個塊的字節數。

    • ? LogBlockNbr

    整個卡的邏輯塊數。

    • ? LogBlockSize

    邏輯塊大小

    #define SPI_FIRSTBIT_MSB (0x00000000UL) #define SPI_FIRSTBIT_LSB SPI_CFG2_LSBFRST
    • ? CardSpeed

    用于設置是否使能SPI總線的TI模式。

    /*!< Normal Speed Card <12.5Mo/s , Spec Version 1.01 */ #define CARD_NORMAL_SPEED ((uint32_t)0x00000000U) /*!< High Speed Card <25Mo/s , Spec version 2.00 */ #define CARD_HIGH_SPEED ((uint32_t)0x00000100U) /*!< UHS-I SD Card <50Mo/s for SDR50, DDR5 Cardsand <104Mo/s for SDR104, Spec version 3.01 */ #define CARD_ULTRA_HIGH_SPEED ((uint32_t)0x00000200U)

    3.3.4????? SDMMC總線句柄結構體SD_HandleTypeDef

    下面是SDMMC句柄結構體:

    #if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U) typedef struct __SD_HandleTypeDef #else typedef struct #endif /* USE_HAL_SD_REGISTER_CALLBACKS */ {SD_TypeDef *Instance; /*!< SD registers base address */SD_InitTypeDef Init; /*!< SD required parameters */HAL_LockTypeDef Lock; /*!< SD locking object */uint8_t *pTxBuffPtr; /*!< Pointer to SD Tx transfer Buffer */uint32_t TxXferSize; /*!< SD Tx Transfer size */uint8_t *pRxBuffPtr; /*!< Pointer to SD Rx transfer Buffer */uint32_t RxXferSize; /*!< SD Rx Transfer size */__IO uint32_t Context; /*!< SD transfer context */__IO HAL_SD_StateTypeDef State; /*!< SD card State */__IO uint32_t ErrorCode; /*!< SD Card Error codes */HAL_SD_CardInfoTypeDef SdCard; /*!< SD Card information */uint32_t CSD[4]; /*!< SD card specific data table */uint32_t CID[4]; /*!< SD card identification number table */#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)void (* TxCpltCallback) (struct __SD_HandleTypeDef *hsd);void (* RxCpltCallback) (struct __SD_HandleTypeDef *hsd);void (* ErrorCallback) (struct __SD_HandleTypeDef *hsd);void (* AbortCpltCallback) (struct __SD_HandleTypeDef *hsd);void (* Read_DMADblBuf0CpltCallback) (struct __SD_HandleTypeDef *hsd);void (* Read_DMADblBuf1CpltCallback) (struct __SD_HandleTypeDef *hsd);void (* Write_DMADblBuf0CpltCallback) (struct __SD_HandleTypeDef *hsd);void (* Write_DMADblBuf1CpltCallback) (struct __SD_HandleTypeDef *hsd); #if (USE_SD_TRANSCEIVER != 0U)void (* DriveTransceiver_1_8V_Callback) (FlagStatus status); #endif /* USE_SD_TRANSCEIVER */void (* MspInitCallback) (struct __SD_HandleTypeDef *hsd);void (* MspDeInitCallback) (struct __SD_HandleTypeDef *hsd); #endif /* USE_HAL_SD_REGISTER_CALLBACKS */ }SD_HandleTypeDef;

    注意事項:

    條件編譯USE_HAL_SD_REGISTER_CALLBACKS用來設置使用自定義回調還是使用默認回調,此定義一般放在stm32h7xx_hal_conf.h文件里面設置:

    ? #define?? USE_HAL_SD_REGISTER_CALLBACKS?? 1

    通過函數HAL_SD_RegisterCallback注冊回調,取消注冊使用函數HAL_SD_UnRegisterCallback。

    這里重點介紹下面幾個參數,其它參數主要是HAL庫內部使用和自定義回調函數。

    • ? SD_TypeDef?? *Instance

    這個參數是寄存器的例化,方便操作寄存器。

    • ? SD_InitTypeDef? Init

    這個參數在本章節3.2小節已經進行了詳細說明。

    3.4?? SDMMC總線源文件stm32h7xx_hal_sd.c

    此文件涉及到的函數較多,這里把幾個常用的函數做個說明:

    • ? HAL_SD_Init
    • ? HAL_SD_DeInit
    • ? HAL_SD_ReadBlocks
    • ? HAL_SD_WriteBlocks
    • ? HAL_SD_ReadBlocks_DMA
    • ? HAL_SD_WriteBlocks_DMA
    • ? HAL_SD_Erase

    3.4.1????? 函數HAL_SD_Init

    函數原型:

    HAL_StatusTypeDef HAL_SD_Init(SD_HandleTypeDef *hsd) {HAL_SD_CardStatusTypeDef CardStatus;uint32_t speedgrade, unitsize;uint32_t tickstart;/* 檢查句柄是否有效 */if(hsd == NULL){return HAL_ERROR;}/* 檢查參數 */assert_param(IS_SDMMC_ALL_INSTANCE(hsd->Instance));assert_param(IS_SDMMC_CLOCK_EDGE(hsd->Init.ClockEdge));assert_param(IS_SDMMC_CLOCK_POWER_SAVE(hsd->Init.ClockPowerSave));assert_param(IS_SDMMC_BUS_WIDE(hsd->Init.BusWide));assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(hsd->Init.HardwareFlowControl));assert_param(IS_SDMMC_CLKDIV(hsd->Init.ClockDiv));if(hsd->State == HAL_SD_STATE_RESET){/* 開鎖 */hsd->Lock = HAL_UNLOCKED;#if (USE_SD_TRANSCEIVER != 0U)/* 兼容 */if (hsd->Init.TranceiverPresent == SDMMC_TRANSCEIVER_UNKNOWN){hsd->Init.TranceiverPresent = SDMMC_TRANSCEIVER_PRESENT;} #endif #if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)/* 復位回調 */hsd->TxCpltCallback = HAL_SD_TxCpltCallback;hsd->RxCpltCallback = HAL_SD_RxCpltCallback;hsd->ErrorCallback = HAL_SD_ErrorCallback;hsd->AbortCpltCallback = HAL_SD_AbortCallback;hsd->Read_DMADblBuf0CpltCallback = HAL_SDEx_Read_DMADoubleBuf0CpltCallback;hsd->Read_DMADblBuf1CpltCallback = HAL_SDEx_Read_DMADoubleBuf1CpltCallback;hsd->Write_DMADblBuf0CpltCallback = HAL_SDEx_Write_DMADoubleBuf0CpltCallback;hsd->Write_DMADblBuf1CpltCallback = HAL_SDEx_Write_DMADoubleBuf1CpltCallback; #if (USE_SD_TRANSCEIVER != 0U)if (hsd->Init.TranceiverPresent == SDMMC_TRANSCEIVER_PRESENT){hsd->DriveTransceiver_1_8V_Callback = HAL_SD_DriveTransceiver_1_8V_Callback;} #endif if(hsd->MspInitCallback == NULL){hsd->MspInitCallback = HAL_SD_MspInit;}/* 初始化底層 */hsd->MspInitCallback(hsd); #else/* 初始化底層硬件 GPIO, CLOCK, CORTEX...etc */HAL_SD_MspInit(hsd); #endif /* USE_HAL_SD_REGISTER_CALLBACKS */}hsd->State = HAL_SD_STATE_BUSY;/* 初始化卡參數 */if (HAL_SD_InitCard(hsd) != HAL_OK){return HAL_ERROR;}if( HAL_SD_GetCardStatus(hsd, &CardStatus) != HAL_OK){return HAL_ERROR;}/* 獲取卡速度等信息 */speedgrade = CardStatus.UhsSpeedGrade;unitsize = CardStatus.UhsAllocationUnitSize;if ((hsd->SdCard.CardType == CARD_SDHC_SDXC) && ((speedgrade != 0U) || (unitsize != 0U))){hsd->SdCard.CardSpeed = CARD_ULTRA_HIGH_SPEED;}else{if (hsd->SdCard.CardType == CARD_SDHC_SDXC){hsd->SdCard.CardSpeed = CARD_HIGH_SPEED;}else{hsd->SdCard.CardSpeed = CARD_NORMAL_SPEED;}}/* 配置總線位寬 */if(HAL_SD_ConfigWideBusOperation(hsd, hsd->Init.BusWide) != HAL_OK){return HAL_ERROR;}/* 驗證卡初始化后是否就緒 */tickstart = HAL_GetTick();while((HAL_SD_GetCardState(hsd) != HAL_SD_CARD_TRANSFER)){if((HAL_GetTick()-tickstart) >= SDMMC_DATATIMEOUT){hsd->ErrorCode = HAL_SD_ERROR_TIMEOUT;hsd->State= HAL_SD_STATE_READY;return HAL_TIMEOUT;}}hsd->ErrorCode = HAL_SD_ERROR_NONE;hsd->Context = SD_CONTEXT_NONE;hsd->State = HAL_SD_STATE_READY;return HAL_OK; }

    函數描述:

    此函數用于初始化SD卡。

    函數參數:

    • ? 第1個參數是SD_HandleTypeDef類型結構體指針變量,用于配置要初始化的參數。
    • ? 返回值,返回HAL_TIMEOUT表示超時,HAL_ERROR表示參數錯誤,HAL_OK表示發送成功,HAL_BUSY表示忙,正在使用中。

    注意事項:

  • 函數HAL_SD_MspInit用于初始化SD的底層時鐘、引腳等功能。需要用戶自己在此函數里面實現具體的功能。由于這個函數是弱定義的,允許用戶在工程其它源文件里面重新實現此函數。當然,不限制一定要在此函數里面實現,也可以像早期的標準庫那樣,用戶自己初始化即可,更靈活些。
  • 如果形參hsd的結構體成員State沒有做初始狀態,這個地方就是個坑。特別是用戶搞了一個局部變量SD_HandleTypeDef SdHandle。
  • 對于局部變量來說,這個參數就是一個隨機值,如果是全局變量還好,一般MDK和IAR都會將全部變量初始化為0,而恰好這個 HAL_SD_STATE_RESET? = 0x00U。

    解決辦法有三

    方法1:用戶自己初始化SD和涉及到的GPIO等。

    方法2:定義SD_HandleTypeDef SdHandle為全局變量。

    方法3:下面的方法

    if(HAL_SD_DeInit(&SdHandle) != HAL_OK) {Error_Handler(); } if(HAL_SD_Init(&SdHandle) != HAL_OK) {Error_Handler(); }

    使用舉例:

    SD_HandleTypeDef uSdHandle;uSdHandle.Instance = SDMMC1;/* if CLKDIV = 0 then SDMMC Clock frequency = SDMMC Kernel Clockelse SDMMC Clock frequency = SDMMC Kernel Clock / [2 * CLKDIV].200MHz / (2*2) = 50MHz */ uSdHandle.Init.ClockDiv = 2; uSdHandle.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE; uSdHandle.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING; uSdHandle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE; uSdHandle.Init.BusWide = SDMMC_BUS_WIDE_4B; if(HAL_SD_Init(&uSdHandle) != HAL_OK) {sd_state = MSD_ERROR; }

    3.4.2????? 函數HAL_SD_DeInit

    函數原型:

    HAL_StatusTypeDef HAL_SD_DeInit(SD_HandleTypeDef *hsd) {/* 檢查SD卡句柄是否有效 */if(hsd == NULL){return HAL_ERROR;}/* 檢查參數 */assert_param(IS_SDMMC_ALL_INSTANCE(hsd->Instance));hsd->State = HAL_SD_STATE_BUSY;#if (USE_SD_TRANSCEIVER != 0U)/* 關閉1.8V模式 */if (hsd->Init.TranceiverPresent == SDMMC_TRANSCEIVER_PRESENT){ #if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)if(hsd->DriveTransceiver_1_8V_Callback == NULL){hsd->DriveTransceiver_1_8V_Callback = HAL_SD_DriveTransceiver_1_8V_Callback;}hsd->DriveTransceiver_1_8V_Callback(RESET); #elseHAL_SD_DriveTransceiver_1_8V_Callback(RESET); #endif } #endif/* 關閉SD卡電源 */SD_PowerOFF(hsd);#if defined (USE_HAL_SD_REGISTER_CALLBACKS) && (USE_HAL_SD_REGISTER_CALLBACKS == 1U)if(hsd->MspDeInitCallback == NULL){hsd->MspDeInitCallback = HAL_SD_MspDeInit;}/* 復位底層硬件 */hsd->MspDeInitCallback(hsd); #else/* 復位底層硬件 */HAL_SD_MspDeInit(hsd); #endif hsd->ErrorCode = HAL_SD_ERROR_NONE;hsd->State = HAL_SD_STATE_RESET;return HAL_OK; }

    函數描述:

    用于復位SD總線初始化。

    函數參數:

    • ? 第1個參數是SD_HandleTypeDef類型結構體指針變量。
    • ? 返回值,返回HAL_TIMEOUT表示超時,HAL_ERROR表示參數錯誤,HAL_OK表示發送成功,HAL_BUSY表示忙,正在使用中。

    3.4.3????? 函數HAL_SD_ReadBlocks

    函數原型:

    HAL_StatusTypeDef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout) {SDMMC_DataInitTypeDef config;uint32_t errorstate;uint32_t tickstart = HAL_GetTick();uint32_t count, data, dataremaining;uint32_t add = BlockAdd;uint8_t *tempbuff = pData;if(NULL == pData){hsd->ErrorCode |= HAL_SD_ERROR_PARAM;return HAL_ERROR;}if(hsd->State == HAL_SD_STATE_READY){hsd->ErrorCode = HAL_SD_ERROR_NONE;if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)){hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;return HAL_ERROR;}hsd->State = HAL_SD_STATE_BUSY;/* 初始化數據控制寄存器 */hsd->Instance->DCTRL = 0U;if(hsd->SdCard.CardType != CARD_SDHC_SDXC){add *= 512U;}/* 配置SD DPSM (Data Path State Machine) */config.DataTimeOut = SDMMC_DATATIMEOUT;config.DataLength = NumberOfBlocks * BLOCKSIZE;config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;config.DPSM = SDMMC_DPSM_DISABLE;(void)SDMMC_ConfigData(hsd->Instance, &config);__SDMMC_CMDTRANS_ENABLE( hsd->Instance);/* 查詢方式塊讀取 */if(NumberOfBlocks > 1U){hsd->Context = SD_CONTEXT_READ_MULTIPLE_BLOCK;/* 多塊讀取命令 */errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add);}else{hsd->Context = SD_CONTEXT_READ_SINGLE_BLOCK;/* 單塊讀取命令 */errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, add);}if(errorstate != HAL_SD_ERROR_NONE){/* 清除所有靜態標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);hsd->ErrorCode |= errorstate;hsd->State = HAL_SD_STATE_READY;hsd->Context = SD_CONTEXT_NONE;return HAL_ERROR;}/* 查詢SDMMC標志 */dataremaining = config.DataLength;while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)){if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= 32U)){/* 從SDMMC Rx FIFO讀取數據 */for(count = 0U; count < 8U; count++){data = SDMMC_ReadFIFO(hsd->Instance);*tempbuff = (uint8_t)(data & 0xFFU);tempbuff++;*tempbuff = (uint8_t)((data >> 8U) & 0xFFU);tempbuff++;*tempbuff = (uint8_t)((data >> 16U) & 0xFFU);tempbuff++;*tempbuff = (uint8_t)((data >> 24U) & 0xFFU);tempbuff++;}dataremaining -= 32U;}if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U)){/* 清除所有靜態標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);hsd->ErrorCode |= HAL_SD_ERROR_TIMEOUT;hsd->State= HAL_SD_STATE_READY;hsd->Context = SD_CONTEXT_NONE;return HAL_TIMEOUT;}}__SDMMC_CMDTRANS_DISABLE( hsd->Instance);/* 多塊讀取發送停止傳輸命令 */if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U)){if(hsd->SdCard.CardType != CARD_SECURED){/* 發送停止傳輸命令 */errorstate = SDMMC_CmdStopTransfer(hsd->Instance);if(errorstate != HAL_SD_ERROR_NONE){/* 清除所有靜態標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);hsd->ErrorCode |= errorstate;hsd->State = HAL_SD_STATE_READY;hsd->Context = SD_CONTEXT_NONE;return HAL_ERROR;}}}/* 獲取錯誤狀態 */if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)){/* 清除所有靜態標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT;hsd->State = HAL_SD_STATE_READY;hsd->Context = SD_CONTEXT_NONE;return HAL_ERROR;}else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)){/* 清除所有靜態標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL;hsd->State = HAL_SD_STATE_READY;hsd->Context = SD_CONTEXT_NONE;return HAL_ERROR;}else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)){/* 清除所有靜態標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);hsd->ErrorCode |= HAL_SD_ERROR_RX_OVERRUN;hsd->State = HAL_SD_STATE_READY;hsd->Context = SD_CONTEXT_NONE;return HAL_ERROR;}else{/* 什么都不做 */}/* 清除所有靜態標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS);hsd->State = HAL_SD_STATE_READY;return HAL_OK;}else{hsd->ErrorCode |= HAL_SD_ERROR_BUSY;return HAL_ERROR;} }

    函數描述:

    此函數主要用于SD卡數據讀取。

    函數參數:

    • ? 第1個參數是SD_HandleTypeDef類型結構體指針變量。
    • ? 第2個參數是接收數據的緩沖地址。
    • ? 第3個參數是要讀取的扇區地址,即從第幾個扇區開始讀取(512字節為一個扇區)。
    • ? 第4個參數是讀取的扇區數。
    • ? 第5個參數是傳輸過程的溢出時間,單位ms。
    • ? 返回值,返回HAL_TIMEOUT表示超時,HAL_ERROR表示參數錯誤,HAL_OK表示發送成功,HAL_BUSY表示忙,正在使用中。

    使用舉例:

    /*** @brief Reads block(s) from a specified address in an SD card, in polling mode.* @param pData: Pointer to the buffer that will contain the data to transmit* @param ReadAddr: Address from where data is to be read* @param NumOfBlocks: Number of SD blocks to read* @param Timeout: Timeout for read operation* @retval SD status*/ uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout) {if( HAL_SD_ReadBlocks(&uSdHandle, (uint8_t *)pData, ReadAddr, NumOfBlocks, Timeout) == HAL_OK){return MSD_OK;}else{return MSD_ERROR;}}

    3.4.4????? 函數HAL_SD_WriteBlocks

    函數原型:

    HAL_StatusTypeDef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout) {SDMMC_DataInitTypeDef config;uint32_t errorstate;uint32_t tickstart = HAL_GetTick();uint32_t count, data, dataremaining;uint32_t add = BlockAdd;uint8_t *tempbuff = pData;if(NULL == pData){hsd->ErrorCode |= HAL_SD_ERROR_PARAM;return HAL_ERROR;}if(hsd->State == HAL_SD_STATE_READY){hsd->ErrorCode = HAL_SD_ERROR_NONE;if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)){hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;return HAL_ERROR;}hsd->State = HAL_SD_STATE_BUSY;/* 初始化數據控制寄存器 */hsd->Instance->DCTRL = 0U;if(hsd->SdCard.CardType != CARD_SDHC_SDXC){add *= 512U;}/* 配置SD DPSM */config.DataTimeOut = SDMMC_DATATIMEOUT;config.DataLength = NumberOfBlocks * BLOCKSIZE;config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;config.DPSM = SDMMC_DPSM_DISABLE;(void)SDMMC_ConfigData(hsd->Instance, &config);__SDMMC_CMDTRANS_ENABLE( hsd->Instance);/* 查詢方式塊寫操作 */if(NumberOfBlocks > 1U){hsd->Context = SD_CONTEXT_WRITE_MULTIPLE_BLOCK;/* 寫多塊命令 */errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add);}else{hsd->Context = SD_CONTEXT_WRITE_SINGLE_BLOCK;/* 寫單塊命令 */errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, add);}if(errorstate != HAL_SD_ERROR_NONE){/* 清除所有靜態命令 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);hsd->ErrorCode |= errorstate;hsd->State = HAL_SD_STATE_READY;hsd->Context = SD_CONTEXT_NONE;return HAL_ERROR;}/* 查詢方式塊寫操作 */dataremaining = config.DataLength;while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)){if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= 32U)){/* 寫數據到SDMMC Tx FIFO */for(count = 0U; count < 8U; count++){data = (uint32_t)(*tempbuff);tempbuff++;data |= ((uint32_t)(*tempbuff) << 8U);tempbuff++;data |= ((uint32_t)(*tempbuff) << 16U);tempbuff++;data |= ((uint32_t)(*tempbuff) << 24U);tempbuff++;(void)SDMMC_WriteFIFO(hsd->Instance, &data);}dataremaining -= 32U;}if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U)){/* 清除所有靜態標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);hsd->ErrorCode |= errorstate;hsd->State = HAL_SD_STATE_READY;hsd->Context = SD_CONTEXT_NONE;return HAL_TIMEOUT;}}__SDMMC_CMDTRANS_DISABLE( hsd->Instance);/* 多塊寫操作,發送停止傳輸命令 */if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U)){if(hsd->SdCard.CardType != CARD_SECURED){/* 發送停止傳輸命令 */errorstate = SDMMC_CmdStopTransfer(hsd->Instance);if(errorstate != HAL_SD_ERROR_NONE){/* 清除所有靜態傳輸標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);hsd->ErrorCode |= errorstate;hsd->State = HAL_SD_STATE_READY;hsd->Context = SD_CONTEXT_NONE;return HAL_ERROR;}}}/* Get error state */if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)){/* 清除所有靜態傳輸標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT;hsd->State = HAL_SD_STATE_READY;hsd->Context = SD_CONTEXT_NONE;return HAL_ERROR;}else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)){/* 清除所有靜態傳輸標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL;hsd->State = HAL_SD_STATE_READY;hsd->Context = SD_CONTEXT_NONE;return HAL_ERROR;}else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXUNDERR)){/* 清除所有靜態傳輸標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);hsd->ErrorCode |= HAL_SD_ERROR_TX_UNDERRUN;hsd->State = HAL_SD_STATE_READY;hsd->Context = SD_CONTEXT_NONE;return HAL_ERROR;}else{/* 什么都不做 */}/* 清除所有靜態傳輸標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS);hsd->State = HAL_SD_STATE_READY;return HAL_OK;}else{hsd->ErrorCode |= HAL_SD_ERROR_BUSY;return HAL_ERROR;} }

    函數描述:

    此函數主要用于向SD卡寫入數據。

    函數參數:

    • ? 第1個參數是SD_HandleTypeDef類型結構體指針變量。
    • ? 第2個參數是要寫入到SD卡的數據緩沖地址。
    • ? 第3個參數是要寫入的扇區地址,即從第幾個扇區開始寫入(512字節為一個扇區)。
    • ? 第4個參數是讀取的扇區數。
    • ? 第5個參數是傳輸過程的溢出時間,單位ms。
    • ? 返回值,返回HAL_TIMEOUT表示超時,HAL_ERROR表示參數錯誤,HAL_OK表示發送成功,HAL_BUSY表示忙,正在使用中。

    使用舉例:

    /*** @brief Writes block(s) to a specified address in an SD card, in polling mode.* @param pData: Pointer to the buffer that will contain the data to transmit* @param WriteAddr: Address from where data is to be written* @param NumOfBlocks: Number of SD blocks to write* @param Timeout: Timeout for write operation* @retval SD status*/ uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout) {if( HAL_SD_WriteBlocks(&uSdHandle, (uint8_t *)pData, WriteAddr, NumOfBlocks, Timeout) == HAL_OK){return MSD_OK;}else{return MSD_ERROR;} }

    3.4.5????? 函數HAL_SD_ReadBlocks_DMA

    函數原型:

    HAL_StatusTypeDef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) {SDMMC_DataInitTypeDef config;uint32_t errorstate;uint32_t add = BlockAdd;if(NULL == pData){hsd->ErrorCode |= HAL_SD_ERROR_PARAM;return HAL_ERROR;}if(hsd->State == HAL_SD_STATE_READY){hsd->ErrorCode = HAL_SD_ERROR_NONE;if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)){hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;return HAL_ERROR;}hsd->State = HAL_SD_STATE_BUSY;/* 初始化數據控制寄存器 */hsd->Instance->DCTRL = 0U;hsd->pRxBuffPtr = pData;hsd->RxXferSize = BLOCKSIZE * NumberOfBlocks;if(hsd->SdCard.CardType != CARD_SDHC_SDXC){add *= 512U;}/* 配置SD DPSM (Data Path State Machine) */config.DataTimeOut = SDMMC_DATATIMEOUT;config.DataLength = BLOCKSIZE * NumberOfBlocks;config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;config.DPSM = SDMMC_DPSM_DISABLE;(void)SDMMC_ConfigData(hsd->Instance, &config);__SDMMC_CMDTRANS_ENABLE( hsd->Instance);hsd->Instance->IDMABASE0 = (uint32_t) pData ;hsd->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF;/* DMA方式讀取多個塊 */if(NumberOfBlocks > 1U){hsd->Context = (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_DMA);/* DMA方式讀取多塊命令 */errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add);}else{hsd->Context = (SD_CONTEXT_READ_SINGLE_BLOCK | SD_CONTEXT_DMA);/* 讀取單塊命令 */errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, add);}if(errorstate != HAL_SD_ERROR_NONE){/* 清除所有靜態標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);hsd->ErrorCode |= errorstate;hsd->State = HAL_SD_STATE_READY;hsd->Context = SD_CONTEXT_NONE;return HAL_ERROR;}/* 使能傳輸中斷 */__HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND));return HAL_OK;}else{return HAL_BUSY;} }

    函數描述:

    此函數主要用于SD卡數據讀取,DMA方式。

    函數參數:

    • ? 第1個參數是SD_HandleTypeDef類型結構體指針變量。
    • ? 第2個參數是接收數據的緩沖地址。
    • ? 第3個參數是要讀取的扇區地址,即從第幾個扇區開始讀取(512字節為一個扇區)。
    • ? 第4個參數是讀取的扇區數。
    • ? 返回值,返回HAL_TIMEOUT表示超時,HAL_ERROR表示參數錯誤,HAL_OK表示發送成功,HAL_BUSY表示忙,正在使用中。

    使用舉例:

    /** * @brief Reads block(s) from a specified address in an SD card, in DMA mode. * @param pData: Pointer to the buffer that will contain the data to transmit * @param ReadAddr: Address from where data is to be read * @param NumOfBlocks: Number of SD blocks to read * @retval SD status */ uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks) {if( HAL_SD_ReadBlocks_DMA(&uSdHandle, (uint8_t *)pData, ReadAddr, NumOfBlocks) == HAL_OK){return MSD_OK;}else{return MSD_ERROR;} }

    3.4.6????? 函數HAL_SD_WriteBlocks_DMA

    函數原型:

    HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) {SDMMC_DataInitTypeDef config;uint32_t errorstate;uint32_t add = BlockAdd;if(NULL == pData){hsd->ErrorCode |= HAL_SD_ERROR_PARAM;return HAL_ERROR;}if(hsd->State == HAL_SD_STATE_READY){hsd->ErrorCode = HAL_SD_ERROR_NONE;if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)){hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;return HAL_ERROR;}hsd->State = HAL_SD_STATE_BUSY;/* 初始化數據控制寄存器 */hsd->Instance->DCTRL = 0U;hsd->pTxBuffPtr = pData;hsd->TxXferSize = BLOCKSIZE * NumberOfBlocks;if(hsd->SdCard.CardType != CARD_SDHC_SDXC){add *= 512U;}/* 配置SD DPSM (Data Path State Machine) */config.DataTimeOut = SDMMC_DATATIMEOUT;config.DataLength = BLOCKSIZE * NumberOfBlocks;config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;config.DPSM = SDMMC_DPSM_DISABLE;(void)SDMMC_ConfigData(hsd->Instance, &config);__SDMMC_CMDTRANS_ENABLE( hsd->Instance);hsd->Instance->IDMABASE0 = (uint32_t) pData ;hsd->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF;/* 查詢模式寫塊 */if(NumberOfBlocks > 1U){hsd->Context = (SD_CONTEXT_WRITE_MULTIPLE_BLOCK | SD_CONTEXT_DMA);/* 多塊寫命令 */errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add);}else{hsd->Context = (SD_CONTEXT_WRITE_SINGLE_BLOCK | SD_CONTEXT_DMA);/* 單塊寫命令 */errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, add);}if(errorstate != HAL_SD_ERROR_NONE){/* 清除靜態標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);hsd->ErrorCode |= errorstate;hsd->State = HAL_SD_STATE_READY;hsd->Context = SD_CONTEXT_NONE;return HAL_ERROR;}/* 使能傳輸中斷 Enable */__HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND));return HAL_OK;}else{return HAL_BUSY;} }

    函數描述:

    此函數主要用于向SD卡寫入數據,DMA方式。

    函數參數:

    • ? 第1個參數是SD_HandleTypeDef類型結構體指針變量。
    • ? 第2個參數是要寫入到SD卡的數據緩沖地址。
    • ? 第3個參數是要寫入的扇區地址,即從第幾個扇區開始寫入(512字節為一個扇區)。
    • ? 第4個參數是讀取的扇區數。
    • ? 返回值,返回HAL_TIMEOUT表示超時,HAL_ERROR表示參數錯誤,HAL_OK表示發送成功,HAL_BUSY表示忙,正在使用中。

    使用舉例:

    /** * @brief Writes block(s) to a specified address in an SD card, in DMA mode. * @param pData: Pointer to the buffer that will contain the data to transmit * @param WriteAddr: Address from where data is to be written * @param NumOfBlocks: Number of SD blocks to write * @retval SD status */ uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks) {if( HAL_SD_WriteBlocks_DMA(&uSdHandle, (uint8_t *)pData, WriteAddr, NumOfBlocks) == HAL_OK){return MSD_OK;}else{return MSD_ERROR;} }

    3.4.7????? 函數HAL_SD_Erase

    函數原型:

    HAL_StatusTypeDef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint32_t BlockStartAdd, uint32_t BlockEndAdd) {uint32_t errorstate;uint32_t start_add = BlockStartAdd;uint32_t end_add = BlockEndAdd;if(hsd->State == HAL_SD_STATE_READY){hsd->ErrorCode = HAL_SD_ERROR_NONE;if(end_add < start_add){hsd->ErrorCode |= HAL_SD_ERROR_PARAM;return HAL_ERROR;}if(end_add > (hsd->SdCard.LogBlockNbr)){hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;return HAL_ERROR;}hsd->State = HAL_SD_STATE_BUSY;/* 檢測是否支持擦除命令 */if(((hsd->SdCard.Class) & SDMMC_CCCC_ERASE) == 0U){/* 清除所有靜態標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);hsd->ErrorCode |= HAL_SD_ERROR_REQUEST_NOT_APPLICABLE;hsd->State = HAL_SD_STATE_READY;return HAL_ERROR;}if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED){/* 清除所有靜態標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);hsd->ErrorCode |= HAL_SD_ERROR_LOCK_UNLOCK_FAILED;hsd->State = HAL_SD_STATE_READY;return HAL_ERROR;}/* 對于高容量卡,獲取起始塊和結束塊 */if(hsd->SdCard.CardType != CARD_SDHC_SDXC){start_add *= 512U;end_add *= 512U;}/* 根據sd-card spec 1.0 ERASE_GROUP_START (CMD32) 和 erase_group_end(CMD33) */if(hsd->SdCard.CardType != CARD_SECURED){/* 發送CMD32 SD_ERASE_GRP_START命令帶地址參數 */errorstate = SDMMC_CmdSDEraseStartAdd(hsd->Instance, start_add);if(errorstate != HAL_SD_ERROR_NONE){/* 清除所有靜態標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);hsd->ErrorCode |= errorstate;hsd->State = HAL_SD_STATE_READY;return HAL_ERROR;}/* 發送CMD33 SD_ERASE_GRP_END命令,帶地址參數 */errorstate = SDMMC_CmdSDEraseEndAdd(hsd->Instance, end_add);if(errorstate != HAL_SD_ERROR_NONE){/* 清除所有靜態標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);hsd->ErrorCode |= errorstate;hsd->State = HAL_SD_STATE_READY;return HAL_ERROR;}}/* 發送CMD38 ERASE命令 */errorstate = SDMMC_CmdErase(hsd->Instance, 0UL);if(errorstate != HAL_SD_ERROR_NONE){/* 清除所有靜態標志 */__HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS);hsd->ErrorCode |= errorstate;hsd->State = HAL_SD_STATE_READY;return HAL_ERROR;}hsd->State = HAL_SD_STATE_READY;return HAL_OK;}else{return HAL_BUSY;} }

    函數描述:

    此函數主要用于SD卡擦除。

    函數參數:

    • ? 第1個參數是SD_HandleTypeDef類型結構體指針變量。
    • ? 第2個參數是擦除的起始扇區地址,地址單位是第幾個扇區(512字節為一個扇區)。
    • ? 第3個參數是擦除的結束扇區地址,地址單位是第幾個扇區(512字節為一個扇區)。
    • ? 返回值,返回HAL_TIMEOUT表示超時,HAL_ERROR表示參數錯誤,HAL_OK表示發送成功,HAL_BUSY表示忙,正在使用中。

    使用舉例:

    /** * @brief Erases the specified memory area of the given SD card. * @param StartAddr: Start byte address * @param EndAddr: End byte address * @retval SD status */ uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr) {if( HAL_SD_Erase(&uSdHandle, StartAddr, EndAddr) == HAL_OK){return MSD_OK;}else{return MSD_ERROR;} }

    3.5?? 總結

    本章節就為大家講解這么多,更多SDMMC知識可以看STM32H7的參考手冊。

    ?

    總結

    以上是生活随笔為你收集整理的【STM32H7】第3章 ThreadX FileX移植SDIO接口SD的基础知识的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    免费精品视频 | 国产亚洲激情视频在线 | 国产精品第一视频 | 91高清视频免费 | 97超级碰碰碰碰久久久久 | 色视频网址 | 日韩欧美在线观看 | 午夜 久久 tv | 国产精品成人久久久久久久 | 91网免费看 | 日韩大片在线播放 | 久久首页 | 久久久久欠精品国产毛片国产毛生 | 久久久久免费精品国产小说色大师 | 国产精品色视频 | 日本黄色a级大片 | 亚洲成人午夜av | 亚洲春色综合另类校园电影 | 免费看wwwwwwwwwww的视频 久久久久久99精品 91中文字幕视频 | 久久亚洲私人国产精品va | 亚洲综合欧美激情 | 免费在线成人av电影 | 亚洲永久精品在线 | av一级免费 | 亚洲乱码久久久 | 91爱爱电影| 久久国产精品久久精品国产演员表 | 亚洲国产精品500在线观看 | 亚洲妇女av | 成人动漫一区二区三区 | 国产一区播放 | av成人亚洲| 婷婷丁香狠狠爱 | 国产精品免费久久久久久久久久中文 | 天天草天天插 | 黄色av三级在线 | 亚洲人在线7777777精品 | av在线免费观看不卡 | 九九久久久 | 国产精品视频观看 | 日韩欧美网址 | 国产成人免费在线 | 97精品国产97久久久久久 | 久久国产精品影片 | 久久视了| 亚洲国产中文在线观看 | 日本动漫做毛片一区二区 | 中文字幕大全 | 一区 二区 精品 | 娇妻呻吟一区二区三区 | 一级国产视频 | 亚洲国产一区av | 99精品黄色片免费大全 | av大片网址 | 四虎4hu永久免费 | 国产不卡视频在线播放 | 国产精品日韩在线观看 | 国产91九色蝌蚪 | 中文字幕你懂的 | 日本中文字幕在线播放 | 中文字幕888| 亚洲欧洲精品在线 | 日韩一区二区三区高清免费看看 | 日日夜夜精品免费视频 | 日韩网站免费观看 | 久久久久日本精品一区二区三区 | 久久精品影片 | 三级大片网站 | 久草在线免费资源站 | 黄色小网站在线观看 | 黄色大片免费网站 | 亚洲午夜精品久久久 | 国产精品一区二区三区电影 | a视频在线看 | 在线国产欧美 | 国产va饥渴难耐女保洁员在线观看 | 一区二区av| 欧美精品v国产精品v日韩精品 | 日韩在线免费高清视频 | 国产特黄色片 | 国产精品久久伊人 | 精品国产黄色片 | 玖玖玖影院 | 国产黄色免费观看 | 在线观看www视频 | 亚洲国产精品999 | 91久久在线观看 | 亚洲永久字幕 | 日韩在线观看视频免费 | 免费a v在线 | 欧美成人性网 | 久久人人爽人人爽 | 国产免费一区二区三区最新 | 成人国产精品久久久春色 | 日韩精品极品视频 | 国产在线观看你懂的 | 日韩精品视频免费在线观看 | 亚洲最新av在线网站 | 午夜免费电影院 | 久久免费一 | 久草免费新视频 | 91亚洲国产 | 久久高清av | 亚洲欧美日本国产 | 国产一区视频免费在线观看 | 在线免费三级 | 亚洲视频,欧洲视频 | 狠狠夜夜 | 亚洲黄色免费观看 | 香蕉影视在线观看 | 天天射天天干天天操 | 韩国av一区二区三区 | 日韩一区二区三区高清在线观看 | 国产视频2021| 最新影院 | 热re99久久精品国产66热 | 99久e精品热线免费 99国产精品久久久久久久久久 | 日韩在线观看你懂得 | 天堂av中文字幕 | 2023年中文无字幕文字 | 在线观看日韩国产 | 欧美在线观看视频 | 碰超在线97人人 | 欧美成人亚洲 | 日韩电影中文,亚洲精品乱码 | 精品亚洲成人 | 麻豆传媒精品 | 色婷婷激情四射 | 中文字幕亚洲综合久久五月天色无吗'' | 五月婷网站| 国产91精品欧美 | 国产在线观看中文字幕 | 国产精品久久久久四虎 | 在线观看一 | 免费a网站 | 日韩91精品 | 久久久免费精品国产一区二区 | 嫩草伊人久久精品少妇av | 成人精品视频久久久久 | 天天草天天干天天射 | 国产在线a视频 | 欧美精品久久久久性色 | 在线中文字幕一区二区 | 97视频免费播放 | 婷婷在线精品视频 | 久草免费在线观看视频 | 日韩av二区 | 国产精品久久久久久久午夜 | 亚洲一级黄色片 | 视频在线观看日韩 | 天天摸夜夜添 | 久久国产成人午夜av影院宅 | 国产麻豆精品一区 | 日韩欧美网址 | 福利网址在线观看 | 国产精品人人做人人爽人人添 | 国产亚洲精品久久19p | 伊人黄| 国产精品久久久久三级 | 九九影视理伦片 | 久久国产香蕉视频 | 成人久久毛片 | 国产一级片直播 | 91精品对白一区国产伦 | 91亚洲在线观看 | 日韩理论电影在线观看 | 天天摸夜夜操 | 欧美激情综合五月 | av电影av在线 | 日韩亚洲国产中文字幕 | 亚洲成a人片综合在线 | 欧美日本高清视频 | 欧美激情精品久久久久久免费印度 | 国产视频精品久久 | 久久激情久久 | 少妇资源站| 人人草天天草 | 欧美日韩精品在线播放 | 久久精品国亚洲 | 色婷婷综合久久久久中文字幕1 | 综合影视 | 在线观看v片 | va视频在线观看 | 成人免费在线观看电影 | 公与妇乱理三级xxx 在线观看视频在线观看 | 国产黄大片 | 亚洲最快最全在线视频 | 99精品视频在线观看免费 | 日操操| 91一区二区在线 | 在线高清av| 久久夜色精品国产欧美一区麻豆 | 日韩在线免费看 | 欧美在线18 | 亚洲精品成人免费 | 亚洲成人软件 | 超碰在线人人97 | 成人av电影免费观看 | 国产成人久久av977小说 | 夜夜骑天天操 | 爱爱av在线 | 久久久久久久久久久久久久免费看 | 日本久久视频 | 激情图片久久 | 婷婷激情综合五月天 | 婷婷日日 | 在线综合 亚洲 欧美在线视频 | av在线网站大全 | 麻豆免费在线播放 | 久久久久久久久久国产精品 | 久久美女高清视频 | 久久另类小说 | 久久精品一区八戒影视 | 91大神视频网站 | 日韩欧美专区 | 欧美va天堂va视频va在线 | 丝袜av一区| 99re在线视频观看 | 黄色软件视频大全免费下载 | av福利在线看| 狠狠干狠狠久久 | 久久久国产一区二区 | 午夜丁香网 | 日韩高清无线码2023 | 国产a国产 | 久久久伊人网 | 国产精品网址在线观看 | 欧美日韩一区二区三区免费视频 | 最近日本中文字幕 | 久久成人国产精品 | 欧美国产日韩在线视频 | 中文字幕字幕中文 | 激情视频一区二区三区 | 久久国产一区二区 | 日韩剧情| 成年美女黄网站色大片免费看 | 色99在线| 精品视频 | 九色视频网站 | 中文字幕二区三区 | www黄色| 四虎www. | 婷婷中文字幕综合 | 在线韩国电影免费观影完整版 | 欧美一二三区在线播放 | 日韩在线高清免费视频 | 精品国产人成亚洲区 | 日韩免费一区二区 | 国产在线成人 | 久久一级片| 在线播放 日韩专区 | 99久e精品热线免费 99国产精品久久久久久久久久 | 色婷婷av在线 | 蜜桃传媒一区二区 | 99热这里有 | 91福利专区 | 深夜免费福利网站 | 久久久久久免费 | www.夜色.com | 免费视频 三区 | 五月天九九 | 久草在线手机视频 | 中文字幕在线观看视频免费 | 色偷偷97| 亚洲欧美日韩中文在线 | 西西4444www大胆无视频 | 久久九九影视 | 亚洲国产精品免费 | 美女视频网站久久 | 国产美女无遮挡永久免费 | 成人在线视频一区 | 久久久免费国产 | 一区二区三区不卡在线 | 国产 日韩 欧美 自拍 | 成 人 黄 色视频免费播放 | 久久电影国产免费久久电影 | 国产精品女同一区二区三区久久夜 | 91在线观看视频网站 | 国产精品一区二区av麻豆 | 国产精品一区二区电影 | 在线免费黄色av | 亚洲高清免费在线 | 久久视频网 | 91视频观看免费 | 97超级碰| 狠狠色丁香九九婷婷综合五月 | 国内免费久久久久久久久久久 | 91黄色影视 | 国产精品久久中文字幕 | 欧美性护士 | 亚洲一区日韩在线 | 久久99在线观看 | 国产老熟 | 午夜电影 电影 | 国产网站色| 久久久久免费网 | 在线视频日韩一区 | 国产 一区二区三区 在线 | 激情大尺度视频 | 日韩精品中文字幕在线 | 久久精品一二三区白丝高潮 | 亚洲无线视频 | 日韩中文字幕亚洲一区二区va在线 | 在线成人免费电影 | 国产91免费看 | 亚洲成人精品久久久 | 911国产在线观看 | 国产资源在线观看 | 亚洲不卡123 | 日韩v在线 | 西西444www | 69国产在线观看 | 精品国产一区二区三区久久久 | 国产精品永久免费 | 91av视屏| 久久欧美视频 | 成片免费观看视频999 | 国产色妞影院wwwxxx | 国产高清视频在线免费观看 | 日韩理论在线视频 | 91成品视频 | 中文字幕 国产专区 | 成人免费中文字幕 | 国产精品一区二区精品视频免费看 | 美女黄色网在线播放 | 超碰人人干人人 | 在线观看中文字幕视频 | 99久久精品一区二区成人 | 久久人人爽爽人人爽人人片av | 天天色天天爱天天射综合 | 亚洲成av人片在线观看无 | 99视频99| 国产精品一区在线播放 | 欧美片一区二区三区 | 国产网红在线观看 | 国产无限资源在线观看 | 欧美日韩在线播放 | 日日噜噜噜噜夜夜爽亚洲精品 | 四虎视频 | 国产精品一区二区免费看 | 日韩精品一区二区三区不卡 | 国内少妇自拍视频一区 | 久久伊99综合婷婷久久伊 | 黄色三级免费 | 在线高清一区 | 色综合色综合色综合 | 99视频精品全国免费 | 91精选 | 99久久国产免费,99久久国产免费大片 | 免费污片 | 婷婷精品国产欧美精品亚洲人人爽 | 日韩高清一二三区 | 超碰在线观看av.com | 精品国产一区二区三区四区在线观看 | av片中文 | 色偷偷88欧美精品久久久 | www.xxx.性狂虐 | 欧美日韩在线视频一区 | 99免费在线视频观看 | 黄色成品视频 | 麻豆国产电影 | 五月综合久久 | 国产美女无遮挡永久免费 | 97精品国产97久久久久久久久久久久 | 日韩一区二区三区免费视频 | 99在线观看免费视频精品观看 | 亚洲一级电影视频 | 国产黄色片在线 | 一区二区中文字幕在线观看 | 欧美日韩一区二区三区免费视频 | 国产精品24小时在线观看 | 国产视频精品久久 | 国内精品视频久久 | 亚洲a资源 | 日韩在线中文字幕视频 | 中文字幕乱码在线播放 | 久久综合色天天久久综合图片 | www五月 | 色婷婷骚婷婷 | 日韩免费一区 | 中文字幕中文字幕中文字幕 | 精品久久久久久亚洲综合网 | 一区二区激情视频 | 97天堂 | 久草在线视频在线 | 在线观看片 | 黄色视屏在线免费观看 | 麻豆传媒电影在线观看 | 91干干干 | 亚洲污视频 | 亚洲人成在线电影 | 99精品视频免费看 | 超碰电影在线观看 | 日韩国产精品一区 | 97超碰资源 | 综合黄色网 | 成人性生爱a∨ | 韩日av在线 | 欧美精品在线免费 | 亚洲美女视频网 | 亚洲三级网站 | 最新av网址在线观看 | 国产人在线成免费视频 | 视频在线观看国产 | 成人午夜免费剧场 | 91日韩在线 | 97超碰国产精品女人人人爽 | 中文字幕在线播放一区 | 国产另类av | 国内精品久久久久影院优 | 99国产精品久久久久老师 | 国产69精品久久久久久 | 国产一区欧美一区 | 成人国产精品久久久 | 97超碰资源网 | 99视频在线观看视频 | 日本一区二区三区免费观看 | 国产午夜av | 2023天天干 | 国产精品第一 | 国产丝袜高跟 | 黄色一级在线视频 | 91亚色视频在线观看 | 日韩av一区二区在线影视 | 国产视频一区二区在线播放 | 亚洲成人第一区 | 国外av在线 | 亚洲 综合 激情 | 中文字幕中文字幕中文字幕 | 一区二区三区免费在线 | 欧美最新另类人妖 | 五月天激情综合 | 五月天六月婷 | 亚洲h视频在线 | 999成人网 | 波多野结衣视频网址 | 在线观看黄a | 国产精品久久久久久久久久东京 | 中文字幕久久网 | 国产中文字幕视频在线观看 | 国产成人精品一区二区在线 | 日韩在线视频在线观看 | www.色午夜,com | 久久综合狠狠综合久久狠狠色综合 | 国产精品99久久久久久久久 | 在线免费看黄色 | 五月天最新网址 | 日韩一区二区免费在线观看 | 一区二区三区高清在线 | 久久成人精品电影 | 欧美日韩调教 | 国产精品xxxx18a99| 丁香六月综合网 | 久久精品牌麻豆国产大山 | 日韩精品专区在线影院重磅 | 99这里有精品 | 日韩在线三级 | 国产一级免费观看视频 | 免费视频久久久久 | 国产精品资源 | 成人久久网| 亚洲国产精品传媒在线观看 | 国产一级片观看 | 国产亚洲久久 | 色婷婷丁香 | 国产午夜影院 | 久久亚洲精品国产亚洲老地址 | www.色午夜.com | 午夜av在线电影 | 国产玖玖在线 | 亚洲伦理中文字幕 | 久久久久久国产精品亚洲78 | 在线亚洲天堂网 | 一级黄色片在线播放 | 麻豆视频观看 | 日本中文字幕网址 | 亚洲国产人午在线一二区 | 国产999在线观看 | 永久免费的啪啪网站免费观看浪潮 | 99久久婷婷国产 | 男女免费av | 亚洲精品91天天久久人人 | 日韩一级片大全 | 国内精品久久久久影院优 | 99热99热| 国产精品一区二区吃奶在线观看 | 99精品欧美一区二区蜜桃免费 | 中文字幕文字幕一区二区 | 91大神精品视频 | 免费男女羞羞的视频网站中文字幕 | 三级黄色在线 | 欧美视频日韩视频 | 在线观看亚洲免费视频 | 999ZYZ玖玖资源站永久 | av播放在线 | 视频在线观看亚洲 | 国产精品毛片久久久久久 | 精品欧美一区二区在线观看 | 亚洲激情在线观看 | 91香蕉视频在线 | 国产精品一区二区白浆 | 久久精品中文 | 日韩va在线观看 | 在线看v片 | 精品国产一区二区三区在线观看 | 狠狠躁日日躁狂躁夜夜躁av | 国产精品一区二区在线播放 | 亚洲精选在线观看 | 在线视频 影院 | 91av在线看 | 91成人破解版 | 久久1电影院 | 2019精品手机国产品在线 | 国产xxxxx在线观看 | 碰天天操天天 | 黄色在线观看污 | 国产一区二区精 | 少妇精品久久久一区二区免费 | 国产高清中文字幕 | 中文av网| 国产电影一区二区三区四区 | 国产99久久久久 | 久久99久久精品 | 91精品国| 91九色蝌蚪视频在线 | 天天射,天天干 | 91自拍视频在线观看 | 国产啊v在线观看 | 一级片视频在线 | 干狠狠 | 在线观看日韩精品 | 午夜狠狠干 | 亚洲精品乱码久久久久v最新版 | 久久人人爽人人爽 | 久久久久久看片 | 91自拍成人 | 激情婷婷六月 | 久久五月精品 | 亚洲成人国产 | 亚洲va欧美va国产va黑人 | 亚洲狠狠干 | 探花视频免费观看 | 中文字幕亚洲综合久久五月天色无吗'' | 人人爽人人看 | 五月天视频网 | 成人性生交大片免费看中文网站 | 97精品国产aⅴ | 97成人啪啪网 | 国产黄色大片免费看 | www.狠狠色.com| 欧美人人 | 天天躁天天狠天天透 | 视频国产在线 | 人人舔人人爽 | 在线观看av免费 | 日韩欧美综合精品 | 欧美 日韩 性 | 97国产在线观看 | 国产精品久久艹 | 国产精品美女在线 | 91看片在线播放 | 国色天香第二季 | 欧美 日韩 国产 中文字幕 | 国产精品成人久久久 | 国产精品免费观看在线 | 丝袜美女视频网站 | 精品在线观看一区二区三区 | 2019中文字幕第一页 | 91麻豆精品国产91久久久使用方法 | 五月亚洲 | 久久黄色免费视频 | 91大神精品视频在线观看 | 一级做a视频 | av成人在线电影 | 五月激情在线 | www黄色| 成 人 黄 色 视频播放1 | 日韩欧美有码在线 | 亚洲资源在线观看 | 日韩一级成人av | 99久久久久国产精品免费 | www.久热| 人人草人人草 | 国产一区二区在线播放视频 | 国产成人99av超碰超爽 | 成人免费观看av | 丁香花中文字幕 | 久久综合婷婷国产二区高清 | 国产成人精品三级 | 国产高清中文字幕 | 日日夜夜狠狠操 | 中文字幕亚洲综合久久五月天色无吗'' | 黄色中文字幕在线 | 久久精品久久精品久久 | 美女在线观看网站 | 91人人揉日日捏人人看 | 久久久久久美女 | 黄色av观看 | 日韩精品一区二区电影 | 日产乱码一二三区别在线 | 人人澡人人爽 | 中文字幕在线网 | 国内精品久久久久久久久久 | 一区二区三区四区五区在线视频 | 911在线 | 色久五月| 亚洲午夜小视频 | 四虎影视精品永久在线观看 | 日韩精品黄| 亚洲成人黄色 | 久久精品人人做人人综合老师 | 国产精品九九九九九九 | 久久免费黄色网址 | 国产一区二区高清视频 | 亚洲精品玖玖玖av在线看 | 色诱亚洲精品久久久久久 | 天天夜夜操 | 欧美最猛性xxxxx亚洲精品 | 国产精品久久久久久久久久久久午夜 | 亚洲专区视频在线观看 | www.狠狠插.com| 91在线播放国产 | 日韩丝袜 | 中文字幕第一页在线播放 | www.国产精品 | 在线亚洲观看 | 亚洲激情婷婷 | 天天视频色版 | 欧美va天堂va视频va在线 | 亚洲精品456在线播放 | 成人国产精品av | 成人黄色在线播放 | 成人免费在线播放 | 91久久偷偷做嫩草影院 | 黄色大片日本 | 少妇bbw搡bbbb搡bbb | www.神马久久 | 久久国产精品免费视频 | 91麻豆精品久久久久久 | 国产精品免费在线播放 | 啪啪资源 | 国产免费观看视频 | 手机看片国产 | 激情丁香月| 伊人五月综合 | 日韩免费小视频 | www.黄色片网站 | 日韩av资源在线观看 | 亚洲电影网站 | 国产va精品免费观看 | 中文字幕亚洲综合久久五月天色无吗'' | 手机av看片 | 成人av在线电影 | 欧美日韩国产一区二区三区 | 九九热在线观看 | 片黄色毛片黄色毛片 | 国产日韩欧美在线 | 久久99网| 久久国产精品精品国产色婷婷 | www.久久久久 | 国产精品久久久久av免费 | 久久久影院一区二区三区 | 亚洲成人av片| 久草av在线播放 | 西西www4444大胆视频 | 狠狠操夜夜操 | 日韩av中文| 五月综合色 | 中文字幕在线高清 | 九九在线免费视频 | 色婷婷狠狠五月综合天色拍 | 日韩av一区二区在线影视 | 欧美大片大全 | 久久久高清免费视频 | 天天操天天干天天 | 亚洲国产精品一区二区久久hs | 久久婷婷综合激情 | 午夜电影一区 | 国产 日韩 欧美 在线 | www久久99 | 99精品成人| 人人爱爱人人 | 2019中文字幕网站 | 综合网在线视频 | 激情深爱五月 | 亚洲精品在线看 | 国产精品久久久久久久久久久久午 | 深爱激情五月婷婷 | 99人成在线观看视频 | 中文字幕观看av | 欧美精品在线观看免费 | 国产亚洲精品女人久久久久久 | 成人在线视频一区 | 毛片在线播放网址 | 黄色大片av | 免费成人在线网站 | 国产看片网站 | 欧美热久久 | 午夜天使| 欧美日韩一区三区 | 人人爽人人香蕉 | 66av99精品福利视频在线 | 激情综合色综合久久综合 | 国产第一二区 | 国产精品久久精品 | 亚洲成人一二三 | 国产偷在线 | av成人免费在线 | 国产成人在线免费观看 | 国内成人精品视频 | 成人黄色小说视频 | 一级黄色电影网站 | 免费视频xnxx com | 国产精品高清免费在线观看 | 日韩在线观看网址 | 国产精品永久免费观看 | 午夜一级免费电影 | 久久综合狠狠狠色97 | 久久精品美女 | 伊人激情综合 | 人人干在线观看 | 一区二区在线影院 | 麻豆免费看片 | 中文字幕亚洲精品日韩 | 99热 精品在线 | 国产无套精品久久久久久 | 狠狠狠色丁香婷婷综合久久五月 | 操操日| 日韩在线观看视频网站 | 精品欧美一区二区精品久久 | 亚洲开心激情 | 欧美日在线观看 | 人人视频网站 | 日日干天天干 | 999久久久国产精品 高清av免费观看 | av黄色免费看 | 91精品久久久久久 | 国产在线精品福利 | 欧美美女视频在线观看 | 精品国产中文字幕 | 亚洲欧美在线综合 | www.色午夜 | 亚洲婷婷综合色高清在线 | 免费看的黄色录像 | 97天天综合网 | 欧洲av不卡 | 一级淫片a| 岛国av在线不卡 | 日日爱av | 中文字幕在线免费看线人 | 日本久久久久久科技有限公司 | 在线观看亚洲a | 久久96国产精品久久99软件 | 国产精品久久网 | 色天堂在线视频 | 国产中文字幕久久 | 色操插 | 欧美日韩调教 | 一区二区三区精品在线视频 | 国产精品第一视频 | 色综合色综合色综合 | 波多野结衣电影一区二区 | 天天色天天综合 | 91精品国产99久久久久 | 国产亚洲欧美在线视频 | 国产精品9999| 在线看国产 | 亚州天堂 | 欧美色操| 国产一区二区免费看 | 69视频永久免费观看 | 91激情视频在线播放 | 日本公乱妇视频 | 蜜臀av性久久久久av蜜臀三区 | 免费在线精品视频 | 日本久久片| 国产亚洲精品女人久久久久久 | 欧美 日韩精品 | 国产精品岛国久久久久久久久红粉 | 久久国产精品一区二区三区 | 91香蕉视频720p| 日日草夜夜操 | 亚洲国产成人在线观看 | 亚洲一区二区三区miaa149 | 视频在线观看91 | 久久国产剧场电影 | 国产不卡免费 | 日韩精品黄 | 日本久久电影网 | 久久这里只有精品1 | av中文字幕av | 夜夜操天天干 | 国产精品久久久久久久久毛片 | 亚洲精品一区中文字幕乱码 | 欧美激情另类 | 亚洲成年片 | 亚洲国产影院av久久久久 | 不卡的av片 | 国产精品久久久久久久免费 | 日韩欧美xxxx | 一区二区三区四区五区六区 | 天天干视频在线 | 九色视频网站 | 亚洲91中文字幕无线码三区 | 亚洲专区一二三 | 日韩中文字幕免费看 | 欧美日韩精品在线免费观看 | 免费看国产精品 | 亚洲精品久久久久中文字幕m男 | 日韩欧美视频一区二区三区 | 韩国av永久免费 | 激情丁香婷婷 | 午夜国产在线 | 国产手机视频精品 | 国产短视频在线播放 | 久久99在线观看 | 亚洲最大av| 中文字幕亚洲精品日韩 | 最新国产精品拍自在线播放 | 精品国产91亚洲一区二区三区www | av片子在线观看 | 久久久九色精品国产一区二区三区 | 久久免费视频99 | 久久天天操 | 黄色高清视频在线观看 | 国产亚洲aⅴaaaaaa毛片 | 中文字幕视频三区 | 在线黄频| 天天操天天色综合 | 日日日日日 | 亚洲精品动漫在线 | 亚洲第一伊人 | 色婷婷五 | 在线观看日本高清mv视频 | 99视频精品免费观看, | 亚洲精品午夜一区人人爽 | 国产精品高清在线 | 久久av高清 | 99精品国产亚洲 | 日韩av片在线 | av电影中文字幕在线观看 | 99视频99| 亚洲国产高清视频 | 深夜福利视频在线观看 | 久久国产女人 | 久久久久中文 | 国产手机在线观看 | 欧美一区三区四区 | www.久久久精品 | 国产高清在线a视频大全 | 久久免费看a级毛毛片 | 日韩激情久久 | 日韩精品一区二区三区在线视频 | 免费情趣视频 | 久久夜夜爽 | 99九九热只有国产精品 | 亚洲国产精品一区二区久久,亚洲午夜 | 高清av免费看 | 人人澡视频 | 色射爱 | 国产免费嫩草影院 | 99免在线观看免费视频高清 | 国产精品久久99 | 在线看免费 | 在线色亚洲 | 久久视频这里有精品 | 国产精品99久久久久的智能播放 | 99精品欧美一区二区 | 九九免费在线观看视频 | 日韩婷婷| 亚洲一区二区三区在线看 | 337p西西人体大胆瓣开下部 | 伊人影院得得 | 欧美污污视频 | 成人免费在线视频观看 | 777视频在线观看 | 日产av在线播放 | 国产真实在线 | 中文字幕免费一区 | 亚洲精品99 | 久久精品网站视频 | 亚洲人人射 | 免费观看的黄色 | 天天干夜夜想 | 久久爱综合 | 国产69精品久久久久久久久久 | 97超碰超碰 | 久久亚洲在线 | 国产福利免费看 | 久久草av | 色悠悠久久综合 | 精品一区二区在线免费观看 | 奇米影视777四色米奇影院 | 久黄色| 国产精品专区在线 | 在线之家官网 | 黄色影院在线免费观看 | 成人亚洲网 | 国产日韩精品在线观看 | 国产激情免费 | 国产视频 亚洲精品 | 日韩在线视频网 | 亚洲第一成网站 | 色多多污污在线观看 | 不卡视频国产 | 久久不卡视频 | 午夜久久影视 | 国产精品免费久久久久影院仙踪林 | 在线看一区 | 四虎8848免费高清在线观看 | 亚洲成人动漫在线观看 | 国产高清视频免费观看 | 国产亚洲午夜高清国产拍精品 | 精品久久久成人 | 亚洲精品乱码久久久久久蜜桃91 | 国产99一区视频免费 | 免费在线观看污 | 日韩免费观看视频 | 精品电影一区 | 国产永久免费 | 在线观看中文字幕第一页 | 久久综合狠狠综合久久狠狠色综合 | 成人一级影视 | 胖bbbb搡bbbb擦bbbb| 国产精品黄网站在线观看 | 国产精品理论在线观看 | 国产精品一区在线观看你懂的 | 亚洲国产精品一区二区久久,亚洲午夜 | 五月激情久久久 | 午夜视频一区二区三区 | 热久久国产精品 | 免费av网站在线 | 最新真实国产在线视频 | 亚洲欧洲成人 | 四虎永久免费在线观看 | www.天天成人国产电影 | 91人人射| 免费三级影片 | 玖玖在线免费视频 | 99国内精品久久久久久久 | 欧美精品久久久久久久久免 | 99视频一区 | 一区二区三区韩国免费中文网站 | 美女av电影 | 黄色美女免费网站 | 日韩久久在线 | 91高清在线看 | 18久久久久久 | 免费高清影视 | 91网址在线观看 | 日韩av电影中文字幕在线观看 | 亚洲成av人影院 | 国产老太婆免费交性大片 | 521色香蕉网站在线观看 | 97碰在线视频| 国产精品初高中精品久久 | 亚洲天堂网在线视频 | 黄色动态图xx | 一区电影 | 狠狠网站| av免费网| 狠狠操欧美 | 免费看成人片 | 91| 韩国av一区二区三区在线观看 | 最近免费中文字幕 | 日韩av片免费在线观看 | 中文字幕 在线看 | 国产欧美最新羞羞视频在线观看 | 久久精品视频网 | 狠狠狠狠狠色综合 | 国产综合精品久久 | 一区二区三区动漫 | 一区免费在线 | 成人av亚洲 | 在线观看免费黄视频 | av一级免费| 天天射天天色天天干 | 欧美成人一区二区 | 中文字幕一区二区三区四区视频 | 国产精品免费成人 | 国产亚洲欧美在线视频 | 国产在线观看 | 久久精品视频网 | 美女国内精品自产拍在线播放 | 九热在线 | 亚洲成人黄色在线观看 | 中文字幕精品一区 | 国产成人久久av免费高清密臂 | 亚洲伦理电影在线 | 久久福利国产 | 国产伦理久久精品久久久久_ | 在线免费观看涩涩 | 久久久久亚洲天堂 | 在线看黄网站 | 午夜久久福利影院 | 久久久亚洲国产精品麻豆综合天堂 | av大全在线免费观看 |