你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32驱动eMMC读写数据

[复制链接]
STMCU小助手 发布时间:2021-12-29 23:50
STM32驱动eMMC读写数据
: p6 V' t5 H8 P- w; E参照 JEDEC eMMC标准:JESD84-B51 (Revision of JESD84-B50.1, July 2014)
& l! {  J/ b) k" |6 ]/ t驱动芯片采用stm32h7xx芯片。通过官方HAL库中stm32h7xx_hal_mmc.h文件驱动,采用8bit数据传输模式,与SD卡驱动类似。实测写入速度6-10MB/s左右。
- ~3 S6 P$ k: I8 [
6 t' q' S# H2 R4 W0 z: K初始化代码清单:& p* S( _$ i6 r" s( K

  z+ T) f' _3 c  ?
  1. HAL_StatusTypeDef SDMMC1_MMC_Init(void)
    ' S6 z- _0 O1 h* _1 x# l4 ?
  2. {) i/ F4 {$ I: l" z+ X
  3.   hmmc1.Instance = SDMMC1;
    $ R/ Y; f$ ?  ~% m/ t, X
  4.   hmmc1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
    1 C# w5 e; q6 E+ ]" R) L2 s& C9 T# W
  5.   hmmc1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
    . Z: K4 Z( `' e( Q
  6.   hmmc1.Init.BusWide = SDMMC_BUS_WIDE_8B;
    ! k  H8 n4 Z# g) Q
  7.   hmmc1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
    2 }" {4 \% J; ]& v  B$ L5 s' _
  8.   hmmc1.Init.ClockDiv = 1;6 [0 m' |2 O: Q% w) ]
  9.   if (HAL_MMC_Init(&hmmc1) != HAL_OK)9 t" l7 }$ H# h5 l) \& ^" u
  10.   {, r7 D9 I4 c3 \5 i8 c
  11.       Error_Handler();4 f4 p! e* f9 a# [0 d
  12.   }% H4 v: Y; ?& `: q
  13.   return HAL_OK;3 O! j- @4 t. k0 F
  14. }
复制代码

1 d3 A; B9 B3 |5 U; g底层驱动代码清单:
- r* x; B2 c- v, d7 i( {+ l+ y  y0 w6 S6 J
  1. void HAL_MMC_MspInit(MMC_HandleTypeDef* hmmc)
    $ W% G, H2 R# D7 H+ [
  2. {
    # _! _5 k7 g: k
  3.   GPIO_InitTypeDef GPIO_InitStruct = {0};
    , j; y( R# i+ t& ]* J7 D, [
  4.   if(hmmc->Instance==SDMMC1)
    ' X2 D0 P# b' C( F: j
  5.   {
    ! U, Z6 Y* B" m7 b5 ]! v" A) g  w9 [
  6.   /* USER CODE BEGIN SDMMC1_MspInit 0 */
    - a6 l' O; v& W. _3 _3 d! m8 T( M
  7.     /* Peripheral clock enable */
    ; I) J8 J- G5 T/ \1 p% D
  8.     __HAL_RCC_SDMMC1_CLK_ENABLE();
    0 ?% x2 J8 ~$ {( `/ m( O
  9.     __HAL_RCC_GPIOC_CLK_ENABLE();/ u% X0 T- {/ Q+ r8 H' X0 `2 K
  10.     __HAL_RCC_GPIOD_CLK_ENABLE();: x$ u; y1 c- D& f
  11.     /**SDMMC1 GPIO Configuration   
    $ x5 T- e7 e' A. l
  12.               PC8     ------> SDMMC1_D04 \# Q' W, g- K/ M9 Q, @! [9 \) e( J
  13.            PC9     ------> SDMMC1_D1 ! f" s( a4 I$ n4 f6 }
  14.            PC10    ------> SDMMC1_D20 j; @9 W2 A2 V$ c7 T& G
  15.            PC11    ------> SDMMC1_D3
    ; J; ^0 b# V% n
  16.            PB8     ------> SDMMC1_D4
    2 C7 R' l6 O% d: Z& N
  17.            PB9     ------> SDMMC1_D58 F: p4 n( C2 x/ G& h8 _+ w' `. ^3 G
  18.            PC6     ------> SDMMC1_D6
    1 t! V# e% D( p- _; G* ~
  19.            PC7     ------> SDMMC1_D7* V% V. y+ b9 l! m
  20.            PC12    ------> SDMMC1_CK+ U/ ?' ?5 B% V- a
  21.            PD2     ------> SDMMC1_CMD
    9 _& K" c. w$ H/ n3 a% O
  22.     */
    $ O8 b6 d: }+ u, ~. [; ?
  23.     GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_8 , d1 F/ k! ^# p
  24.                           |GPIO_PIN_9|GPIO_PIN_6|GPIO_PIN_7;
    3 m8 f0 u6 g2 A  g* L2 h0 g$ Y
  25.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    ) W1 Q5 c9 t- u) s
  26.     GPIO_InitStruct.Pull = GPIO_NOPULL;
    ; I. r, H0 [+ O9 P5 L3 t
  27.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;( E+ y$ s& X) k$ \0 A4 c  `9 G
  28.     GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;
    0 {7 [% w( w3 q+ F; {
  29.     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
      K, H1 T  W5 s

  30. / A; p. m% \: e/ A2 n$ i. Q4 w
  31.     GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;( [& |$ y: F* p% b5 B6 [
  32.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    - Y3 |2 Z' V  W4 u1 U; T( ^
  33.     GPIO_InitStruct.Pull = GPIO_NOPULL;
    4 ^8 s9 z. v/ @- \
  34.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    # R, s  \6 O6 v& `: w% W
  35.     GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;7 t" p: l- D3 j4 [* l! \
  36.     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    1 R5 a9 A% D2 G4 _
  37. 1 t! V) m* F! i& b. L; n! r7 p1 K
  38.     GPIO_InitStruct.Pin = GPIO_PIN_2;
    " J) c3 s2 w, u. {+ e" O2 ~
  39.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;1 \# P  G+ j5 c  R' p* [
  40.     GPIO_InitStruct.Pull = GPIO_NOPULL;; {3 ]+ [. f  M3 Z
  41.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;9 K* w9 h4 H  [: d, h7 B' o
  42.     GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;: v& d/ ]0 `1 _1 |) o
  43.     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
    ; {8 [5 R* n0 X" Q) d
  44. 8 ~. V5 F# m& H. X6 V& {/ H
  45.    HAL_NVIC_SetPriority(SDMMC1_IRQn,1,1);  //配置SDMMC1中断
    * f) q, r( b/ N, x
  46.    HAL_NVIC_EnableIRQ(SDMMC1_IRQn);        //使能SDMMC1中断" G5 N- _6 a% V; v# `. I
  47.    HAL_NVIC_SetPriority(SysTick_IRQn, 0x0E ,0);6 T$ F2 w0 u* K1 ^) P
  48.   }, P- l8 c& H9 i5 U6 v# G
  49. }
复制代码
: ~4 j, A$ x" ]
在DMA模式下,从MMC卡的指定地址读取数据:
2 s6 \/ E: k" x3 [. J
8 p  y% r' s: t9 s: @1 [
  1. /**
    / J  a" K# a; e2 [/ ]1 t  t( Y
  2.   * @brief  在DMA模式下,从MMC卡的指定地址读取数据8 `( x% ?  x1 O1 F0 l6 @
  3.   * @param  pData:指向将包含要传输的数据的缓冲区的指针, ~+ @9 U6 ~6 @4 _
  4.   * @param  ReadAddr:要读取数据的地址( q, q& \/ I, ^1 q' V+ V  j2 o
  5.   * @param  NumOfBlocks:要读取的MMC块数量
    ' |( B+ L7 T( S, a) @" c1 i; R
  6.   * @retval eMMC状态% ^; i  [" p# w0 i8 J' r( P
  7.   */  w4 U1 \+ t1 D
  8. uint8_t BSP_MMC_ReadBlocks_DMA(uint8_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks)" g) k5 r# t! v4 l
  9. {9 Z! K6 m1 Z) E) {
  10.    HAL_StatusTypeDef Status =  HAL_OK;; y" B% l) E2 G! W1 G4 i* `$ N

  11. / ?  {" m  r) E, w  }, `
  12.    if(HAL_MMC_ReadBlocks_DMA(&hmmc1, pData, ReadAddr, NumOfBlocks) != HAL_OK)
      _. @" r% W) u  ^/ c7 H, G
  13.    {/ m& D# }3 p2 |# d& W
  14.       Status = HAL_ERROR;2 }' z, N3 n. ?; d/ B- z  M
  15.    }
    " b  t$ z2 z; d! M
  16.    return Status; ' V' d3 c, L; T
  17. }
复制代码

; d6 e0 Y6 f- d7 p8 d在DMA模式下,向MMC卡的指定地址写入数据:
: u1 [, t4 d! [" i" ^! b
* l8 O' ?; R# ^$ J
  1. /**+ F# Y0 [' o1 v8 [# |5 R
  2.   * @brief  在DMA模式下,向MMC卡的指定地址写入数据
    9 }8 t) y9 |- {3 S' O' z
  3.   * @param  pData:指向将包含要传输的数据的缓冲区的指针
    " b6 u" G+ h1 c& C$ I' N& p3 d
  4.   * @param  WriteAddr:要写入数据的地址- l% m, G! c, ?# N8 ~9 \
  5.   * @param  NumOfBlocks:要写的MMC块的数量
    # e( v1 E# j% j4 A! `+ H
  6.   * @retval MMC状态( i. n) K5 O& ~" x0 r& m: t
  7.   */
    $ F1 ]# O* v$ n7 ]" [+ v5 a" j
  8. uint8_t BSP_MMC_WriteBlocks_DMA(uint8_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks)9 ?; v7 v/ d, M5 z
  9. {+ y) [. t  I7 ?
  10.   HAL_StatusTypeDef Status =  HAL_OK;% l" j4 j" u( i; Q! C: N1 V
  11. 9 e$ E; }' {& t9 O/ J7 }
  12.   /* Write block(s) in DMA transfer mode */2 Y* A; R8 a/ ]/ K
  13.   if (HAL_MMC_WriteBlocks_DMA(&hmmc1, pData, WriteAddr, NumOfBlocks) != HAL_OK)( l) f4 Y2 D: p3 _
  14.   {- b6 D- E, c6 f5 }0 N
  15.     Status = HAL_ERROR;! w4 ~( F$ c- E4 Z$ H% m
  16.   }
    2 ~% V7 S2 N# o: F: H8 \
  17.   return Status;
    2 ]5 r! ]" C$ V8 z% u; D4 R/ v
  18. }
复制代码

0 d" H! }1 o" x% d擦除eMMC卡数据:$ c4 L, T! x3 W4 I4 r0 Q/ W" ?

# v  [1 x2 K1 z" x& W
  1. /**3 g2 I# a$ U/ G3 V
  2.   * @brief  擦除eMMC卡数据" w$ X+ q& ]% k! u3 f9 v. `+ r
  3.   * @param  无
    5 n. w/ n. w. k9 }' O
  4.   * @retval 无
    ! t! E( j( a' m/ s0 Q: d
  5.   */
    5 ^8 F; v! F$ t9 A# T
  6. void MMC_EraseTest(void)
    ! u# D% l+ h- b" \- q7 t
  7. {( t$ H1 ?/ B# _* i) M# h3 ]" _
  8.    HAL_StatusTypeDef Status = HAL_OK;( Q( d# |( Y7 K8 U2 {+ g' V
  9.    HAL_StatusTypeDef EraseStatus = HAL_OK;
    # Y2 }3 i) D4 W/ O( M5 ^4 g. E1 j
  10.    if (Status == HAL_OK)& ?$ s4 v) D& ~% \/ L/ Z
  11.    {
    8 W% @4 Q# \0 f; O3 P( n; h
  12.       Status = HAL_MMC_Erase(&hmmc1, 0x00, (BLOCK_SIZE * NUMBER_OF_BLOCKS));
    - P# B! y7 B% `
  13.       //等待擦除完成
    ! b) n/ z7 R( m4 N
  14.       if(Wait_SDCARD_Ready() != HAL_OK)
    1 S8 y* q4 {) p5 y( [6 b3 ]2 n
  15.       {  D# t8 a/ F6 e# V! H; |
  16.          EraseStatus = HAL_ERROR;
    5 v5 A& s& N4 e% F% E
  17.       }8 m7 K# T7 ?. R& l
  18.    }+ U: \  n+ q- E8 V
  19.    if(EraseStatus != HAL_OK)7 I) A0 D+ d# M+ K4 H
  20.    {    * ]3 o' Y9 K$ }& ~
  21.       Error_Handler();
    4 y4 e) ?& e6 w, l$ {3 g0 E
  22.    }7 Z- A- L8 @* U( N4 z/ ]
  23. }
复制代码

# o7 N; a' J5 Z7 y, W* ]9 feMMC卡等待擦除完成函数:% Y% T4 b4 H& O8 B2 m+ x' {0 ]

3 L& A& Z0 w3 q( R2 G. D
  1. /**
    . A4 t2 F  a- C: ]& ~& @
  2.   * @brief  eMMC卡等待擦除完成函数. b8 F- h$ A" L  F' o# e
  3.   * @param  无
    % ]  _; a1 r% e+ E, e
  4.   * @retval HAL_OK:擦除成功;HAL_ERROR:擦除失败* q5 U# K# b/ R2 C" L, Q
  5.   */' S1 f1 o; ]/ C9 g( c" C8 B/ d8 p
  6. static HAL_StatusTypeDef Wait_SDCARD_Ready(void)
    ' {) Z+ ?6 p1 L, S2 w  }
  7. {$ E0 a( @' F( p- E# o! E3 j2 R1 F
  8.    uint32_t loop = MMC_TIMEOUT;# S% b" Y# t3 `
  9. 3 E% G- B5 \1 p) t# o
  10.    /* Wait for the Erasing process is completed *// D' n% p" I5 F3 h' O( d/ C, Z
  11.    /* Verify that SD card is ready to use after the Erase */
    * p! k# Y) Q& a3 N
  12.    while(loop > 0)
    ! I3 l( P$ _- S& c$ E- Q/ u+ o
  13.    {0 c4 H/ ]7 d! o9 n& N/ k1 z
  14.       loop--;& ?( E2 u/ {+ Y! d
  15.       if(HAL_MMC_GetCardState(&hmmc1) == HAL_MMC_CARD_TRANSFER). ], M$ a& }" g
  16.       {3 z2 @$ i0 o: v* ?- @4 U+ b! p) \
  17.          return HAL_OK;
    0 Y- |1 E, ^+ z! J& i9 L: h4 u3 k
  18.       }* T! o& C* ^9 `* ?# z' N: M
  19.    }' `3 D3 n0 E7 h. R8 w) A% S. y) T
  20.    return HAL_ERROR;
    ! q% b+ Z0 s+ A3 n5 j! [
  21. }
复制代码

% y9 V* X  f$ P* u7 u5 O最近移植的eMMC卡的驱动程序,分享出来希望对各位开发者有所帮助。还移植了FATFS文件系统到eMMC驱动程序中,之后整理好再分享。
9 p) f1 A2 k! G7 |$ b
- n* y/ Q7 }4 o9 r& I
+ B  N* a3 g8 o& ~$ v
收藏 评论0 发布时间:2021-12-29 23:50

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版