一、Cubemx工程配置' C# U) A& m* C8 q' Z6 P- N$ g7 m/ F$ c
1、时钟配置; |7 @7 h3 X$ @% Z5 o, ]1 q
! ~+ C4 S" Z/ R$ F
3 @: z" T1 c- l- Z+ {9 H- b4 w# M/ |) o n7 b9 r
2、SDMMC设置& f, }; q) _, w) `5 m. V, w
& a6 u- q7 \2 T" R# N! W3 H/ ^ z官方库文件建议如下:
6 P3 M e+ D7 M! S( Z" }, `- jThe SD Card frequency (SDMMC_CK) is computed as follows:
* {7 Y: M$ T5 Y) V, `* p. m+ BSDMMC_CK = SDMMCCLK / (2 * ClockDiv)) P' X3 e, w [% k
$ o; L x6 X; E! G: P+ r# U$ @具体设置如下图所示:7 J' a* V+ M5 A( N" f& n
3 M* ~, p0 k+ E9 v3 x( m
! ]/ X; o: g, q8 s; q二、实验部分
9 e% t* |4 N+ ^4 @( _1.获得TF卡信息$ Y; S) ~( C4 h T& _" z, t+ w+ r
初始化好SD后我们先获得卡信息并串口打印出来。
6 u0 a8 h% j; { v- HAL_SD_CardInfoTypeDef SDCardInfo; //SD卡信息结构体' o V; t# b! ~# U# r8 `* y
- //得到卡的信息并输出到串口1
$ e" g1 _4 p: u9 J$ } - HAL_SD_GetCardInfo(&hsd1, &SDCardInfo);//HAL_SD_CardInfoTypeDef *pCardInfo);//获取SD卡信息5 j0 D- A6 r! Q- v4 s2 [2 H
- printf("Card Type:%d\r\n",SDCardInfo.CardType); //卡类型- E- t8 Y1 x( [4 p
- printf("Card CardVersion:%d\r\n",SDCardInfo.CardVersion); //CardVersion* F8 u; F' j6 u9 I5 s1 N
- printf("Card RCA:%d\r\n",SDCardInfo.RelCardAdd); //卡相对地址) `0 {. p" v& T( ]
- printf("Card Capacity:%d MB\r\n",(u32)(SDCardInfo.LogBlockNbr)>>11); //显示容量
r* Y h( B% u* \3 D- I* J - printf("Card BlockSize:%d\r\n\r\n",SDCardInfo.LogBlockSize);//显示块大小
复制代码 ' A! N$ A4 f* k5 b" B
可以看出已经正确读出卡片信息,如下图:
& c3 ~$ I! ~5 D# T) g+ b3 e6 J' k+ m; _7 ~. T# l8 c. b' z N6 N
. F! Q2 T+ e+ V g8 @
: L2 m2 X) y0 C' W2.读、写、擦除SD卡2 p2 |" j6 e: s' w
这里需要注意的一点是,库文件官方建议如下:
* l. S6 V. \8 L8 F8 i- X- o: B/ S6 c# O
: j" ^ X9 W& _/ w
1 J0 K$ K+ a" e* y% k
操作SD卡后需要先用函数HAL_SD_GetCardState()确定一下卡的状态再进行其他操作。后期使用需要注意0 w' w1 ~( r7 X6 Z1 t
* `& z# e+ `) j7 c实验方式:按键1按下时给扇区6写入512个字节的0xbb。按键2按下时读取扇区6内的内容。按键3按下时擦除扇区6的内容。 另外,由于定义了rd_buf和buf为512个字节需要将栈设置大一点,不然程序运行会不正常。
0 m& \' P; c, E3 q( v' L
: O. G+ a! [& i4 z% F8 y9 }" j
" Z* w( _3 ^0 r- d
. U+ \, ]% `/ z' J5 j
实验代码如下(示例):- key=KEYPRESS(); //按键
, @' w" D; H$ y5 Y5 y - if(key==1)//KEY1按下了 6 g O% @+ ~% ]& C, q/ s
- {
, s; w# r5 E: O8 B- x! z e - for(sd_size=0;sd_size<512;sd_size++)buf[sd_size]=0xbb; //给扇区6写数据, _3 @) M, i/ o# {/ ~. q
- HAL_SD_WriteBlocks(&hsd1, buf, 512*6, 1, 0xff);
0 I. y8 A8 I5 ^ D - printf("\r\nWrite DATA ENDED\r\n");
; y4 w q8 @0 Q! X* w1 a8 r - } & Y2 f- e& L+ j6 z2 ?( |8 ?- ]
- if(key==2)//KEY2按下了
# o; G" n/ A9 C% U* U, q# { - {( J! \$ H$ d2 v, ~; r& P
- //读取扇区6的内容% A$ b+ R6 C m- t/ K& Q8 h* m
- if(HAL_SD_ReadBlocks(&hsd1, rd_buf, 512*6, 1, 0xff) == HAL_OK)+ x- J6 a3 }+ T% n9 k0 ?8 ]1 w- |
- {
7 w; [2 i8 L& x, ~ - printf("SECTOR 6 DATA:\r\n");+ }; n( r- _3 y B- W5 U
- for(sd_size=0;sd_size<512;sd_size++)
; s0 \- J( X% d3 N0 E9 u9 \ - printf("%x ",rd_buf[sd_size]);//打印扇区数据 & V3 v5 S4 R& O
- printf("\r\nRead DATA ENDED\r\n");
3 z8 f& q6 m8 P: \9 c8 h - }
' D) Z. f* A, k! ^9 o- f9 P" B - } $ z, e. t! G8 f
- if(key==3)//KEY3按下了 擦除扇区6的内容9 r# F; x8 P7 {: ~8 i3 n4 ?
- {2 R9 J( ]9 H( C
- HAL_SD_Erase(&hsd1,512*6,512*7);, @1 B l: d8 P. |
- printf("\r\nErase DATA ENDED\r\n");
1 p6 o9 n1 [2 X- @; I3 A0 s1 _ - }
! g- N) }6 l" [* F
复制代码 9 a& ]% S2 G0 }, u0 I( a7 q
1 R3 D7 a+ F- D& ~
3.实验现象最终可以在串口看到正确的实验现象,如下图:
1 d. S1 {! P! S1 `& h
1 D9 E' `3 p0 L+ {% m
& f$ t% p% v8 U" J
& p1 I# K& U+ `$ z2 e. T |