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

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

[复制链接]
STMCU小助手 发布时间:2021-12-29 23:50
STM32驱动eMMC读写数据
* s* c1 X; h4 @3 V参照 JEDEC eMMC标准:JESD84-B51 (Revision of JESD84-B50.1, July 2014)
7 A) t3 R# q' e4 _驱动芯片采用stm32h7xx芯片。通过官方HAL库中stm32h7xx_hal_mmc.h文件驱动,采用8bit数据传输模式,与SD卡驱动类似。实测写入速度6-10MB/s左右。9 B9 a2 X7 X9 F2 i2 d+ u

0 e- C3 u2 D# [( L5 Y4 }1 _: e初始化代码清单:
$ Z2 t$ @3 y: X  R/ h7 v# O1 \0 q
  1. HAL_StatusTypeDef SDMMC1_MMC_Init(void)9 Y( T: q  m# B0 U' P6 h4 g* N
  2. {
    5 `5 b/ p- h. E3 x
  3.   hmmc1.Instance = SDMMC1;( X  k5 ]- X/ ]* N+ ?* R3 P* }, |8 i
  4.   hmmc1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
    + l) r/ N& k# K/ r  w$ E+ w
  5.   hmmc1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;" w7 H; h" T0 R0 P* {
  6.   hmmc1.Init.BusWide = SDMMC_BUS_WIDE_8B;
    # S" `, B" ]- C9 Q' ?( @; S' |0 o
  7.   hmmc1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
    4 Q$ [4 `8 V+ R& `  T/ u
  8.   hmmc1.Init.ClockDiv = 1;. L; B! b% T/ N8 q1 Q4 `. C# v4 Y
  9.   if (HAL_MMC_Init(&hmmc1) != HAL_OK)
    . ^" O/ D  f7 w0 j; r: O
  10.   {3 C& |9 Y/ F$ I; s
  11.       Error_Handler();: }0 ]4 x* }) x% [' q  y, ^( M
  12.   }5 e& y9 Z# I" B: f
  13.   return HAL_OK;
    ' {  B" N* F% b7 N; F
  14. }
复制代码

* d& S1 i  p! f" r; u1 J( S4 Q底层驱动代码清单:
0 I9 D1 `3 l$ ^8 s4 b3 r4 w* h3 N1 [6 a6 N, [9 P0 }
  1. void HAL_MMC_MspInit(MMC_HandleTypeDef* hmmc)' y% d3 x. n+ ?, ]
  2. {
    & E- y) h2 s' l1 ]( i% {5 B) X
  3.   GPIO_InitTypeDef GPIO_InitStruct = {0};
    1 {! K+ |; A. X3 B) J$ C
  4.   if(hmmc->Instance==SDMMC1)5 H3 `; f2 p6 Y) A# v3 |! F
  5.   {8 O0 B4 o9 t( ~3 u) S/ o
  6.   /* USER CODE BEGIN SDMMC1_MspInit 0 */
    - X# [  p) [5 k
  7.     /* Peripheral clock enable */, H/ U  q, W4 z3 E5 ]& _5 F
  8.     __HAL_RCC_SDMMC1_CLK_ENABLE();# ~9 g  r: i) m
  9.     __HAL_RCC_GPIOC_CLK_ENABLE();
    . j8 `6 ^- @) ?3 T
  10.     __HAL_RCC_GPIOD_CLK_ENABLE();7 e3 j: J. y$ ^1 m( E
  11.     /**SDMMC1 GPIO Configuration    2 p& o% B  Z3 x# }/ h
  12.               PC8     ------> SDMMC1_D02 Y* q. C" }& d. |2 b+ o
  13.            PC9     ------> SDMMC1_D1 & q  N3 l" y% K* q, ]: r# B5 q4 q
  14.            PC10    ------> SDMMC1_D2# G6 j- z  c/ \: r
  15.            PC11    ------> SDMMC1_D3
    0 W' Q) s$ D: c' b3 T
  16.            PB8     ------> SDMMC1_D4# W# `, p9 f" z+ f
  17.            PB9     ------> SDMMC1_D5
    3 W9 B& e; m' J$ C& B' w2 _
  18.            PC6     ------> SDMMC1_D63 O4 g" `! r0 ]! a$ x: h1 D) g
  19.            PC7     ------> SDMMC1_D7
    5 U) M0 H4 E. t, s
  20.            PC12    ------> SDMMC1_CK
    ) k, H+ ^4 f7 n# ?5 ]
  21.            PD2     ------> SDMMC1_CMD
    9 W3 n, F: T5 {3 @  {; R
  22.     */
    ( _0 b$ ~. Z; }) X- c' u
  23.     GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_8 3 w- F! Z' h7 F& f
  24.                           |GPIO_PIN_9|GPIO_PIN_6|GPIO_PIN_7;
    / J0 |, }' Y" E# L- Z
  25.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    - \2 L6 S" O, ?6 P# |3 \/ ]
  26.     GPIO_InitStruct.Pull = GPIO_NOPULL;$ W- g$ h+ z0 g
  27.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;4 Y+ m7 z" X, n# f* o
  28.     GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;  }# p7 ]# e' j6 [) T
  29.     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);. d& y) D7 n& S! x; J. X

  30. " R" ~) ~( }. Q$ q4 n" {) ]. Q
  31.     GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
    * X2 I# l8 `; M# P
  32.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;- c7 X1 |; _, B6 N* r) Q
  33.     GPIO_InitStruct.Pull = GPIO_NOPULL;
    " Q+ ?1 w& ]% s! b
  34.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    8 J7 f) x5 v/ `7 J2 u( s, O6 m
  35.     GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;
    & }; x0 V8 S, R6 _2 S  C: N5 w
  36.     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);3 U- o* ?% R0 m1 x( t$ [7 o3 ^
  37. 3 p7 C+ J/ f2 ~2 ]% V
  38.     GPIO_InitStruct.Pin = GPIO_PIN_2;/ m: J' ^" v3 I% |5 J3 Z
  39.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;2 ]' C. a. G5 s
  40.     GPIO_InitStruct.Pull = GPIO_NOPULL;
    2 z5 X  d; x- [8 K
  41.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    9 y8 L* @  ?( \* E: ?" X  l/ u
  42.     GPIO_InitStruct.Alternate = GPIO_AF12_SDIO1;
    4 L1 j: D3 p; J7 J# @; X' ]
  43.     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
    6 i# A2 y( e) T4 L

  44. / q* U& r2 i0 C; }
  45.    HAL_NVIC_SetPriority(SDMMC1_IRQn,1,1);  //配置SDMMC1中断
      Z/ z1 R' J' V) i  e
  46.    HAL_NVIC_EnableIRQ(SDMMC1_IRQn);        //使能SDMMC1中断
    4 {8 f. O. T, t+ l
  47.    HAL_NVIC_SetPriority(SysTick_IRQn, 0x0E ,0);" T, x$ ~' P3 R7 J" ]1 h: {/ A- w
  48.   }
    $ q$ k/ L( P; [) W
  49. }
复制代码
. y- S- |3 \6 z4 f
在DMA模式下,从MMC卡的指定地址读取数据:
$ \0 k& m+ v0 D
2 s4 `' J9 y7 i( ?) v
  1. /**
    ( K+ `/ l* C4 G- ~  c1 X
  2.   * @brief  在DMA模式下,从MMC卡的指定地址读取数据
    - t) A) l, f7 i  {
  3.   * @param  pData:指向将包含要传输的数据的缓冲区的指针
    0 T# r7 j# Z0 I  O- _9 \
  4.   * @param  ReadAddr:要读取数据的地址& U2 n( G2 m! H/ q. o1 n  H- N
  5.   * @param  NumOfBlocks:要读取的MMC块数量
    + t' u6 @9 A) g0 |9 \
  6.   * @retval eMMC状态
    # ]' S; ]1 Y5 d/ e
  7.   */9 T1 B5 ]# k1 K: n) |& [/ }/ w4 d' d
  8. uint8_t BSP_MMC_ReadBlocks_DMA(uint8_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks)
    " v7 Q$ v' f% H. z* u: F
  9. {& w/ D. I. \( `
  10.    HAL_StatusTypeDef Status =  HAL_OK;
    : D  y$ i0 c# _5 K7 s

  11.   \/ a! w6 L6 X6 _5 z( @
  12.    if(HAL_MMC_ReadBlocks_DMA(&hmmc1, pData, ReadAddr, NumOfBlocks) != HAL_OK)0 L; E9 B5 |3 Z' U0 \3 B2 H
  13.    {
    * h9 q+ L# _8 K2 x4 J  I
  14.       Status = HAL_ERROR;2 h' N' \5 C8 n  O
  15.    } + k8 k* X5 l8 E& Y
  16.    return Status;
    % k* x7 v) A8 x0 D) u( R
  17. }
复制代码
- h" M2 m# _6 I0 T( g
在DMA模式下,向MMC卡的指定地址写入数据:
& K+ V. |' I3 N$ T7 v# ]9 E' ?( L9 G
  1. /**1 y7 Z4 R5 W9 k
  2.   * @brief  在DMA模式下,向MMC卡的指定地址写入数据
    ; Q3 f1 ?# b% C& T% `
  3.   * @param  pData:指向将包含要传输的数据的缓冲区的指针
    * o& J9 ~7 |- l. V
  4.   * @param  WriteAddr:要写入数据的地址+ y& ?1 ]$ t: O3 k/ W$ Y
  5.   * @param  NumOfBlocks:要写的MMC块的数量
    ! u# ?% ]0 e9 F) I; T
  6.   * @retval MMC状态
    - S# V1 R; {4 K( S
  7.   */0 f  x9 g4 N! O* J1 k5 A* F' i+ w! B
  8. uint8_t BSP_MMC_WriteBlocks_DMA(uint8_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks). X8 U9 x( U8 T* A! X1 ~
  9. {
    % {' N" M( E5 Y; E: k* X4 ?2 x% L2 E
  10.   HAL_StatusTypeDef Status =  HAL_OK;6 M) @$ @* ^% @4 ]

  11. ) ]7 v; z) i$ v- K; G% m6 ?
  12.   /* Write block(s) in DMA transfer mode */
    4 x9 f& M+ v' p+ A4 l- n
  13.   if (HAL_MMC_WriteBlocks_DMA(&hmmc1, pData, WriteAddr, NumOfBlocks) != HAL_OK)
    ; X) ^' ^, g/ S) H* W
  14.   {
    $ M/ t, n8 R, \8 L9 z' R/ I3 x2 W
  15.     Status = HAL_ERROR;
    ( [: x$ H5 x0 E9 r
  16.   }
    ) s  w3 ~2 F6 S" v/ F9 [
  17.   return Status; 7 |$ a3 i, Z. @
  18. }
