一、Cubemx工程配置
( t* t I: h1 K3 d- X1、时钟配置
" _4 m) Z" h0 X4 V- }# ~: s& I0 H
) D0 Z" R$ A; T0 y7 O
7 y1 @ ]" @1 f; F2 @! [( ~9 W
( t9 h5 C& @+ M2、SDMMC设置
+ M& J+ c9 K R% C5 A# ^
+ {+ I8 p2 a% ^# ?/ G, v5 U官方库文件建议如下:
9 i+ u* p; T" R9 Y7 AThe SD Card frequency (SDMMC_CK) is computed as follows:
$ ]) I% b }: k- w1 V* k6 g% {SDMMC_CK = SDMMCCLK / (2 * ClockDiv)! l. t1 J3 Q v4 E+ O
: G1 U+ E0 X9 ^4 p) r0 A4 W- o( F$ R具体设置如下图所示:# Q9 }- ~, @4 d; f! ^, o
2 p) b6 X0 D; u$ C0 ~3 L
- m% U* v" y* z4 t# q二、实验部分
7 ^5 U! a& r; C; W& {5 S4 |1.获得TF卡信息
4 f+ i0 i( X2 }' p初始化好SD后我们先获得卡信息并串口打印出来。
7 ^) S0 M4 ]& y K$ M, L- HAL_SD_CardInfoTypeDef SDCardInfo; //SD卡信息结构体: x2 ?" `! n1 T/ p# m8 s9 H
- //得到卡的信息并输出到串口13 V7 j! H% N. P6 L( o" c4 W
- HAL_SD_GetCardInfo(&hsd1, &SDCardInfo);//HAL_SD_CardInfoTypeDef *pCardInfo);//获取SD卡信息2 U7 q, o0 D& b. \ w
- printf("Card Type:%d\r\n",SDCardInfo.CardType); //卡类型
- T. O o+ ]' J1 @; Y2 ?/ u - printf("Card CardVersion:%d\r\n",SDCardInfo.CardVersion); //CardVersion
1 F3 I* ^4 _1 j0 a5 W" k - printf("Card RCA:%d\r\n",SDCardInfo.RelCardAdd); //卡相对地址$ S: z1 r( C7 e) t' `- ]
- printf("Card Capacity:%d MB\r\n",(u32)(SDCardInfo.LogBlockNbr)>>11); //显示容量
1 b# W: N& z1 T - printf("Card BlockSize:%d\r\n\r\n",SDCardInfo.LogBlockSize);//显示块大小
复制代码 4 A) M$ r6 l: ]* v" ` @- f
可以看出已经正确读出卡片信息,如下图:
& k4 E7 K( l4 o* L, q3 m. x# g4 p" y$ h" Z
. ?9 _5 c( u$ w
$ o5 W: Z" X# t; F
2.读、写、擦除SD卡
: c! y) }9 i" P这里需要注意的一点是,库文件官方建议如下:
, O/ L1 `9 }. a/ ]/ _8 _% P% h0 C0 z; K: u! g* q
5 T) i: d# H, G. t
, h7 j7 I6 i' @, @2 h: M: t
操作SD卡后需要先用函数HAL_SD_GetCardState()确定一下卡的状态再进行其他操作。后期使用需要注意
9 m- f M: |1 m5 m
) J% e1 ^. |& f( h4 G- k) f! k实验方式:按键1按下时给扇区6写入512个字节的0xbb。按键2按下时读取扇区6内的内容。按键3按下时擦除扇区6的内容。 另外,由于定义了rd_buf和buf为512个字节需要将栈设置大一点,不然程序运行会不正常。
/ z) y5 s( s2 b& @: ~& l0 q8 E
$ ?9 M; R) V, l2 l$ X7 P
2 E8 i/ k) @2 v6 V
9 i, Z9 ]2 @ ]. M: j实验代码如下(示例):- key=KEYPRESS(); //按键6 `* v3 V. p0 h6 M8 T u! V+ X6 G
- if(key==1)//KEY1按下了 - f: U9 B: v" N
- {+ N" C5 E: N; w$ L% v
- for(sd_size=0;sd_size<512;sd_size++)buf[sd_size]=0xbb; //给扇区6写数据8 x% l1 A: n$ ^- G& E, f) p
- HAL_SD_WriteBlocks(&hsd1, buf, 512*6, 1, 0xff);- }) O8 j6 T' K. N# O
- printf("\r\nWrite DATA ENDED\r\n");
% r) ?! I( ?8 P Z' H8 j- A7 r - } 6 A; e) a- c* M9 Z1 D# H4 O; [
- if(key==2)//KEY2按下了
/ |. O2 X4 {2 n9 P | - {
. ^# ~% G6 v1 v' @4 r6 g - //读取扇区6的内容
; P2 Q: \( v6 ^6 G6 @6 s - if(HAL_SD_ReadBlocks(&hsd1, rd_buf, 512*6, 1, 0xff) == HAL_OK)
( V- B: }( V6 k$ K# V' Y1 w, A - {
2 F& C( K8 C' \6 B - printf("SECTOR 6 DATA:\r\n");
3 r2 D$ h' ~9 c3 h8 \ - for(sd_size=0;sd_size<512;sd_size++)' H6 O1 G% B2 H( C+ m7 S* y- a. Q
- printf("%x ",rd_buf[sd_size]);//打印扇区数据
, E$ i8 f) y+ A7 k2 Y$ k/ M ~ - printf("\r\nRead DATA ENDED\r\n");
W8 T! V8 S% } - }
) s- I6 h% J9 B6 G - } 7 b' j! P) a O# {, f
- if(key==3)//KEY3按下了 擦除扇区6的内容9 `6 G5 T2 g! e* b! f
- {7 z$ x% l, t# [7 j
- HAL_SD_Erase(&hsd1,512*6,512*7);# a7 J6 C0 g1 K9 r" j
- printf("\r\nErase DATA ENDED\r\n");% { O+ r- N9 U8 Z
- } ) ]/ S" }* y2 K- x% }5 H1 p4 {8 v
复制代码
' [( Y$ }' U. z" l- l7 M( x1 z) p3 K1 h8 \9 v
3.实验现象最终可以在串口看到正确的实验现象,如下图:
! }7 P: A: _8 E% Y$ T+ S
- L0 X: c7 X! U( D1 s+ g& ], w9 {! F+ Y" h" s/ K
" r# ]7 C& S$ i, @1 t) h2 w. G4 S |