硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1693|回复: 3
收起左侧

F429 通过SDIO DMA方式无法正常读写SD卡

[复制链接]

5

主题

13

回帖

28

积分

新手上路

积分
28
发表于 2022-3-6 22:18:58 | 显示全部楼层 |阅读模式
工程是通过cubemax 生成   通过按键1控制轮询方式读写SD卡正常   但通过按键2控制 “DMA方式无法正常读写”@硬汉  能不能帮忙看看问题出在哪  感谢!
初始化部分代码

  1. /**
  2.   ******************************************************************************
  3.   * @file    sdio.c
  4.   * @brief   This file provides code for the configuration
  5.   *          of the SDIO instances.
  6.   ******************************************************************************
  7.   * @attention
  8.   *
  9.   * <h2><center>&#169; Copyright (c) 2022 STMicroelectronics.
  10.   * All rights reserved.</center></h2>
  11.   *
  12.   * This software component is licensed by ST under BSD 3-Clause license,
  13.   * the "License"; You may not use this file except in compliance with the
  14.   * License. You may obtain a copy of the License at:
  15.   *                        opensource.org/licenses/BSD-3-Clause
  16.   *
  17.   ******************************************************************************
  18.   */

  19. /* Includes ------------------------------------------------------------------*/
  20. #include "sdio.h"

  21. /* USER CODE BEGIN 0 */

  22. /* USER CODE END 0 */

  23. SD_HandleTypeDef hsd;
  24. DMA_HandleTypeDef hdma_sdio_rx;
  25. DMA_HandleTypeDef hdma_sdio_tx;

  26. /* SDIO init function */

  27. void MX_SDIO_SD_Init(void)
  28. {

  29.   hsd.Instance = SDIO;
  30.   hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
  31.   hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
  32.   hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
  33.   hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
  34.   hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
  35.   hsd.Init.ClockDiv = 0;
  36.   if (HAL_SD_Init(&hsd) != HAL_OK)
  37.   {
  38.     Error_Handler();
  39.   }
  40.   if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)
  41.   {
  42.     Error_Handler();
  43.   }

  44. }

  45. void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)
  46. {

  47.   GPIO_InitTypeDef GPIO_InitStruct = {0};
  48.   if(sdHandle->Instance==SDIO)
  49.   {
  50.   /* USER CODE BEGIN SDIO_MspInit 0 */

  51.   /* USER CODE END SDIO_MspInit 0 */
  52.     /* SDIO clock enable */
  53.     __HAL_RCC_SDIO_CLK_ENABLE();

  54.     __HAL_RCC_GPIOC_CLK_ENABLE();
  55.     __HAL_RCC_GPIOD_CLK_ENABLE();
  56.     /**SDIO GPIO Configuration
  57.     PC8     ------> SDIO_D0
  58.     PC9     ------> SDIO_D1
  59.     PC10     ------> SDIO_D2
  60.     PC11     ------> SDIO_D3
  61.     PC12     ------> SDIO_CK
  62.     PD2     ------> SDIO_CMD
  63.     */
  64.     GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
  65.                           |GPIO_PIN_12;
  66.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  67.     GPIO_InitStruct.Pull = GPIO_PULLUP;
  68.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  69.     GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
  70.     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  71.     GPIO_InitStruct.Pin = GPIO_PIN_2;
  72.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  73.     GPIO_InitStruct.Pull = GPIO_PULLUP;
  74.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  75.     GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
  76.     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  77.     /* SDIO DMA Init */
  78.     /* SDIO_RX Init */
  79.     hdma_sdio_rx.Instance = DMA2_Stream3;
  80.     hdma_sdio_rx.Init.Channel = DMA_CHANNEL_4;
  81.     hdma_sdio_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
  82.     hdma_sdio_rx.Init.PeriphInc = DMA_PINC_DISABLE;
  83.     hdma_sdio_rx.Init.MemInc = DMA_MINC_ENABLE;
  84.     hdma_sdio_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  85.     hdma_sdio_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  86.     hdma_sdio_rx.Init.Mode = DMA_PFCTRL;
  87.     hdma_sdio_rx.Init.Priority = DMA_PRIORITY_LOW;
  88.     hdma_sdio_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
  89.     hdma_sdio_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
  90.     hdma_sdio_rx.Init.MemBurst = DMA_MBURST_INC4;
  91.     hdma_sdio_rx.Init.PeriphBurst = DMA_PBURST_INC4;
  92.     if (HAL_DMA_Init(&hdma_sdio_rx) != HAL_OK)
  93.     {
  94.       Error_Handler();
  95.     }

  96.     __HAL_LINKDMA(sdHandle,hdmarx,hdma_sdio_rx);

  97.     /* SDIO_TX Init */
  98.     hdma_sdio_tx.Instance = DMA2_Stream6;
  99.     hdma_sdio_tx.Init.Channel = DMA_CHANNEL_4;
  100.     hdma_sdio_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
  101.     hdma_sdio_tx.Init.PeriphInc = DMA_PINC_DISABLE;
  102.     hdma_sdio_tx.Init.MemInc = DMA_MINC_ENABLE;
  103.     hdma_sdio_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  104.     hdma_sdio_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  105.     hdma_sdio_tx.Init.Mode = DMA_PFCTRL;
  106.     hdma_sdio_tx.Init.Priority = DMA_PRIORITY_LOW;
  107.     hdma_sdio_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
  108.     hdma_sdio_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
  109.     hdma_sdio_tx.Init.MemBurst = DMA_MBURST_INC4;
  110.     hdma_sdio_tx.Init.PeriphBurst = DMA_PBURST_INC4;
  111.     if (HAL_DMA_Init(&hdma_sdio_tx) != HAL_OK)
  112.     {
  113.       Error_Handler();
  114.     }

  115.     __HAL_LINKDMA(sdHandle,hdmatx,hdma_sdio_tx);

  116.     /* SDIO interrupt Init */
  117.     HAL_NVIC_SetPriority(SDIO_IRQn, 0, 0);
  118.     HAL_NVIC_EnableIRQ(SDIO_IRQn);
  119.   /* USER CODE BEGIN SDIO_MspInit 1 */

  120.   /* USER CODE END SDIO_MspInit 1 */
  121.   }
  122. }

  123. void HAL_SD_MspDeInit(SD_HandleTypeDef* sdHandle)
  124. {

  125.   if(sdHandle->Instance==SDIO)
  126.   {
  127.   /* USER CODE BEGIN SDIO_MspDeInit 0 */

  128.   /* USER CODE END SDIO_MspDeInit 0 */
  129.     /* Peripheral clock disable */
  130.     __HAL_RCC_SDIO_CLK_DISABLE();

  131.     /**SDIO GPIO Configuration
  132.     PC8     ------> SDIO_D0
  133.     PC9     ------> SDIO_D1
  134.     PC10     ------> SDIO_D2
  135.     PC11     ------> SDIO_D3
  136.     PC12     ------> SDIO_CK
  137.     PD2     ------> SDIO_CMD
  138.     */
  139.     HAL_GPIO_DeInit(GPIOC, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
  140.                           |GPIO_PIN_12);

  141.     HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2);

  142.     /* SDIO DMA DeInit */
  143.     HAL_DMA_DeInit(sdHandle->hdmarx);
  144.     HAL_DMA_DeInit(sdHandle->hdmatx);

  145.     /* SDIO interrupt Deinit */
  146.     HAL_NVIC_DisableIRQ(SDIO_IRQn);
  147.   /* USER CODE BEGIN SDIO_MspDeInit 1 */

  148.   /* USER CODE END SDIO_MspDeInit 1 */
  149.   }
  150. }

  151. /* USER CODE BEGIN 1 */

  152. /* USER CODE END 1 */

  153. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码



