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

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

[复制链接]
STMCU小助手 发布时间:2021-12-29 23:50
STM32驱动eMMC读写数据- m1 O$ ]  E" q; f" A
参照 JEDEC eMMC标准:JESD84-B51 (Revision of JESD84-B50.1, July 2014)
7 {+ M' k7 n# e: F; }驱动芯片采用stm32h7xx芯片。通过官方HAL库中stm32h7xx_hal_mmc.h文件驱动,采用8bit数据传输模式,与SD卡驱动类似。实测写入速度6-10MB/s左右。4 p6 g0 ?- ~1 g0 a3 O' I5 P8 k
( {' j6 u+ W% ^6 D5 U/ D; v7 }9 D
初始化代码清单:
# z: g- U$ F, P' ?7 T$ j
( j0 S8 B3 m: d
  1. HAL_StatusTypeDef SDMMC1_MMC_Init(void)" c$ U0 y0 b) u+ Z6 h
  2. {, y6 e2 d" k, L& _! i$ \) b. P
  3.   hmmc1.Instance = SDMMC1;
    / W' i: M% |+ d
  4.   hmmc1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;0 b: G$ @% r+ D. G7 y2 X$ v
  5.   hmmc1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
    % Y' k* v( m  A$ e4 q7 G
  6.   hmmc1.Init.BusWide = SDMMC_BUS_WIDE_8B;5 p: N6 q+ h2 x% o) G
  7.   hmmc1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;" d6 Z! [* d  {8 u7 F9 n
  8.   hmmc1.Init.ClockDiv = 1;
    6 ^2 }) o9 R' L9 ~7 S
  9.   if (HAL_MMC_Init(&hmmc1) != HAL_OK)
    1 b' J/ W8 b, w/ Z& d
  10.   {
    4 K7 _7 _/ T" b+ ]3 x8 g
  11.       Error_Handler();
    8 W2 P; ?" M1 c9 m, }
  12.   }9 t3 V# L% h8 b2 x' Z
  13.   return HAL_OK;
    ; f. x8 M# ?% X4 C
  14. }
复制代码

/ s- j/ _. [( Q: a4 X6 O/ |- i底层驱动代码清单:! f9 j9 j' ?+ \. p

4 v& ^; W5 }" z! e$ ^0 b
  1. void HAL_MMC_MspInit(MMC_HandleTypeDef* hmmc)
    4 U7 n" y' i) S, G- u  z
  2. {( _1 h. _0 j4 X  V% {4 P
  3.   GPIO_InitTypeDef GPIO_InitStruct = {0};7 \, g, m8 B- v" c* M3 O! U$ P
  4.   if(hmmc->Instance==SDMMC1)
    $ `& e$ C6 G% p4 \
  5.   {
    & s. N  D) f9 d/ C* s$ D0 I
  6.   /* USER CODE BEGIN SDMMC1_MspInit 0 */* j0 e* p9 H3 a6 s3 A" z
  7.     /* Peripheral clock enable */
    , }; |  t6 `2 v* l) Y! v& Y: y
  8.     __HAL_RCC_SDMMC1_CLK_ENABLE();
    ' h$ {! U4 T% T) K& f! l; V
  9.     __HAL_RCC_GPIOC_CLK_ENABLE();
    - N4 K4 ?* }" j: K; S- f5 o
  10.     __HAL_RCC_GPIOD_CLK_ENABLE();1 T- _# a4 q: T
  11.     /**SDMMC1 GPIO Configuration    5 H7 H/ T- V+ N; D7 _) O) s
  12.               PC8     ------> SDMMC1_D0" {3 D8 ~; m0 K5 g. y1 c/ Y$ k
  13.            PC9     ------> SDMMC1_D1
    ! _; F* f+ x) `" j: b% M
  14.            PC10    ------> SDMMC1_D2
    & c; v7 x" H2 p
  15.            PC11    ------> SDMMC1_D3
      l. K  H( M4 n/ j0 R
  16.            PB8     ------> SDMMC1_D4
    ' v9 s. o4 N7 i1 b" W: t/ R
  17.            PB9     ------> SDMMC1_D5# ?; r" a. b2 [" F/ {5 j. ~
  18.            PC6     ------> SDMMC1_D6- d, ?' W; j0 i
  19.            PC7     ------> SDMMC1_D7' w% c, Q/ K8 W$ @$ G* b
  20.            PC12    ------> SDMMC1_CK
    7 F  e3 F6 B% j: y9 s) Q/ \5 P0 e
  21.            PD2     ------> SDMMC1_CMD& p2 {( \* P2 k( u6 }# q# _
  22.     */+ u- B5 n3 P  l/ F/ ~
  23.     GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_8
    / Z4 e' y( S0 o, _
  24.                           |GPIO_PIN_9|GPIO_PIN_6|GPIO_PIN_7;3 h4 e- Q* {. l7 W* O( l% Z6 i
  25.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;2 X, S# U: }3 P, h( y! O3 j/ o  N
  26.     GPIO_InitStruct.Pull = GPIO_NOPULL;0 \1 s$ ]6 ~) d4 v' R$ |4 y
  27.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;* X; s- ?# G) _* x6 R
  28.     GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;  Z8 J9 M* B6 O! N
  29.     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    0 |  d9 l9 P6 S+ t
  30. ! Z" Y$ k0 E, ]8 F0 J3 e
  31.     GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
    " Q" T% W. ^7 p% e
  32.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    ! r( G2 E9 S7 t1 c+ N2 o/ c3 P
  33.     GPIO_InitStruct.Pull = GPIO_NOPULL;
    8 G0 k/ B. s/ o; ^% B# M
  34.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;. f$ p8 u! W( F' ?% N; v* G; D" R
  35.     GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;; y" }- Z  t5 m1 m$ \
  36.     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);0 w( _/ d3 Z6 y8 z( I# {! g4 \

  37. * {. ^$ S! v1 F, v8 t8 W
  38.     GPIO_InitStruct.Pin = GPIO_PIN_2;
    7 W# q, G, R% j: h
  39.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    : s& {0 m' J' j& p
  40.     GPIO_InitStruct.Pull = GPIO_NOPULL;
    % s+ ]9 w- n7 _* [) X" L6 n
  41.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    2 F, ?% N# l  x5 [- P
  42.     GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;# O* a+ }5 V4 Q2 H; _3 @1 E4 f5 S
  43.     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);( Q3 v2 s; V' o. v$ o/ L7 p

  44. 0 {  q8 f* G/ `4 e
  45.    HAL_NVIC_SetPriority(SDMMC1_IRQn,1,1);  //配置SDMMC1中断
    / @* i# U5 P2 e
  46.    HAL_NVIC_EnableIRQ(SDMMC1_IRQn);        //使能SDMMC1中断
    0 E( U# ?2 X0 [3 D, B% }1 B
  47.    HAL_NVIC_SetPriority(SysTick_IRQn, 0x0E ,0);( b9 b9 a& u9 a) |
  48.   }
    ' k$ g7 R. `  l# ]
  49. }
复制代码
" K$ T5 j/ U8 _- j  Q4 R
在DMA模式下,从MMC卡的指定地址读取数据:
) \: Y  u3 G8 ?9 d% {6 v9 w
7 U( z0 g- `& m  b
  1. /**1 }5 Y1 O2 Q. U: ~' u" \+ F
  2.   * @brief  在DMA模式下,从MMC卡的指定地址读取数据1 d2 N- w% z( B, p
  3.   * @param  pData:指向将包含要传输的数据的缓冲区的指针4 w% i1 V$ N7 N; g* a
  4.   * @param  ReadAddr:要读取数据的地址; Z/ \3 l: k  Z* o
  5.   * @param  NumOfBlocks:要读取的MMC块数量
    $ G' C4 i! S$ C
  6.   * @retval eMMC状态
    1 D+ x5 [( q2 Z+ L
  7.   */
    9 {; F) U  P+ Y4 @/ Y) O
  8. uint8_t BSP_MMC_ReadBlocks_DMA(uint8_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks)
    & [+ R, C& t, ~, z. n0 g5 P
  9. {
    3 }3 r$ S7 x, m7 Z
  10.    HAL_StatusTypeDef Status =  HAL_OK;
    9 A8 Q6 o( O. k5 s* s9 O
  11. : G& J" H8 t+ }
  12.    if(HAL_MMC_ReadBlocks_DMA(&hmmc1, pData, ReadAddr, NumOfBlocks) != HAL_OK)( {; \! X0 E: t, i3 U3 W8 N& G5 I
  13.    {& p8 j0 `# H, W& t
  14.       Status = HAL_ERROR;8 C# \( r, [$ q- T' E
  15.    }
    ( L* u$ h* a" g" P; L( f
  16.    return Status;
    3 y, u3 ~& A! ?4 \3 t# [
  17. }
复制代码

) U1 R" ~) x. V在DMA模式下,向MMC卡的指定地址写入数据:/ [( e& q+ b5 n6 z1 _4 p& m
' ]+ @& B* w' Z6 a& ~  N
  1. /**
    - w# l* o$ k. d
  2.   * @brief  在DMA模式下,向MMC卡的指定地址写入数据* G/ _" H/ Z; c- z- ^& _8 L- [! P9 l. H- A
  3.   * @param  pData:指向将包含要传输的数据的缓冲区的指针
    / l: A9 l# d, V- H1 M3 }* C
  4.   * @param  WriteAddr:要写入数据的地址
    ( D5 {, a# a4 ~/ A" Q
  5.   * @param  NumOfBlocks:要写的MMC块的数量
    6 k! L4 q; G9 i' Y- N
  6.   * @retval MMC状态
    # q5 I$ Y( b" v/ Z# R& o% [& B
  7.   */
    1 a$ @: b( I7 n$ Y
  8. uint8_t BSP_MMC_WriteBlocks_DMA(uint8_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks)
    & C6 `/ E3 U+ A+ ^. O2 F
  9. {$ ]2 W2 f  A5 o+ p. L
  10.   HAL_StatusTypeDef Status =  HAL_OK;
    ( v# `' V2 @: o  {2 U

  11. % _4 d" Y" b- k. Y, ^! J0 S
  12.   /* Write block(s) in DMA transfer mode */
    ) K4 Y* E( e6 V/ ^( M! f0 n6 ~
  13.   if (HAL_MMC_WriteBlocks_DMA(&hmmc1, pData, WriteAddr, NumOfBlocks) != HAL_OK)+ E% a) Q2 v: r
  14.   {1 u) T# g3 |# j7 a& L7 g9 V- X
  15.     Status = HAL_ERROR;
    , u4 h2 n- L/ d' t: a0 b5 q+ C
  16.   }& M: r+ i* o, l2 z
  17.   return Status;
    0 a( w% F# D0 I% ]+ O+ q4 @
  18. }
复制代码

/ h% L1 Z  _1 j  |, D擦除eMMC卡数据:4 O, j  r9 w* e" `

7 h; c" _. |( K8 M* O9 G" a
  1. /**
    4 h4 H7 d+ G9 k" O# T- j, l
  2.   * @brief  擦除eMMC卡数据9 V3 e8 S$ `* g& f1 e, p7 `
  3.   * @param  无6 D, y) v: e" c; i
  4.   * @retval 无/ O/ l6 h4 [, U+ O7 r5 t3 |7 ?
  5.   */' B+ ?9 K7 u' T& ~4 g$ s7 P0 O
  6. void MMC_EraseTest(void); a% s# x/ W0 e* _. F/ V
  7. {
    - ]% M8 h: M! w; R
  8.    HAL_StatusTypeDef Status = HAL_OK;8 p" ?$ ?1 T  {5 G
  9.    HAL_StatusTypeDef EraseStatus = HAL_OK;
    . d  h( u2 [% z
  10.    if (Status == HAL_OK)
    ! j6 r5 C: S6 O3 J
  11.    {! W. c* ^0 F3 X0 x
  12.       Status = HAL_MMC_Erase(&hmmc1, 0x00, (BLOCK_SIZE * NUMBER_OF_BLOCKS));4 ?- q: o( x: Q4 N- _  _4 d
  13.       //等待擦除完成
    ' c2 B5 M. i( A) p  H, N9 s/ x
  14.       if(Wait_SDCARD_Ready() != HAL_OK)4 [4 N7 d1 t" t" W1 X/ w( L3 V
  15.       {
    - T* O% I6 H4 f+ {$ {5 Q0 O2 p& D
  16.          EraseStatus = HAL_ERROR;$ c4 O/ D' J1 j& M+ E5 J& b
  17.       }
    ; G1 T  T; j1 \. O2 u
  18.    }5 H3 F: T# l# |  v6 B+ w; G3 ]; {8 I' h
  19.    if(EraseStatus != HAL_OK)* c. t0 D8 C, b8 `  y( I: F+ T
  20.    {   
    ' \6 Q) t6 e2 C* K/ @( ]5 V; r
  21.       Error_Handler();6 R4 j  |- D# Q7 P( ^8 B
  22.    }
    2 [- {  h$ L! J1 n& H1 t
  23. }
复制代码
7 B+ D1 l2 _3 l9 F6 m
eMMC卡等待擦除完成函数:7 G" N: _8 n# f5 [& ?
1 S4 Y$ h2 k/ {( @2 a! A2 ?% K! w
  1. /**
    2 B3 c, x! n3 u$ j# C- o# a
  2.   * @brief  eMMC卡等待擦除完成函数- t) J& M0 |; k) U. |' e
  3.   * @param  无- V- f& I3 ]$ q+ Y! M; n
  4.   * @retval HAL_OK:擦除成功;HAL_ERROR:擦除失败
    4 ~3 D% a" f3 M1 I
  5.   */& @7 F0 w% v$ {, }2 H1 n: x) @
  6. static HAL_StatusTypeDef Wait_SDCARD_Ready(void)8 [& x/ H  a0 I+ S' Z
  7. {
    3 h6 H( o+ J: x5 k" C: \& H- Z
  8.    uint32_t loop = MMC_TIMEOUT;
    ! T5 K! S' U9 {, x
  9. 1 X5 h9 `2 v0 H* P0 J7 u+ Z- P# ]
  10.    /* Wait for the Erasing process is completed */
    - k/ W$ ?) L  U- t7 Q3 u, W
  11.    /* Verify that SD card is ready to use after the Erase */( n2 `3 ?/ ^/ `* i* e- V1 U; B. C
  12.    while(loop > 0)/ E. L" K2 Q* k: V
  13.    {! o% f8 c& I; @9 r: N$ `' [
  14.       loop--;
    2 ~, N" E, `# ^; B
  15.       if(HAL_MMC_GetCardState(&hmmc1) == HAL_MMC_CARD_TRANSFER)/ W( Q1 A' e  I/ e: B
  16.       {
    + C; E3 Y4 ?. d' R* Y
  17.          return HAL_OK;! _. A% L" t  _! }$ j/ B! d/ q
  18.       }
    3 j" X5 U2 P$ B: p" u
  19.    }3 Q+ T" e- y; K9 x
  20.    return HAL_ERROR;
    : V# p$ y& T1 f, R3 a
  21. }
复制代码
4 X6 A) |  O1 y6 R2 R
最近移植的eMMC卡的驱动程序,分享出来希望对各位开发者有所帮助。还移植了FATFS文件系统到eMMC驱动程序中,之后整理好再分享。
1 a$ ^% Y; Y  Q; l: E$ v* N/ Z
5 c) Z% ~8 M2 j& c  m; h# s. w  T. ~% M1 D# a5 [3 q$ }- h# U
赞 收藏 评论0 发布时间:2021-12-29 23:50

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版