完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
file:///C:/Users/Administrator/AppData/Local/YNote/data/qq05E2D92FFCC85611A0CBEB4448FFA27E/0cfd60382960424e80828f6733646a8d/4509229126921501616.jpg SD卡的接口可以支持SD卡模式和SPI模式两种操作模式。 SD模式:采用6线制,使用CLK、CMD、DAT0~DAT3。其中CLK为时钟线,CMD为命令控制线,DAT0~DAT3为数据线,允许4线的高速数据传输; SPI模式:通用的SPI通道接口,使用CS、CLK、DI、DO进行数据通信。 SD模式的数据传输速度比SPI模块要快。我们这一章主要讲通过SD模式控制。 |
|
|
|
|
|
SD卡相关寄存器
SD卡内部有7个寄存器,其中OCR,CID,CSD和SCR寄存器保存卡的配置信息;RCA寄存器保存着通信过程中卡当前暂时分配的地址;卡状态(Card Status)和SD状态(SD Status)寄存器保存着卡的状态,这两个寄存器的内容与通信模式(SD模式或SPI模式)相关 file:///C:/Users/Administrator/AppData/Local/YNote/data/qq05E2D92FFCC85611A0CBEB4448FFA27E/bd0076513fab45f584d5cfe6d57d7b18/clipboard.png |
|
|
|
|
|
命令传输
命令是用于启动操作的令牌。命令在CMD线上以串行的方式传输。所以命令都为固定长度48位。命令路径以半双工模式运行,因此可以发送和接收和响应。 最大支持64个命令:CMD0~CMD63(其中CMD57~63是保留的),另外还有ACMD应用命令。 (本章不打算详细介绍SD各条命令的含义,而且我们编写程序的时候也不会用到,只需大概了解一下即可) |
|
|
|
|
|
数据传输
SD的读写操作是以块为操作对象。先发送命令开始传输,然后传输数据块,传输完数据块紧接着传输CRC检验值。最好发送停止命令停止数据传输。 |
|
|
|
|
|
二.示例程序
复制串口printf的工程,修改文件夹名。击STM32F746I.ioc打开STM32cubeMX的工程文件重新配置,SDMMC选择四线SD模式。 file:///C:/Users/Administrator/AppData/Local/YNote/data/qq05E2D92FFCC85611A0CBEB4448FFA27E/c01e631565464c37a353610ea570e739/clipboard.png 此时SDMMC对应的管脚也被选中。 |
|
|
|
|
|
SDMMC配置参数只有一个分频因子,此处为默认0,不修改。
file:///C:/Users/Administrator/AppData/Local/YNote/data/qq05E2D92FFCC85611A0CBEB4448FFA27E/c11491d01ef7493cbf9ce124ddb3c0c7/clipboard.png |
|
|
|
|
|
特别注意,开启DMA后必须开启SDMMC中断,否则不能判断DMA传输是否完成,程序一直等待。且SDMMC中断的抢占优先级必须比SDMMC DMA中断高。
file:///C:/Users/Administrator/AppData/Local/YNote/data/qq05E2D92FFCC85611A0CBEB4448FFA27E/48c569cc93c0400d8c8e55652169c9ee/clipboard.png |
|
|
|
|
|
[backcolor=initial !important]生成报告以及代码,编译程序。在sdmmc.c文件中可以看到SDMMC初始化函数。在stm32f7xx_hal_sd.h头文件中可以看SD卡的操作函数。 [backcolor=initial !important] [backcolor=initial !important]在main.c文件前面添加变量,Status保存程序返回状态,Buffer_Tx,Buffer_Rx存储读写数据。 [backcolor=initial !important] [backcolor=initial !important]1 [backcolor=initial !important]/* USER CODE BEGIN PV */ [backcolor=initial !important]2 [backcolor=initial !important]/* Private variables ---------------------------------------------------------*/ [backcolor=initial !important]3 [backcolor=initial !important]HAL_SD_ErrorTypedef Status; [backcolor=initial !important]4 [backcolor=initial !important]uint32_t Buffer_Tx[512/4], Buffer_Rx[512/4]; [backcolor=initial !important]5 [backcolor=initial !important]uint32_t i; [backcolor=initial !important]6 [backcolor=initial !important]/* USER CODE END PV */ [backcolor=initial !important] [backcolor=initial !important]程序中用的memset函数填充缓存数据,所以要添加字符头文件。 [backcolor=initial !important] [backcolor=initial !important]1 [backcolor=initial !important]/* USER CODE BEGIN Includes */ [backcolor=initial !important]2 [backcolor=initial !important]#include [backcolor=initial !important]3 [backcolor=initial !important]/* USER CODE END Includes */ [backcolor=initial !important] [backcolor=initial !important] [backcolor=initial !important]在main函数中添加下面应用程序。程序中首先输出SD卡信息,然后进行读写擦除块等操作。 [backcolor=initial !important] [backcolor=initial !important]01 [backcolor=initial !important]/* USER CODE BEGIN 2 */ [backcolor=initial !important]02 [backcolor=initial !important] printf(" Warning: this program may erase all the TF card data. rn"); [backcolor=initial !important]03 [backcolor=initial !important] [backcolor=initial !important]04 [backcolor=initial !important] printf("rn Initialize SD card successfully!rnrn"); [backcolor=initial !important]05 [backcolor=initial !important] printf(" SD card information! rn"); [backcolor=initial !important]06 [backcolor=initial !important] printf(" CardCapacity : %llu rn",SDCardInfo1.CardCapacity ); [backcolor=initial !important]07 [backcolor=initial !important] printf(" CardBlockSize : %d rn",SDCardInfo1.CardBlockSize); [backcolor=initial !important]08 [backcolor=initial !important] printf(" RCA : %d rn",SDCardInfo1.RCA); [backcolor=initial !important]09 [backcolor=initial !important] printf(" CardType : %d rn",SDCardInfo1.CardType); [backcolor=initial !important]10 [backcolor=initial !important] [backcolor=initial !important]11 [backcolor=initial !important] /*------------------- Block Write --------------------------*/ [backcolor=initial !important]12 [backcolor=initial !important] memset(Buffer_Tx,0x15,sizeof(Buffer_Tx)); [backcolor=initial !important]13 [backcolor=initial !important] if(HAL_SD_WriteBlocks_DMA(&hsd1, Buffer_Tx, 0, 512, 1) == SD_OK) [backcolor=initial !important]14 [backcolor=initial !important] { [backcolor=initial !important]15 [backcolor=initial !important] Status = HAL_SD_CheckWriteOperation(&hsd1, (uint32_t)100000000); [backcolor=initial !important]16 [backcolor=initial !important] if (Status == SD_OK) [backcolor=initial !important]17 [backcolor=initial !important] { [backcolor=initial !important]18 [backcolor=initial !important] printf("rn Write block successfully!rn"); [backcolor=initial !important]19 [backcolor=initial !important] for(i=0;i [backcolor=initial !important]20 [backcolor=initial !important] { [backcolor=initial !important]21 [backcolor=initial !important] printf("%02x:0x%08x ",i,Buffer_Tx); [backcolor=initial !important]22 [backcolor=initial !important] } [backcolor=initial !important]23 [backcolor=initial !important] printf("rn"); [backcolor=initial !important]24 [backcolor=initial !important] } [backcolor=initial !important]25 [backcolor=initial !important] else [backcolor=initial !important]26 [backcolor=initial !important] printf("rn Write block fail!rn"); [backcolor=initial !important]27 [backcolor=initial !important] } [backcolor=initial !important]28 [backcolor=initial !important] [backcolor=initial !important]29 [backcolor=initial !important] /*------------------- Block Read --------------------------*/ [backcolor=initial !important]30 [backcolor=initial !important] if(HAL_SD_ReadBlocks_DMA(&hsd1, Buffer_Rx, 0, 512, 1) == SD_OK) [backcolor=initial !important]31 [backcolor=initial !important] { [backcolor=initial !important]32 [backcolor=initial !important] Status = HAL_SD_CheckReadOperation(&hsd1, 0xFFFF); [backcolor=initial !important]33 [backcolor=initial !important] if (Status == SD_OK) [backcolor=initial !important]34 [backcolor=initial !important] { [backcolor=initial !important]35 [backcolor=initial !important] printf("rn Read block successfully!rn"); [backcolor=initial !important]36 [backcolor=initial !important] for(i=0;i [backcolor=initial !important]37 [backcolor=initial !important] { [backcolor=initial !important]38 [backcolor=initial !important] printf("%02x:0x%08x ",i,Buffer_Rx); [backcolor=initial !important]39 [backcolor=initial !important] } [backcolor=initial !important]40 [backcolor=initial !important] printf("rn"); [backcolor=initial !important]41 [backcolor=initial !important] } [backcolor=initial !important]42 [backcolor=initial !important] else [backcolor=initial !important]43 [backcolor=initial !important] printf("rn Read block fail!rn"); [backcolor=initial !important]44 [backcolor=initial !important] } [backcolor=initial !important]45 [backcolor=initial !important] [backcolor=initial !important]46 [backcolor=initial !important] /*------------------- Block Erase -------------------------------*/ [backcolor=initial !important]47 [backcolor=initial !important] Status = HAL_SD_Erase(&hsd1, 0, 512); [backcolor=initial !important]48 [backcolor=initial !important] if (Status == SD_OK) [backcolor=initial !important]49 [backcolor=initial !important] printf("rn Erase block successfully!rn"); [backcolor=initial !important]50 [backcolor=initial !important] else [backcolor=initial !important]51 [backcolor=initial !important] printf("rn Erase block fail!rn"); [backcolor=initial !important]52 [backcolor=initial !important] [backcolor=initial !important]53 [backcolor=initial !important] /*------------------- Block Read --------------------------*/ [backcolor=initial !important]54 [backcolor=initial !important] if(HAL_SD_ReadBlocks_DMA(&hsd1, Buffer_Rx, 0, 512, 1) == SD_OK) [backcolor=initial !important]55 [backcolor=initial !important] { [backcolor=initial !important]56 [backcolor=initial !important] Status = HAL_SD_CheckReadOperation(&hsd1, 0xFFFF); [backcolor=initial !important]57 [backcolor=initial !important] if (Status == SD_OK) [backcolor=initial !important]58 [backcolor=initial !important] { [backcolor=initial !important]59 [backcolor=initial !important] printf("rn Read block successfully!rn"); [backcolor=initial !important]60 [backcolor=initial !important] for(i=0;i [backcolor=initial !important]61 [backcolor=initial !important] { [backcolor=initial !important]62 [backcolor=initial !important] printf("%02x:0x%08x ",i,Buffer_Rx); [backcolor=initial !important]63 [backcolor=initial !important] } [backcolor=initial !important]64 [backcolor=initial !important] printf("rn"); [backcolor=initial !important]65 [backcolor=initial !important] } [backcolor=initial !important]66 [backcolor=initial !important] else [backcolor=initial !important]67 [backcolor=initial !important] printf("rn Read block fail!rn"); [backcolor=initial !important]68 [backcolor=initial !important] } [backcolor=initial !important]69 [backcolor=initial !important] /* USER CODE END 2 */ |
|
|
|
|
|
在SDMMC接口初始化函数MX_SDMMC1_SD_Init()中,调用HAL_SD_Init(&hsd1, &SDCardInfo1)函数初始SD卡(有兴趣的少年可以对比上面的状态图看看SD卡的初始化程序),将SD卡的信息保存在SDCardInfo1结构体中。
SDCardInfo1结构体类型为HAL_SD_CardInfoTypedef,在stm32f7xx_hal_sd.h中可以看到结构体的成员变量。 其中SD_csd,SD_cid分别对应SD卡的CSD,CID寄存器。CardCapacity为SD卡容量大小,CardBlockSize为SD卡块大小,CardType为SD类型。查看HAL_SD_CSDTypedef,HAL_SD_CIDTypedef两个类型可以知道CSD,CID寄存器各位的含义。 01 /** @defgroup SD_Exported_Types_Group5 SD Card information structure 02 * @{ 03 */ 04 typedef struct 05 { 06 HAL_SD_CSDTypedef SD_csd; /*!< SD card specific data register */ 07 HAL_SD_CIDTypedef SD_cid; /*!< SD card identification number register */ 08 uint64_t CardCapacity; /*!< Card capacity */ 09 uint32_t CardBlockSize; /*!< Card block size */ 10 uint16_t RCA; /*!< SD relative card address */ 11 uint8_t CardType; /*!< SD card type */ 12 }HAL_SD_CardInfoTypedef; 程序中HAL_SD_WriteBlocks_DMA()和HAL_SD_ReadBlocks_DMA()读写块,注意调用这函数后面要调用HAL_SD_CheckWriteOperation()/HAL_SD_CheckReadOperation()判断传输是否完成。同样也可以用HAL_SD_WriteBlocks()/HAL_SD_ReadBlocks()通过轮询的方式读写块。HAL_SD_Erase()为擦除块操作。 |
|
|
|
|
|
译程序并下载到开发板。将Micro SD卡插入Micro SD Storage Board中,再插到Open746I-C开发的SDMMC接口中。打开串口调试助手,设置波特率为115200,按下复位串口助手上面会显示如下信息。(注意:此程序会损坏SD卡里面的文件系统,导致SD里面的数据丢失,注意备份数据)
|
|
|
|
|
|
609 浏览 0 评论
【每周推荐】采用11代Intel CPU,基于youyeetoo X1开发板搭建少儿AI智能STEAM积木平台
855 浏览 0 评论
2574 浏览 2 评论
【youyeetoo X1 windows 开发板体验】+ 影音处理和AI模型移植
2274 浏览 5 评论
I.MX6ULL-飞凌 ElfBoard ELF1板卡- 移植zbar的方法
1708 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
5795 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-4-25 07:04 , Processed in 0.480549 second(s), Total 79, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号