STM32L4新版HAL库SDIO(DMA)、FatFs使用教程(二)

  • 使用DMA控制SDIO

上一节已经成功使用普通SDIO模式驱动起SD卡了,但是使用FreeRtos时,CubeMX会强制要求使用DMA模式。下面介绍以DMA模式驱动SDIO的方法。

1、首先,打开CubeMX配置好的文件STM32L476RGT6_SDIO.ioc。

2、到configuration选项卡中,打开SDMMC1,再到DMA Settings选项卡,这里我们添加DMA通道。

这里有三个选择:SDMMC1、SDMMC1_RX、SDMMC1_TX。如图所示,这里要稍微说一下,不同系列的芯片这里是不同的,例如F103系列,这里就只有一个选项SDIO。F4系列有两个选项SDMMC1_RX、SDMMC1_TX,这样怎么选呢?如果是F1系列,只有一个选项,代表这个DMA是发送接收复用的。如果是F4系列,代表DMA是RX、TX分开通道的。本例中使用的是L4系列,经过测试,复用和收发分开使用均可以。

文中只介绍收发DMA通道分开使用的方式,复用方式是只选SDMMC1这一个就够了,注意的是如果是收发复用通道,每次使用DMA收发函数之前都要重新配置DMA参数并初始化,主要配置DMA数据方向内存到外设还是外设到内存,相关函数可参考第三节的SD_DMAConfigRx和SD_DMAConfigTx函数内容。

STM32L4新版HAL库SDIO(DMA)、FatFs使用教程(二)_第1张图片

配置好DMA后如图所示,注意红框中的部分。

STM32L4新版HAL库SDIO(DMA)、FatFs使用教程(二)_第2张图片

3、打开SDMMC中断。如图所示。

STM32L4新版HAL库SDIO(DMA)、FatFs使用教程(二)_第3张图片

4、打开NVIC选项卡配置中断。配置DMA通道低于SDIO的中断优先级。如图,配置DMA为2。

STM32L4新版HAL库SDIO(DMA)、FatFs使用教程(二)_第4张图片

5、生成代码,打开工程。

打开“main.c”,找到测试代码,将原来的SD_Write_Read_Test(void)函数删除,替换为DMA模式,如下代码。也可以直接替换sd_status = HAL_SD_WriteBlocks_DMA(&hsd1,(uint8_t *)Buffer_Block_Tx,WRITE_READ_ADDRESS,NUMBER_OF_BLOCKS);

sd_status = HAL_SD_ReadBlocks_DMA(&hsd1,(uint8_t *)Buffer_Block_Rx,WRITE_READ_ADDRESS,NUMBER_OF_BLOCKS);语句。

/**
  * 函数功能: SD卡读写测试
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 无
  */
void SD_Write_Read_Test(void)
{  
	int i,j = 0;
  /* 填充数据到写缓存 */
  Fill_Buffer(Buffer_Block_Tx,BLOCK_SIZE*NUMBER_OF_BLOCKS, 0x6666);
  
  /* 往SD卡写入数据 */
  sd_status = HAL_SD_WriteBlocks_DMA(&hsd1,(uint8_t *)Buffer_Block_Tx,WRITE_READ_ADDRESS,NUMBER_OF_BLOCKS);
  printf("write status:%d\r\n",sd_status);
			
  HAL_Delay(500);
  /* 从SD卡读取数据 */
  sd_status = HAL_SD_ReadBlocks_DMA(&hsd1,(uint8_t *)Buffer_Block_Rx,WRITE_READ_ADDRESS,NUMBER_OF_BLOCKS);
  printf("read status:%d\r\n",sd_status);
  
  /* 比较数据 */
  test_status = Buffercmp(Buffer_Block_Tx, Buffer_Block_Rx, BLOCK_SIZE*NUMBER_OF_BLOCKS/4);	//比较
  if(test_status == PASSED)
	{
    printf("》读写测试成功!\r\n" );
		
		for(i=0;i

6、下载测试,实验成功。

STM32L4新版HAL库SDIO(DMA)、FatFs使用教程(二)_第5张图片

 

你可能感兴趣的:(STM32开发)