用户部分代码
  1. #include "user_sdcard.h"
  2. #include "sdio.h"
  3. #include <string.h>

  4. extern uint8_t KEY_Value; //按键值

  5. HAL_StatusTypeDef Status;
  6. HAL_SD_CardCIDTypeDef SDCard_CID;
  7. HAL_SD_CardInfoTypeDef SDCardInfo;
  8. __align(4) uint8_t SDBuffer_Tx[512], SDBuffer_Rx[512];
  9. uint32_t i;
  10. uint64_t CardCap;        //SD容量大小

  11. #define BLOCK_START_ADDR         0  //块起始地址
  12. #define NUM_OF_BLOCKS            1  //块数量

  13. //打印SD卡信息
  14. void SDCARD_Info(void)
  15. {
  16.                 HAL_SD_GetCardInfo(&hsd,&SDCardInfo);
  17.                 HAL_SD_GetCardCID(&hsd,&SDCard_CID);
  18.                 CardCap=(uint64_t)(SDCardInfo.LogBlockNbr)*(uint64_t)(SDCardInfo.LogBlockSize);        //&#188;&#198;&#203;&#227;SD&#191;¨′óD&#161; &#194;&#223;&#188;-&#191;é&#184;&#246;êy*&#191;é′óD&#161;
  19.                 printf(" SD card information! \r\n");        
  20.                 printf("Card ManufacturerID:%d\r\n",SDCard_CID.ManufacturerID);                    //&#214;&#198;&#212;ìéìID
  21.                 printf("Card CardType:%d\r\n",SDCardInfo.CardType);                                //SD&#191;¨ààDí
  22.                 printf("Card RCA:%d\r\n",SDCardInfo.RelCardAdd);                                                                      //&#191;¨&#207;à&#182;&#212;μ&#216;&#214;·
  23.                 printf("LogBlockNbr:%d \r\n",(uint32_t)(SDCardInfo.LogBlockNbr));                        //&#194;&#223;&#188;-&#191;é&#184;&#246;êy
  24.                 printf("LogBlockSize:%d \r\n",(uint32_t)(SDCardInfo.LogBlockSize));                //&#194;&#223;&#188;-&#191;é′óD&#161;
  25.                 printf("Card Capacity:%d MB\r\n",(uint32_t)(CardCap>>20));                                                //èYá&#191;Mb
  26.                 printf("Card BlockSize:%d\r\n\r\n",SDCardInfo.BlockSize);                                                  //&#191;é′óD&#161;
  27. }

  28. void SDCARD_Task(void)
  29. {
  30. /******************************************轮询方式**************************************/        
  31.         //按键1单击读取
  32.         if(KEY_Value == 0x01){
  33.                 KEY_Value=0;
  34.                         printf("------------------- Read SD card block data ------------------\r\n");
  35.                         if(HAL_SD_ReadBlocks(&hsd, SDBuffer_Rx, BLOCK_START_ADDR, NUM_OF_BLOCKS, 10) == HAL_OK)
  36.                         {
  37.                                 while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
  38.                                 {
  39.                                 }
  40.                                 printf("\r\nRead Block Success!\r\n");
  41.                                 for(i = 0; i < sizeof(SDBuffer_Rx); i++)
  42.                                 {
  43.                                         printf("%03d:0x%02x ", i, SDBuffer_Rx[i]);
  44.                                 }
  45.                                 printf("\r\n");
  46.                         }
  47.                         else
  48.                         {
  49.                                 printf("\r\nRead Block Failed!\r\n");               
  50.                         }                                
  51.         }
  52.         //按键1双击写入
  53.         else if(KEY_Value == 0x02){
  54.                         KEY_Value=0;
  55.                         memset(SDBuffer_Tx, 0x5A, sizeof(SDBuffer_Tx));
  56.                         printf("------------------- Write SD card block data ------------------\r\n");
  57.                         if(HAL_SD_WriteBlocks(&hsd, SDBuffer_Tx, BLOCK_START_ADDR, NUM_OF_BLOCKS, 10) == HAL_OK)
  58.                         {
  59.                                 while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
  60.                                 {
  61.                                 }
  62.                                 printf("\r\nWrite Block Success!\r\n");
  63.                                 for(i = 0; i < sizeof(SDBuffer_Tx); i++)
  64.                                 {
  65.                                         printf("%03d:0x%02x ", i, SDBuffer_Tx[i]);
  66.                                 }
  67.                                 printf("\r\n");
  68.                         }
  69.                         else
  70.                         {
  71.                                 printf("\r\nWrite Block Failed!\r\n");
  72.                         }
  73.         }

  74.         //按键1长按擦除
  75.         else if(KEY_Value == 0x04){
  76.                         KEY_Value=0;
  77.                         printf("------------------- Block Erase ------------------------------\r\n");
  78.                         if(HAL_SD_Erase(&hsd, BLOCK_START_ADDR, NUM_OF_BLOCKS) == HAL_OK)
  79.                         {
  80.                                 /* Wait until SD cards are ready to use for new operation */
  81.                                 while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
  82.                                 {
  83.                                 }
  84.                                 printf("\r\nErase Block Success!\r\n");
  85.                         }
  86.                         else
  87.                         {
  88.                                         printf("\r\nErase Block Failed!\r\n");                    
  89.                         }               
  90.         }

  91. /******************************************DMA方式**************************************/        
  92.         //按键2 单击读取
  93.         if(KEY_Value == 0x10){
  94.                 KEY_Value=0;
  95.                         printf("------------------- Read SD card block data By DMA------------------\r\n");
  96.                         if(HAL_SD_ReadBlocks_DMA(&hsd, SDBuffer_Rx, 0, 1) == HAL_OK)
  97.                         {
  98.                                 while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
  99.                                 {
  100.                                 }
  101.                                 printf("\r\n Read block successfully!\r\n");
  102.                                 for(i=0;i<sizeof(SDBuffer_Rx)>>2;i++)
  103.                                 {
  104.                                                 printf("%03d:0x%08x ",i,SDBuffer_Rx[i]);
  105.                                 }
  106.                                 printf("\r\n");

  107.                         }               
  108.         }
  109.         //按键2双击写入
  110.         else if(KEY_Value == 0x20){
  111.                         KEY_Value=0;
  112.                         memset(SDBuffer_Tx, 0xA5, sizeof(SDBuffer_Tx));
  113.                         printf("------------------- Write SD card block data By DMA------------------\r\n");
  114.                         if(HAL_SD_WriteBlocks_DMA(&hsd, SDBuffer_Tx, 0, 1) == HAL_OK)
  115.                         {
  116.                                 while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
  117.                                 {
  118.                                 }        
  119.                                 printf("\r\n Write block successfully!\r\n");
  120.                                 for(i=0;i<sizeof(SDBuffer_Tx)>>2;i++)
  121.                                 {
  122.                                                 printf("%03d:0x%08x ",i,SDBuffer_Tx[i]);
  123.                                 }
  124.                                 printf("\r\n");
  125.                         }
  126.         }

  127.         //按键2长按擦除
  128.         else if(KEY_Value == 0x40){
  129.                         KEY_Value=0;
  130.                         printf("------------------- Block Erase ------------------------------\r\n");
  131.                         if(HAL_SD_Erase(&hsd, BLOCK_START_ADDR, NUM_OF_BLOCKS) == HAL_OK)
  132.                         {
  133.                                 /* Wait until SD cards are ready to use for new operation */
  134.                                 while(HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
  135.                                 {
  136.                                 }
  137.                                 printf("\r\nErase Block Success!\r\n");
  138.                         }
  139.                         else
  140.                         {
  141.                                         printf("\r\nErase Block Failed!\r\n");                    
  142.                         }
  143.         }                        
  144. }


复制代码




回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2022-3-7 04:30:53 | 显示全部楼层
一下子还看不出来什么问题,参考我的试试:
V6-024-FatFS文件系统例子(SD卡 V1.1).7z (4.92MB)


回复

使用道具 举报

5

主题

13

回帖

28

积分

新手上路

积分
28
 楼主| 发表于 2022-3-7 23:33:48 | 显示全部楼层
eric2013 发表于 2022-3-7 04:30
一下子还看不出来什么问题,参考我的试试:
V6-024-FatFS文件系统例子(SD卡 V1.1).7z (4.92MB)

感谢   今晚又重新测试了下  代码未做任何改动   又莫名其妙的可以了    不知道昨天哪里出了问题
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2022-3-8 11:27:49 | 显示全部楼层
dfsfjwfmlwsf 发表于 2022-3-7 23:33
感谢   今晚又重新测试了下  代码未做任何改动   又莫名其妙的可以了    不知道昨天哪里出了问题

反复开机100次,每次开机测试10次,看看成功率,估计有成功率问题。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 20:44 , Processed in 0.040063 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表