HAL库的STM32单片机SDIO,FATFS读取SDmini卡

本文基于STM32H750核心,学习使用SDMMC1(SDIO)外设,用CubeMX创建HAL库工程,用SDIO读取TF卡,用FATFS文件系统读出里面的文件。

文末有工程链接。

一、CubeMX创建工程

这里跳过H750时钟的配置,主要是SDMMC1(SDIO)的配置和FATFS文件系统配置。因为CubeMX自带了FATFS,所以不需要去网上拷贝。

 

 

 

再配置一个串口,方便打印信息查看状态。

FAT需要选择一个检测SDIO插入的GPIO引脚,可以任意选择一个GPIO脚,然后在代码里把检测的代码注释掉,也可以不选择GPIO引脚,但是生成工程时会警告。

二、代码

在keil里选择Use microlib,然后做printf的重定向。

int fputc(int ch , FILE*f)
{
  HAL_UART_Transmit(&huart1 , (uint8_t *)&ch , 1 , 0xffff);
  return ch;
}

1.f_mount挂载

FRESULT f_mount (

    FATFS* fs,          /* Pointer to the file system object (NULL:unmount)*/

    const TCHAR* path,  /* Logical drive number to be mounted/unmounted */

    BYTE opt            /* Mode option 0:Do not mount (delayed mount), 1:Mount immediately */

)

@fs:文件系统指针

@path:挂载路径

@ opt:操作,0-卸载  1-挂载

2.f_open()打开文件

FRESULT f_open (
	FIL* fp,			/* Pointer to the blank file object */
	const TCHAR* path,	/* Pointer to the file name */
	BYTE mode			/* Access mode and file open mode flags */
)

@fp:文件指针

@path:文件路径

@mode:方式

#define	FA_READ				0x01
#define	FA_WRITE			0x02
#define	FA_OPEN_EXISTING	0x00
#define	FA_CREATE_NEW		0x04
#define	FA_CREATE_ALWAYS	0x08
#define	FA_OPEN_ALWAYS		0x10
#define	FA_OPEN_APPEND		0x30

3.f_read()和f_write()

FRESULT f_write (
	FIL* fp,			/* Pointer to the file object */
	const void* buff,	/* Pointer to the data to be written */
	UINT btw,			/* Number of bytes to write */
	UINT* bw			/* Pointer to number of bytes written */
)

@fp:文件指针

@buff:写入的字节

@btw:要写入的长度(这个是我们需要写入的长度)

@bw:写入了的长度(这里会返回一个它实际写入的长度,通过比较这两个长度可以知道写入是否成功)

FRESULT f_read (
	FIL* fp, 	/* Pointer to the file object */
	void* buff,	/* Pointer to data buffer */
	UINT btr,	/* Number of bytes to read */
	UINT* br	/* Pointer to number of bytes read */
)

@btr:要读出的字节长度

@br:实际读出的字节长度

三、测试

//在全局变量中定义:
FRESULT f_res;      /* 操作结果 */
FATFS   fs;         /* FAT句柄 */
FIL     file;       /* 文件句柄 */
uint16_t bw;        /* 写入字节长度 */

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SDMMC1_SD_Init();
  MX_USART1_UART_Init();
  MX_FATFS_Init();
  /* USER CODE BEGIN 2 */
  printf("初始化成功\n");
  f_res = f_mount(&fs , "0:" , 1);    //0:不挂载  1:挂载
  if(f_res != FR_OK)
  {
    printf("挂载失败\n");
  }

  f_res = f_open(&file , "0:test.txt" , FA_OPEN_ALWAYS|FA_WRITE); //如果文件存在则打开,如果文件不存在则创建并打开
  if(f_res != FR_OK)
  {
    printf("打开文件失败\n");
  }

  f_res = f_write(&file , "test hello world" , 16 , &bw);
  if(f_res != FR_OK)
  {
    printf("写入失败\n");
  }

  f_res = f_close(&file);
  if(f_res != FR_OK)
  {
    printf("关闭文件失败\n");
  }

  f_res = f_mount(&fs , "0:" , 0);    //0:不挂载  1:挂载
  if(f_res != FR_OK)
  {
    printf("卸载失败\n");
  }
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

 从读卡器中可以读出,测试成功。

注意:文件指针、系统指针要放在全局变量,不要放在main函数里,不然跑不起,没搞明报什么原因。

测试工程下载:提取码:ebo7

### STM32 SDIO HAL 使用教程 #### 初始化过程 为了使用 STM32SDIO 接口来读写 SD ,初始化阶段至关重要。通过 `HAL_SD_Init()` 函数完成 SD 设备的初始化工作[^1]。 ```c // 定义SD_HandleTypeDef句柄结构体变量 SD_HandleTypeDef hsd; void MX_SDIO_SD_Init(void) { /* Initialize the global state of the SD driver */ hsd.Instance = SDIO; // 配置参数 hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING; hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE; hsd.Init.BusWide = SDIO_BUS_WIDE_1B; hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE; hsd.Init.Transceiver = SDIO_TRANSCEIVER_ENABLE; } ``` #### 数据传输功能实现 数据传输可以通过 DMA 或者中断方式触发。这里展示如何利用 DMA 进行批量的数据传送: ```c uint8_t buffer[512]; /* 从指定地址开始向SD发送数据 */ if (HAL_OK != HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t*)buffer, 0, 1)) { Error_Handler(); } /* 从SD接收数据至指定内存位置 */ if (HAL_OK != HAL_SD_ReadBlocks_DMA(&hsd, (uint8_t*)buffer, 0, 1)) { Error_Handler(); } ``` 上述代码片段展示了基本的操作流程,实际应用中还需要处理错误情况以及等待DMA传输结束等细节问题[^2]。 #### 错误处理机制 当发生异常状况时,应该调用自定义的错误处理器来进行相应的恢复动作或者提示用户采取措施: ```c void Error_Handler(void) { while(1); // 死循环挂起程序执行 } ``` 此部分可以根据具体应用场景设计更加复杂的逻辑以便更好地应对各种可能遇到的问题[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天师电通电容爆破工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值