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

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

[复制链接]
STMCU小助手 发布时间:2021-12-29 23:50
STM32驱动eMMC读写数据
9 O; `7 _7 ]9 v) Y: c参照 JEDEC eMMC标准:JESD84-B51 (Revision of JESD84-B50.1, July 2014)  j( i: p% w) c0 z0 O7 H
驱动芯片采用stm32h7xx芯片。通过官方HAL库中stm32h7xx_hal_mmc.h文件驱动,采用8bit数据传输模式,与SD卡驱动类似。实测写入速度6-10MB/s左右。) t. F  Q1 a" u* V6 `* U
0 E$ l/ m$ B, g: D5 b
初始化代码清单:3 [5 k8 H# Y7 O4 i% c7 Z
6 K% I  }2 J; P( k9 m3 `# H- W" Z# U4 K
  1. HAL_StatusTypeDef SDMMC1_MMC_Init(void): b9 F) R& h( L7 _
  2. {
    ' _, U: y8 q: t
  3.   hmmc1.Instance = SDMMC1;; }6 ~2 h! V2 l( g* [% ?
  4.   hmmc1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;% v2 @. R# w- ^
  5.   hmmc1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
    4 u- b5 }3 U7 c7 y8 @% M
  6.   hmmc1.Init.BusWide = SDMMC_BUS_WIDE_8B;
      T7 a# w# {8 U( ?. j" @
  7.   hmmc1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
    % ?0 s" U7 S: c' t2 h: T' v
  8.   hmmc1.Init.ClockDiv = 1;
    , D( }! V# m( W+ U3 B
  9.   if (HAL_MMC_Init(&hmmc1) != HAL_OK)
    ( d8 O% o  t9 W. J
  10.   {
    , M  T3 I3 P4 E
  11.       Error_Handler();0 s5 E2 E& B' N+ n, z$ s
  12.   }
    ) J7 ]0 \, Y; d; c! g" V- ^$ n
  13.   return HAL_OK;& b1 B9 B. J/ j2 ?/ \) ]* a/ o
  14. }
复制代码
7 S% C2 [4 C" @9 |- A' A
底层驱动代码清单:
7 H; E& X8 w$ M- }4 n! j8 D, m) r: |& D0 b' w. G* c
  1. void HAL_MMC_MspInit(MMC_HandleTypeDef* hmmc)
    9 }6 W. f. W. F
  2. {+ b7 p' G; u$ s4 W  r- D0 T7 N
  3.   GPIO_InitTypeDef GPIO_InitStruct = {0};
    " F) R% s, W5 o1 Z3 |$ j
  4.   if(hmmc->Instance==SDMMC1)1 j9 M8 o) p2 }9 h) h6 p8 S+ X
  5.   {
    7 h- @. r5 R2 s
  6.   /* USER CODE BEGIN SDMMC1_MspInit 0 */: Q, M5 D( r" c
  7.     /* Peripheral clock enable */
    1 Q  k" v, W+ H. ^- h: T7 @; b
  8.     __HAL_RCC_SDMMC1_CLK_ENABLE();! S$ U1 [4 m# T" A
  9.     __HAL_RCC_GPIOC_CLK_ENABLE();1 t, b! }- B$ h& W! U
  10.     __HAL_RCC_GPIOD_CLK_ENABLE();( w9 E8 n& K, {% B
  11.     /**SDMMC1 GPIO Configuration   
    . b4 }$ W7 ?7 s  J) u5 g  s
  12.               PC8     ------> SDMMC1_D0
    + v  [2 {& C8 x2 O0 Q4 h, c/ H6 b
  13.            PC9     ------> SDMMC1_D1 1 G7 g( C* G4 \5 w, k
  14.            PC10    ------> SDMMC1_D2
    ! B+ E& d+ I) x: P
  15.            PC11    ------> SDMMC1_D3
    ) ^7 D; I: ^0 {. N0 g# g
  16.            PB8     ------> SDMMC1_D4
    . F# T/ E3 j$ j# ~: _
  17.            PB9     ------> SDMMC1_D5
    0 l7 i: g, V- W; o* G
  18.            PC6     ------> SDMMC1_D6
    * B! D7 g3 M: B. m
  19.            PC7     ------> SDMMC1_D7
    0 P% N, {( S/ l
  20.            PC12    ------> SDMMC1_CK+ ]: S9 ]" N+ X3 Y% [
  21.            PD2     ------> SDMMC1_CMD2 [  j. T  d8 }
  22.     */7 O1 I! J+ X0 ~. X4 O% ]
  23.     GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_8 + ^0 \2 A( {3 C9 h, f4 w" r3 s
  24.                           |GPIO_PIN_9|GPIO_PIN_6|GPIO_PIN_7;
    6 L% j: p/ _! |: e1 m
  25.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    6 J& i- }/ g- l. P2 G
  26.     GPIO_InitStruct.Pull = GPIO_NOPULL;
    ) z0 |( z4 m0 P2 H, r* F  r4 x, u
  27.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    # j- ~- Q* ~& Z1 p7 H/ k, m6 v! M
  28.     GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;
    ( B8 b7 j( B2 W4 p( }/ g0 e! k) q
  29.     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    - w1 O& X' ~0 e6 g" f1 L7 e
  30. 4 Y7 K, F6 X( D! i# ^9 I
  31.     GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
    $ t% m' K9 h4 L# f% d  N4 o& @
  32.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    * `) g8 s5 C; y7 T
  33.     GPIO_InitStruct.Pull = GPIO_NOPULL;7 l+ q2 x- J- I! R) ]/ z
  34.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;" S, e- O* A% Q" u9 l0 o
  35.     GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;/ i; w5 q" d( [; h# j0 P; O( [
  36.     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    % p, T. y! D% [% l7 m! J
  37. / q7 e; G! m( Y
  38.     GPIO_InitStruct.Pin = GPIO_PIN_2;) [$ W0 K2 H, H7 Q
  39.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    ) w" S- L4 w( B0 \  F
  40.     GPIO_InitStruct.Pull = GPIO_NOPULL;
    9 L+ a2 F, t0 }, I1 Z5 J
  41.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    * `2 q' l9 t: x, X! L
  42.     GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;
    7 E! h( L) I8 E6 T% ^0 L4 I3 c& v' c
  43.     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);# t* s& n2 x$ F. m

  44. $ f, V; P( x: _  G+ ?- [3 \( X; z
  45.    HAL_NVIC_SetPriority(SDMMC1_IRQn,1,1);  //配置SDMMC1中断  r2 B9 I0 F% ^0 [7 c$ c" P! [: @
  46.    HAL_NVIC_EnableIRQ(SDMMC1_IRQn);        //使能SDMMC1中断( X' ~8 u8 I. F
  47.    HAL_NVIC_SetPriority(SysTick_IRQn, 0x0E ,0);
    0 F! v3 m- z; L0 _3 n
  48.   }' _# }, p+ K* ~& j
  49. }
复制代码
! W$ q, S' {6 P" B- |
在DMA模式下,从MMC卡的指定地址读取数据:5 x5 u2 d) j. @6 n/ b
0 G3 ]0 Q% B  M$ |
  1. /**
    7 J$ x# D1 K# u  z/ _) E' Z
  2.   * @brief  在DMA模式下,从MMC卡的指定地址读取数据
    2 o$ z1 J. K; K' S
  3.   * @param  pData:指向将包含要传输的数据的缓冲区的指针" w+ r' A8 J, |1 s3 g2 A+ u1 U
  4.   * @param  ReadAddr:要读取数据的地址
    , B! |* K+ j/ i, i
  5.   * @param  NumOfBlocks:要读取的MMC块数量
    8 Q$ k/ [; ^- [
  6.   * @retval eMMC状态
    & p3 E5 t6 e) k/ ?# n6 R
  7.   */
      u4 ]9 {5 {! h' W+ T# F
  8. uint8_t BSP_MMC_ReadBlocks_DMA(uint8_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks)1 v0 c6 X5 e: O$ Q9 f  I, i$ X9 l
  9. {: x! Q/ n5 F/ r0 ?! I
  10.    HAL_StatusTypeDef Status =  HAL_OK;
    # g' _  W  [7 n+ o3 U( v( @
  11. / h; a% K3 }1 N  J% p/ O: i" Y
  12.    if(HAL_MMC_ReadBlocks_DMA(&hmmc1, pData, ReadAddr, NumOfBlocks) != HAL_OK)
    . x" ?+ x, E6 D- E6 L; ?
  13.    {
    5 D& \# K0 A9 v( s  l' }. S; d
  14.       Status = HAL_ERROR;; g! c  F! K3 t1 G, C
  15.    } 0 l  l( C0 f- i9 c, t& N
  16.    return Status;
    ; P2 V" Z7 t* G! M6 V4 P% I1 m' n6 n
  17. }
复制代码
5 w2 U& ~1 e) V  S4 S8 V
在DMA模式下,向MMC卡的指定地址写入数据:
7 r0 A; o; M8 l& L4 K
8 p% w4 B7 v, O  \7 k% M
  1. /**
    0 L4 }, F7 n/ l7 K  {% @, f" z$ D
  2.   * @brief  在DMA模式下,向MMC卡的指定地址写入数据
    : }3 i' i3 I1 f1 }5 U5 a  |
  3.   * @param  pData:指向将包含要传输的数据的缓冲区的指针7 X/ h; Z, o7 h2 [  H
  4.   * @param  WriteAddr:要写入数据的地址
    ; }" j, g) [. B; Q( m
  5.   * @param  NumOfBlocks:要写的MMC块的数量
    9 ]: I# _* F6 O5 ?
  6.   * @retval MMC状态3 S( {+ Q  a) d: N5 ~
  7.   */& A1 x# s: z9 a8 z2 r% ^" d: c
  8. uint8_t BSP_MMC_WriteBlocks_DMA(uint8_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks)9 F- f% G& Q7 g- H' d9 `) n; w. l
  9. {7 p8 E& G, A/ L' \- J3 ]
  10.   HAL_StatusTypeDef Status =  HAL_OK;; q5 e5 ?& j: U# H6 \
  11. 7 b- g' q! i  y4 L# {
  12.   /* Write block(s) in DMA transfer mode */3 A  f6 K: O& _0 Q6 ]# t6 M: ]
  13.   if (HAL_MMC_WriteBlocks_DMA(&hmmc1, pData, WriteAddr, NumOfBlocks) != HAL_OK)$ V; b3 `0 D% ^! m+ f
  14.   {
    " ?  ?1 I. f: z3 [0 ~) ~
  15.     Status = HAL_ERROR;5 u/ O* M' M+ E/ {3 ?2 P8 R
  16.   }) _. C9 y1 c& X6 ?9 p4 L
  17.   return Status; 0 o% P6 K, q9 l: z; c1 \
  18. }
复制代码
$ R* S/ ^& s+ k3 e
擦除eMMC卡数据:
& ]% a' V% I3 `; u4 j! D; N) L! k( f7 c
  1. /**
    0 G. V5 u6 V. A. h
  2.   * @brief  擦除eMMC卡数据
    8 l+ c0 q) Y1 `4 E! F
  3.   * @param  无+ S* x( @; [+ T* d. R0 Q
  4.   * @retval 无1 ?" ^8 h5 n* C, \
  5.   */6 D5 |- `  @, `1 B, o8 U9 u& @
  6. void MMC_EraseTest(void)
    / K# f* G, O8 ^+ R5 ~% X
  7. {
    3 q+ o4 W7 @& p
  8.    HAL_StatusTypeDef Status = HAL_OK;
    $ s" G: O/ Z; Z& \
  9.    HAL_StatusTypeDef EraseStatus = HAL_OK;2 d1 w- z3 s- _: g6 ~4 a# u
  10.    if (Status == HAL_OK)
    $ u: @0 f  s# G0 s1 U* r
  11.    {
    " T! C/ \/ S: N* R
  12.       Status = HAL_MMC_Erase(&hmmc1, 0x00, (BLOCK_SIZE * NUMBER_OF_BLOCKS));
    . M& ?; n8 w1 {& X% t1 `% k
  13.       //等待擦除完成
    ( H" B3 z2 U. \9 x8 f8 h5 e( l
  14.       if(Wait_SDCARD_Ready() != HAL_OK)0 h' l  J1 F4 M' y- \3 I4 r1 `
  15.       {! p4 n% O( i% e( i) a# p, J
  16.          EraseStatus = HAL_ERROR;) t' M& W* K# }, Z9 U
  17.       }9 I& Z: n2 {; O" A. r' K
  18.    }& x4 U0 ~' K1 Q# ~3 ~9 |; N! Q
  19.    if(EraseStatus != HAL_OK)  v: V+ N+ `+ Q7 J" g
  20.    {   
    & `  D- D% o# B, t/ N) M+ O1 Y
  21.       Error_Handler();
    / m4 f5 Y  h# f: b9 v! w  L5 |" P
  22.    }
    + f! J; u! i3 W4 A8 v
  23. }
复制代码

8 f" N% J3 V- C* c' X* reMMC卡等待擦除完成函数:
4 l; M2 |* B1 X* K  K* e: `0 P4 Y7 w" l: c0 B; R
  1. /**
    ) y* D9 P, [% y2 i% r
  2.   * @brief  eMMC卡等待擦除完成函数
    , Q9 P! f( N/ }6 @
  3.   * @param  无5 v- ?! \) ]- t  X8 T* y- C
  4.   * @retval HAL_OK:擦除成功;HAL_ERROR:擦除失败
    ; L7 d3 l  p9 q& u5 W
  5.   */; X6 b, D/ `/ j( u. P9 m- n
  6. static HAL_StatusTypeDef Wait_SDCARD_Ready(void)
    ! D& u: W  B- q0 Z4 Y) I; I
  7. {6 P, ]8 i/ S9 W& T" Y6 x3 [5 P
  8.    uint32_t loop = MMC_TIMEOUT;
    % s5 Y3 X4 M% m( I3 }3 g

  9. 9 a" ?3 }' P' ~$ v
  10.    /* Wait for the Erasing process is completed */' K3 j/ v9 X3 _: p
  11.    /* Verify that SD card is ready to use after the Erase */- r. O" R; W0 @, P! V
  12.    while(loop > 0)$ X& L' \6 ]" E8 N& S) J
  13.    {! x% G, u' O6 S8 S  T/ r% ^; X
  14.       loop--;
    ; t3 t# z- A* a; \
  15.       if(HAL_MMC_GetCardState(&hmmc1) == HAL_MMC_CARD_TRANSFER)  H' C" e/ }4 Y# T. A
  16.       {8 J/ e. E. }/ [: F% Q1 J$ F
  17.          return HAL_OK;
    ! h. i+ v5 R& k' x. M6 q# h& a
  18.       }% C; }" R6 ?) n. _
  19.    }
    . o3 r8 u" L$ U$ o! Z4 s, P
  20.    return HAL_ERROR;: I- D+ f' J, v5 g+ p
  21. }
复制代码

" b9 k' X) J, D' c( g最近移植的eMMC卡的驱动程序,分享出来希望对各位开发者有所帮助。还移植了FATFS文件系统到eMMC驱动程序中,之后整理好再分享。
4 T( \8 q- i( y* E5 V$ K! E: V& @7 Y7 _3 f/ Q% Z
! t  a% B" X. A- d1 e
收藏 评论0 发布时间:2021-12-29 23:50

举报

0个回答

所属标签

相似分享

官网相关资源

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