匿名
未登录
登录
丢石头百科
搜索
查看“STM32CubeMX系列教程17:SDMMC”的源代码
来自丢石头百科
名字空间
页面
讨论
更多
更多
页面选项
查看
查看源代码
历史
←
STM32CubeMX系列教程17:SDMMC
因为以下原因,您没有权限编辑本页:
您所请求的操作仅限于该用户组的用户使用:
用户
您可以查看与复制此页面的源代码。
<b style="font-size: 14px; widows: auto; line-height: 16.8px; background-color: inherit;">一、SDMMC简介</b> <b style="font-size: 14px; widows: auto; line-height: 16.8px; background-color: inherit;"> </b> MMC:MMC就是MultiMediaCard的缩写,即多媒体卡 SD:SD卡为Secure Digital Memory Card, 即安全数码卡 SDIO:SD Input Output 带有输入输出接口,SDIO是在SD标准上定义了一种外设接口 <b style="background-color: inherit;">SD种类</b> SD卡:<=2GB SDHC卡(SD High Capacity,大容量SD卡):4GB~32GB SDXC卡(SD eXtended Capacity):64GB~2TB。 <b style="background-color: inherit;">SD管脚图</b> 我们现在常用的是Micro SD卡,尺寸非常小的,其管脚图如下。 [[File:180308krduvvq4sy8f44q5.jpg]] [[File:180308xhrdqum2drkludrr.jpg]] SD卡的接口可以支持SD卡模式和SPI模式两种操作模式。 SD模式:采用6线制,使用CLK、CMD、DAT0~DAT3。其中CLK为时钟线,CMD为命令控制线,DAT0~DAT3为数据线,允许4线的高速数据传输; SPI模式:通用的SPI通道接口,使用CS、CLK、DI、DO进行数据通信。 SD模式的数据传输速度比SPI模块要快。我们这一章主要讲通过SD模式控制。 <b style="background-color: inherit;">SD卡相关寄存器</b> <b style="background-color: inherit;"> </b> SD卡内部有7个寄存器,其中OCR,CID,CSD和SCR寄存器保存卡的配置信息;RCA寄存器保存着通信过程中卡当前暂时分配的地址;卡状态(Card Status)和SD状态(SD Status)寄存器保存着卡的状态,这两个寄存器的内容与通信模式(SD模式或SPI模式)相关 [[File:180311kexln8i218zmbl1m.png]] <b style="background-color: inherit;">命令传输</b> <b style="background-color: inherit;"> </b> 命令是用于启动操作的令牌。命令在CMD线上以串行的方式传输。所以命令都为固定长度48位。命令路径以半双工模式运行,因此可以发送和接收和响应。 最大支持64个命令:CMD0~CMD63(其中CMD57~63是保留的),另外还有ACMD应用命令。 (本章不打算详细介绍SD各条命令的含义,而且我们编写程序的时候也不会用到,只需大概了解一下即可) [[File:180312nrlniii9yzmnffzi.png]] [[File:180314u5pmwbn5m1wpmgbw.png]] 响应是一个令牌,作为对先前接收命令的应答,从卡发送到主机,响应在CMD线上以串行方式传输。 SDMMC支持两种响应类型,48位短响应和136位长响应。两种类型均使用CRC错误检验。 [[File:180315dgwst2cemunghn2b.png]] <b style="background-color: inherit;">数据传输</b> <b style="background-color: inherit;"> </b> SD的读写操作是以块为操作对象。先发送命令开始传输,然后传输数据块,传输完数据块紧接着传输CRC检验值。最好发送停止命令停止数据传输。 [[File:180319bnlng1wzynwrggzb.png]] SD卡识别流畅图和数据传输流程图: (本章不打算详细介绍SD的状态图,编写程序的时候也不会用到,只需大概了解一下即可) [[File:180307pbjdbpdkqsj6bts6.jpg]] [[File:180306sseq4fw37y3tppyp.jpg]] <b style="background-color: inherit;">二.示例程序</b> <b style="background-color: inherit;"> </b> 复制串口printf的工程,修改文件夹名。击STM32F746I.ioc打开STM32cubeMX的工程文件重新配置,SDMMC选择四线SD模式。 [[File:180320h3p8cg3tkkif8gtw.png]] 此时SDMMC对应的管脚也被选中。 [[File:180320blk71hpaap0um7pu.png]] 配置SDMMC的时钟为48MHz(最高为48MHz)。 [[File:180322y8ep18h75a1e8v67.png]] SDMMC配置参数只有一个分频因子,此处为默认0,不修改。 [[File:180322km38mlnm2z64em2m.png]] 开启SDMMC接收和发送DMA。 [[File:180323bd5e55yzm3y1m2cy.png]] 特别注意,开启DMA后必须开启SDMMC中断,否则不能判断DMA传输是否完成,程序一直等待。且SDMMC中断的抢占优先级必须比SDMMC DMA中断高。 [[File:180324zvxnd9b99dypmyxb.png]] 生成报告以及代码,编译程序。在sdmmc.c文件中可以看到SDMMC初始化函数。在stm32f7xx_hal_sd.h头文件中可以看SD卡的操作函数。 在main.c文件前面添加变量,Status保存程序返回状态,Buffer_Tx,Buffer_Rx存储读写数据。 <syntaxhighlight lang="python"> /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ HAL_SD_ErrorTypedef Status; uint32_t Buffer_Tx[512/4], Buffer_Rx[512/4]; uint32_t i; /* USER CODE END PV */</syntaxhighlight> 程序中用的memset函数填充缓存数据,所以要添加字符头文件。 <syntaxhighlight lang="python"> /* USER CODE BEGIN Includes */ #include <string.h> /* USER CODE END Includes */</string.h></syntaxhighlight> 在main函数中添加下面应用程序。程序中首先输出SD卡信息,然后进行读写擦除块等操作。 <syntaxhighlight lang="python"> /* USER CODE BEGIN 2 */ printf(" Warning: this program may erase all the TF card data. \r\n"); printf("\r\n Initialize SD card successfully!\r\n\r\n"); printf(" SD card information! \r\n"); printf(" CardCapacity : %llu \r\n",SDCardInfo1.CardCapacity ); printf(" CardBlockSize : %d \r\n",SDCardInfo1.CardBlockSize); printf(" RCA : %d \r\n",SDCardInfo1.RCA); printf(" CardType : %d \r\n",SDCardInfo1.CardType); /*------------------- Block Write --------------------------*/ memset(Buffer_Tx,0x15,sizeof(Buffer_Tx)); if(HAL_SD_WriteBlocks_DMA(&hsd1, Buffer_Tx, 0, 512, 1) == SD_OK) { Status = HAL_SD_CheckWriteOperation(&hsd1, (uint32_t)100000000); if (Status == SD_OK) { printf("\r\n Write block successfully!\r\n"); for(i=0;i<sizeof>>2;i++) { printf("%02x:0x%08x ",i,Buffer_Tx[i]); } printf("\r\n"); } else printf("\r\n Write block fail!\r\n"); } /*------------------- Block Read --------------------------*/ if(HAL_SD_ReadBlocks_DMA(&hsd1, Buffer_Rx, 0, 512, 1) == SD_OK) { Status = HAL_SD_CheckReadOperation(&hsd1, 0xFFFF); if (Status == SD_OK) { printf("\r\n Read block successfully!\r\n"); for(i=0;i<sizeof>>2;i++) { printf("%02x:0x%08x ",i,Buffer_Rx[i]); } printf("\r\n"); } else printf("\r\n Read block fail!\r\n"); } /*------------------- Block Erase -------------------------------*/ Status = HAL_SD_Erase(&hsd1, 0, 512); if (Status == SD_OK) printf("\r\n Erase block successfully!\r\n"); else printf("\r\n Erase block fail!\r\n"); /*------------------- Block Read --------------------------*/ if(HAL_SD_ReadBlocks_DMA(&hsd1, Buffer_Rx, 0, 512, 1) == SD_OK) { Status = HAL_SD_CheckReadOperation(&hsd1, 0xFFFF); if (Status == SD_OK) { printf("\r\n Read block successfully!\r\n"); for(i=0;i<sizeof>>2;i++) { printf("%02x:0x%08x ",i,Buffer_Rx[i]); } printf("\r\n"); } else printf("\r\n Read block fail!\r\n"); } /* USER CODE END 2 */</sizeof></sizeof></sizeof></syntaxhighlight> 在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寄存器各位的含义。 <syntaxhighlight lang="python"> /** @defgroup SD_Exported_Types_Group5 SD Card information structure * @{ */ typedef struct { HAL_SD_CSDTypedef SD_csd; /*!< SD card specific data register */ HAL_SD_CIDTypedef SD_cid; /*!< SD card identification number register */ uint64_t CardCapacity; /*!< Card capacity */ uint32_t CardBlockSize; /*!< Card block size */ uint16_t RCA; /*!< SD relative card address */ uint8_t CardType; /*!< SD card type */ }HAL_SD_CardInfoTypedef;</syntaxhighlight> 程序中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里面的数据丢失,注意备份数据) [[File:180325jczciav3czr1sve1.png]]
返回至
STM32CubeMX系列教程17:SDMMC
。
导航
导航
首页
最近更改
随机页面
MediaWiki帮助
首页
首页
树莓派
主机
配件包
外壳
键鼠
电源
扩展板
显示屏
墨水屏
摄像模块
通信模块
继电器
电机驱动板
游戏机
产品分类
树莓派
Arduino
micro:bit
STM32
Espressif
WiFi模块
蓝牙模块
无线模块
LoRa模块
4G模块
GSM
GPRS
以太网
导航模块
北斗卫星
GPS
LCD
墨水屏
OLED
摄像头
USB模块
串口模块
RS232
RS485
CAN
传感器
温度模块
湿度模块
气压模块
继电器
电机模块
指纹模块
电平转换
音频模块
编程器
Wiki工具
Wiki工具
特殊页面
页面工具
页面工具
用户页面工具
更多
链入页面
相关更改
页面信息
页面日志