【STM32+HAL】SDIO+DMA模式读写SD卡

一、准备工作

有关CUBEMX的初始化配置,参见我的另一篇blog:【STM32+HAL】CUBEMX初始化配置

二、所用工具


1、芯片: STM32F407ZGT6

2、IDE: MDK-Keil软件

3、库文件:STM32F4xxHAL库

三、实现功能

实现用SDIO+DMA读写SD卡内容

四、HAL库配置

1、开启SDIO

模式配置为1bit,开启DMA传输,开启中断

 Clock transition on which the bit capture is made (时钟跳变沿捕获数据配置):数据捕获边沿设置,可设置为上升沿/下降沿

 SDIO Clock divider bypass (时钟分频器旁路使能):使能该参数时,SDIO_CLK=SDIOCLK;否则SDIO_CLK频率由时钟分频因子决定

 SDIO Clock output enable when the bus is idle (空闲模式时钟输出使能):节能模式,此实验不使能

 SDIO hardware flow control (硬件流控):设置是否使能SDIO的硬件流控,此处不使能

 SDIOCLK clock divide factor (时钟分频因子):当不使能时钟分频器旁路时,SDIO_CLK=SDIOCLK / (2+时钟分频因子)

2、开启串口通信

至此,HAL库配置完毕 

五、Keil填写代码

1、SD.h
#ifndef __SD_H__
#define __SD_H__

#include "sdio.h"
#include "stdio.h"



void SDCard_TestRead(void);
void SDCard_TestWrite(void);
void SDCard_ShowInfo(void);
void SDCard_EraseBlocks(uint8_t BlockAddrStart,uint8_t BlockAddrEnd);

void SDCard_Write_DMA(uint8_t *TX, uint32_t BlockCount, uint32_t BlockAddr);
void SDCard_Read_DMA(uint8_t *RX,uint32_t BlockCount,uint32_t BlockAddr);


#endif

2、SD.c

篇幅有限,仅提供SD.c核心代码

/**
  * @brief  SD卡DMA写入函数
  * @param  uint8_t *TX: 写入数据数组(若要存入负数,需提前加一个数值,典型值为127,此时数据范围为-127 ~ 128)
  * @param  BlockCount:  写入的总片数
  * @param  BlockAddr:   起始写入的片数
  */
void SDCard_Write_DMA(uint8_t *TX, uint32_t BlockCount, uint32_t BlockAddr)
{
	HAL_SD_WriteBlocks_DMA(&hsd, TX, BlockAddr, BlockCount);				//存入TX数组数据到sd卡
}


/**
  * @brief  SD卡DMA读取函数
  * @param  uint8_t *RX: 读取数据数组(若已存入负数,需在打印时减一个数值,典型值为127,此时数据范围为-127 ~ 128)
  * @param  BlockCount:  读取的总片数
  * @param  BlockAddr:   起始读取的片数
  */
void SDCard_Read_DMA(uint8_t *RX, uint32_t BlockCount, uint32_t BlockAddr)
{
	HAL_SD_ReadBlocks_DMA(&hsd, RX, BlockAddr, BlockCount);					//读取sd卡数据到RX数组
}


/**
  * @brief  SD卡擦除函数
  * @param  BlockAddrStart: 擦除开始块数
  * @param  BlockAddrEnd:   擦除结束块数
  */
void SDCard_EraseBlocks(uint8_t BlockAddrStart,uint8_t BlockAddrEnd)
{
	printf("\r\n*** Erasing blocks ***\r\n");
	if(HAL_SD_Erase(&hsd, BlockAddrStart, BlockAddrEnd)==HAL_OK)		//擦除数据
		printf("Erasing blocks,OK\r\n");
	else
		printf("Erasing blocks,fail\r\n");
	HAL_SD_CardStateTypeDef cardState=HAL_SD_GetCardState(&hsd);
	printf("GetCardState()= %d\r\n", cardState);						//打印当前sd卡数据状态
	while(cardState != HAL_SD_CARD_TRANSFER)
	{
		HAL_Delay(1);
		cardState=HAL_SD_GetCardState(&hsd);
	}
	printf("Blocks %d-%d is erased.\r\n",BlockAddrStart, BlockAddrEnd);
}

3、main.c
 uint8_t rx[BLOCKSIZE],tx[BLOCKSIZE];

 /* USER CODE BEGIN 2 */
	printf("Hello World\r\n");
	HAL_Delay(500);

	SDCard_Write_DMA(tx,1,6);
	HAL_Delay(500);
	SDCard_Read_DMA(rx,1,6);
	HAL_Delay(500);
	SDCard_EraseBlocks(0,10);
  /* USER CODE END 2 */

六、巨人之肩

【STM32+HAL】利用SDIO将大量数据存入SD卡,并根据需要读出

STM32CubeMX教程27 SDIO - 读写SD卡

七、源码提供

资源【STM32+HAL】SDIO+DMA模式读写SD卡

八、更多DMA应用

详见【STM32+HAL】DMA应用

九、结语

本人能力有限,代码未必是最优解,若有可改进之处望在评论区留言,采纳有赏~

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-05-03 14:58:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-03 14:58:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-03 14:58:03       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-03 14:58:03       20 阅读

热门阅读

  1. Centos 7.6(1810) 打包Openssh8.1p1

    2024-05-03 14:58:03       15 阅读
  2. spring循环依赖解决方案

    2024-05-03 14:58:03       13 阅读
  3. Python系列一之excel的读取

    2024-05-03 14:58:03       14 阅读
  4. SQL温习笔记【SQL Server】

    2024-05-03 14:58:03       13 阅读
  5. 《中华人民共和国妇女权益保障法》解读

    2024-05-03 14:58:03       12 阅读