一、Cubemx工程配置4 M: P4 J! r6 K2 ~# f
1、时钟配置3 G2 h, n7 r! g% R, r
' T" F0 R0 S h E
' p. @% r5 S# i$ z& @
9 J* D* e( V3 p# \2、SDMMC设置
! }2 R+ F& |5 f v6 I3 ]8 K) J
6 M: N: B4 S& F; W官方库文件建议如下:
) u& u" G0 l' e XThe SD Card frequency (SDMMC_CK) is computed as follows:% l/ d( P" A# P9 m
SDMMC_CK = SDMMCCLK / (2 * ClockDiv)6 n4 n: F6 j9 j; p. A
& I) B: R5 [" n6 {) q8 ]
具体设置如下图所示:9 i6 n7 H" K# W% i3 a, p
9 R) W Z: f* x& l
. ~2 `4 I2 A, g4 `( T" Q9 Y二、实验部分$ ^; X @" P7 i$ Q% R9 {
1.获得TF卡信息
* c: i; d1 T0 W3 |初始化好SD后我们先获得卡信息并串口打印出来。( E: c2 |0 V' ~) z8 d1 X& ] h
- HAL_SD_CardInfoTypeDef SDCardInfo; //SD卡信息结构体
8 ?2 D, N' Q/ O' U3 h: } - //得到卡的信息并输出到串口1
/ h( T5 t5 w% o8 K - HAL_SD_GetCardInfo(&hsd1, &SDCardInfo);//HAL_SD_CardInfoTypeDef *pCardInfo);//获取SD卡信息
" u d) A$ `( ^$ A. m5 v. R8 k - printf("Card Type:%d\r\n",SDCardInfo.CardType); //卡类型+ l! R# w3 w. y
- printf("Card CardVersion:%d\r\n",SDCardInfo.CardVersion); //CardVersion
% c- E2 h1 K, s; U7 ` - printf("Card RCA:%d\r\n",SDCardInfo.RelCardAdd); //卡相对地址
+ ~6 P: i" @0 o, o6 Q - printf("Card Capacity:%d MB\r\n",(u32)(SDCardInfo.LogBlockNbr)>>11); //显示容量
5 l. `2 l8 E. r: p - printf("Card BlockSize:%d\r\n\r\n",SDCardInfo.LogBlockSize);//显示块大小
复制代码
$ q4 I, z+ G2 a) X4 ~& \可以看出已经正确读出卡片信息,如下图:5 \/ A3 F3 h8 n
$ e( V2 o6 W X; k' Q, @
. `8 a8 A4 e! ]0 G! H: Q! W! z( @* I" |' ^# o% D
2.读、写、擦除SD卡
! N0 B! ^+ ^% P1 x& L这里需要注意的一点是,库文件官方建议如下:
# W' ]8 R3 @) e9 Y5 s W, y8 l7 W1 h- b8 Q8 D. R
5 }5 f1 h) [/ a& o3 C, G
% T8 n1 a# I5 K' T1 M
操作SD卡后需要先用函数HAL_SD_GetCardState()确定一下卡的状态再进行其他操作。后期使用需要注意
$ u* X+ i# T1 a; L
: P6 {9 s# W/ ^2 B实验方式:按键1按下时给扇区6写入512个字节的0xbb。按键2按下时读取扇区6内的内容。按键3按下时擦除扇区6的内容。 另外,由于定义了rd_buf和buf为512个字节需要将栈设置大一点,不然程序运行会不正常。( t5 n( ?: i# @3 [
: V, m! S% s; c* b3 I
$ e# G8 _4 A! z- f0 y) z( D
0 G: s) b% n& x& v; d实验代码如下(示例):- key=KEYPRESS(); //按键
+ S; v; \/ i% K4 B - if(key==1)//KEY1按下了 ' o+ j& l) Y7 n4 `% i$ m0 ?5 i8 L% k
- {
\, A1 k* f0 A! x' Y: R# y) m - for(sd_size=0;sd_size<512;sd_size++)buf[sd_size]=0xbb; //给扇区6写数据
* V7 [9 |4 _. z: O$ n* G+ ^# Q5 o. r - HAL_SD_WriteBlocks(&hsd1, buf, 512*6, 1, 0xff);4 Z! ?1 v$ c3 K+ k0 c
- printf("\r\nWrite DATA ENDED\r\n");3 V; T# B7 \! ~3 }/ M7 h2 w
- } 8 `9 M- J' I# r0 \, }# l
- if(key==2)//KEY2按下了 " L& P5 v1 a/ r; [* Y# h, A
- {
" ~" U( @% o+ Y+ b( } - //读取扇区6的内容
4 ^3 ]* z3 l) t2 O: T0 A - if(HAL_SD_ReadBlocks(&hsd1, rd_buf, 512*6, 1, 0xff) == HAL_OK)4 [# t! I3 j4 K0 W1 t% {
- { ( g9 r- q8 Z h
- printf("SECTOR 6 DATA:\r\n");
. \' s" C* q7 }1 |$ W9 ]" v+ P - for(sd_size=0;sd_size<512;sd_size++). g+ W$ k2 P9 u" E' L4 ]9 V' H
- printf("%x ",rd_buf[sd_size]);//打印扇区数据
7 ?9 P( H0 v8 U0 j( N6 [8 E: ~+ q - printf("\r\nRead DATA ENDED\r\n");) y7 z% }" d* k4 x! C; J& D! U
- }
3 l+ Y8 [, G" _) [6 P - } 1 e ]& z+ I2 \, }9 U+ j- h; H
- if(key==3)//KEY3按下了 擦除扇区6的内容
6 b v \; d/ S! v - {# W/ B" k# D" N! N% F( v
- HAL_SD_Erase(&hsd1,512*6,512*7);
0 _2 t% V5 I: Y! c - printf("\r\nErase DATA ENDED\r\n");
6 P+ f; r$ {; c& W& L. F( J6 ` - } $ M* H- ^3 W2 H( I- m3 q" b8 l
复制代码
- }9 h6 d* _; M5 Z, Z' L. i2 A* y, ^% u, J* g( ^
3.实验现象最终可以在串口看到正确的实验现象,如下图:
) l2 L+ v3 r9 ~ g: m' U+ {
0 F/ a5 M. W& q) q7 l4 I: t
* O! Y7 w' i8 s
- p* g( u# k g4 k) E; q
|