复制代码
. i6 m8 B% b# E2 b
擦除eMMC卡数据:
3 p* }. V0 A+ j6 [% B
3 v/ B( L' _2 D+ E2 V/ K" R
  1. /**( \- t% V6 q9 h. l# {9 ?
  2.   * @brief  擦除eMMC卡数据
    8 b2 Y5 I3 W) P; Y7 R! F) f0 o
  3.   * @param  无
    0 l( D- D( B3 v1 t' y  }
  4.   * @retval 无
    4 A/ B' i1 Q9 n- B
  5.   */
    + C! D8 ~% v! n/ o' k
  6. void MMC_EraseTest(void)( v  c* Y( w9 Q* f, s4 D
  7. {
      q( i! H! ^1 w
  8.    HAL_StatusTypeDef Status = HAL_OK;# C6 q7 q1 J: j4 v8 \+ t
  9.    HAL_StatusTypeDef EraseStatus = HAL_OK;" F" |8 k! g% r% g
  10.    if (Status == HAL_OK)
    ! n8 c$ I- P( L) J
  11.    {
    & T1 O- R: F) e
  12.       Status = HAL_MMC_Erase(&hmmc1, 0x00, (BLOCK_SIZE * NUMBER_OF_BLOCKS));7 X" ^+ c/ }7 ]$ |6 {: D4 ^
  13.       //等待擦除完成* O' g0 G9 R- p$ L% X
  14.       if(Wait_SDCARD_Ready() != HAL_OK)+ H: Z! [) d) z4 U# {1 j% _! F
  15.       {) N# V8 h, Y6 }0 w
  16.          EraseStatus = HAL_ERROR;
    6 s1 g) b$ L/ o5 P0 S$ n
  17.       }5 {4 ?2 V) R$ C. Z. K5 O! t  _
  18.    }
    6 j3 @  V- q! p1 z1 o) ]/ r
  19.    if(EraseStatus != HAL_OK). x6 H( U: e- z6 u7 Q1 b9 o
  20.    {    + ?8 j" R1 g- [& R4 h$ P. H
  21.       Error_Handler();3 N! `4 k* L: j. X
  22.    }/ D; b- O0 w3 e4 E
  23. }
复制代码
$ t$ U# }  M! P: D: X
eMMC卡等待擦除完成函数:
4 K2 r" d3 D2 p, U+ X0 k+ R
4 y, X! z& v. `* u3 |$ g
  1. /**; O! a" A# Z! W; Q
  2.   * @brief  eMMC卡等待擦除完成函数
    3 m- P+ O3 S) V0 g, _' b4 g. v
  3.   * @param  无: ?- y! w- i2 r' d/ y
  4.   * @retval HAL_OK:擦除成功;HAL_ERROR:擦除失败1 z( T+ K! P/ v/ g& N4 c
  5.   */
    8 J3 f- r& Z3 w2 H' J1 ?& Z
  6. static HAL_StatusTypeDef Wait_SDCARD_Ready(void)
    5 f9 K4 V) u& r2 }) n
  7. {
    5 U6 W- T6 X# O5 d. i0 c2 {
  8.    uint32_t loop = MMC_TIMEOUT;
    1 Q4 m6 O2 L' a  o' g$ o; b

  9. 9 D( `' R( T0 V: N3 N% v
  10.    /* Wait for the Erasing process is completed */
    ; S- `! ^4 O' u* G" m! a( r1 q! R
  11.    /* Verify that SD card is ready to use after the Erase */, [0 z7 B2 M" Y  ?) _1 j
  12.    while(loop > 0)3 X: G# [  ~( G: ^4 K
  13.    {
    : L7 @' y2 ]$ c* U4 S  n# d  |
  14.       loop--;
    & }1 X7 V5 q0 u: w5 J: r  [% h
  15.       if(HAL_MMC_GetCardState(&hmmc1) == HAL_MMC_CARD_TRANSFER)3 {' [) l! K/ I. ^# r0 c% R/ l
  16.       {
    2 r5 ?2 E, j; O4 V. F5 E0 ~
  17.          return HAL_OK;
    : [+ C8 w) `, o" Q
  18.       }
    9 m0 m- L$ `& H  I$ `+ g) D* J/ p5 T
  19.    }  x9 V! w! J: i. `3 U
  20.    return HAL_ERROR;, O$ y4 K/ [6 e
  21. }
复制代码

. F7 |+ R* S! Y- Y, e最近移植的eMMC卡的驱动程序,分享出来希望对各位开发者有所帮助。还移植了FATFS文件系统到eMMC驱动程序中,之后整理好再分享。
$ M3 [1 H' s9 b5 J
( m  v8 M& U5 c! V) z3 _9 X, l- x4 H5 ]0 i- r) g$ F7 j- \
收藏 评论0 发布时间:2021-12-29 23:50

举报

0个回答

所属标签

相似技术帖

官网相关资源

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