SD卡的使用

记录下SD卡的使用

1.首先需要正确移植SD卡的程序

由于SD卡的管脚是固定的,标准库参考官方例程就行

加入 stm32_eval_sdio_sd.c 这是官方写的

2.加入在其他文件中定义的缺少的东西

c 复制代码
#define SD_DETECT_PIN                    GPIO_Pin_11                 /* PF.11 */
#define SD_DETECT_GPIO_PORT              GPIOF                       /* GPIOF */
#define SD_DETECT_GPIO_CLK               RCC_APB2Periph_GPIOF

#define SDIO_FIFO_ADDRESS                ((uint32_t)0x40018080)
/** 
  * @brief  SDIO Intialization Frequency (400KHz max)
  */
#define SDIO_INIT_CLK_DIV                ((uint8_t)0xB2)
/** 
  * @brief  SDIO Data Transfer Frequency (25MHz max) 
  */
//#define SDIO_TRANSFER_CLK_DIV            ((uint8_t)0x00) 
#define SDIO_TRANSFER_CLK_DIV            ((uint8_t)0x01) 

3.加入SDIO.c的函数

c 复制代码
#include "bsp_SDIO.h"

#include "stm32_eval_sdio_sd.h"

/** @addtogroup STM32F10x_StdPeriph_Examples
  * @{
  */

/** @addtogroup SDIO_uSDCard
  * @{
  */



/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint8_t Buffer_Block_Tx[BLOCK_SIZE], Buffer_Block_Rx[BLOCK_SIZE];
uint8_t Buffer_MultiBlock_Tx[MULTI_BUFFER_SIZE], Buffer_MultiBlock_Rx[MULTI_BUFFER_SIZE];
volatile TestStatus EraseStatus = FAILED, TransferStatus1 = FAILED, TransferStatus2 = FAILED;
SD_Error Status = SD_OK;
__IO uint32_t SDCardOperation = SD_OPERATION_ERASE;



/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
//int main(void)
//{
//  /*!< At this stage the microcontroller clock setting is already configured, 
//       this is done through SystemInit() function which is called from startup
//       file (startup_stm32f10x_xx.s) before to branch to application main.
//       To reconfigure the default setting of SystemInit() function, refer to
//       system_stm32f10x.c file
//     */

//  /* Initialize LEDs available on STM3210X-EVAL board *************************/
  STM_EVAL_LEDInit(LED1);
  STM_EVAL_LEDInit(LED2);
  STM_EVAL_LEDInit(LED3);
  STM_EVAL_LEDInit(LED4);  

//  /* Interrupt Config */
//  NVIC_Configuration();

//  /*------------------------------ SD Init ---------------------------------- */
//  if((Status = SD_Init()) != SD_OK)
//  {
    STM_EVAL_LEDOn(LED4); 
//  }
//        
//  while((Status == SD_OK) && (SDCardOperation != SD_OPERATION_END) && (SD_Detect()== SD_PRESENT))
//  {
//    switch(SDCardOperation)
//    {
//      /*-------------------------- SD Erase Test ---------------------------- */
//      case (SD_OPERATION_ERASE):
//      {
//        SD_EraseTest();
//        SDCardOperation = SD_OPERATION_BLOCK;
//        break;
//      }
//      /*-------------------------- SD Single Block Test --------------------- */
//      case (SD_OPERATION_BLOCK):
//      {
//        SD_SingleBlockTest();
//        SDCardOperation = SD_OPERATION_MULTI_BLOCK;
//        break;
//      }       
//      /*-------------------------- SD Multi Blocks Test --------------------- */
//      case (SD_OPERATION_MULTI_BLOCK):
//      {
//        SD_MultiBlockTest();
//        SDCardOperation = SD_OPERATION_END;
//        break;
//      }              
//    }
//  }
//  
//  /* Infinite loop */
//  while (1)
//  {}
//}

///**
//  * @brief  Configures SDIO IRQ channel.
//  * @param  None
//  * @retval None
//  */
//void NVIC_Configuration(void)
//{
//  NVIC_InitTypeDef NVIC_InitStructure;

//  /* Configure the NVIC Preemption Priority Bits */
//  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

//  NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
//  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
//  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
//  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//  NVIC_Init(&NVIC_InitStructure);
//}

/**
  * @brief  Tests the SD card erase operation.
  * @param  None
  * @retval None
  */
void SD_EraseTest(void)
{
  /*------------------- Block Erase ------------------------------------------*/
  if (Status == SD_OK)
  {
    /* Erase NumberOfBlocks Blocks of WRITE_BL_LEN(512 Bytes) */
    Status = SD_Erase(0x00, (BLOCK_SIZE * NUMBER_OF_BLOCKS));
  }

  if (Status == SD_OK)
  {
    Status = SD_ReadMultiBlocks(Buffer_MultiBlock_Rx, 0x00, BLOCK_SIZE, NUMBER_OF_BLOCKS);

    /* Check if the Transfer is finished */
    Status = SD_WaitReadOperation();

    /* Wait until end of DMA transfer */
    while(SD_GetStatus() != SD_TRANSFER_OK);
  }

  /* Check the correctness of erased blocks */
  if (Status == SD_OK)
  {
    EraseStatus = eBuffercmp(Buffer_MultiBlock_Rx, MULTI_BUFFER_SIZE);
  }
  
  if(EraseStatus == PASSED)
  {
//    STM_EVAL_LEDOn(LED1);
  }
  else
  {
//    STM_EVAL_LEDOff(LED1);
//    STM_EVAL_LEDOn(LED4);    
  }
}

/**
  * @brief  Tests the SD card Single Blocks operations.
  * @param  None
  * @retval None
  */
void SD_SingleBlockTest(void)
{
  /*------------------- Block Read/Write --------------------------*/
  /* Fill the buffer to send */
  Fill_Buffer(Buffer_Block_Tx, BLOCK_SIZE, 0x320F);

  if (Status == SD_OK)
  {
    /* Write block of 512 bytes on address 0 */
    Status = SD_WriteBlock(Buffer_Block_Tx, 0x00, BLOCK_SIZE);
    /* Check if the Transfer is finished */
    Status = SD_WaitWriteOperation();
    while(SD_GetStatus() != SD_TRANSFER_OK);
  }

  if (Status == SD_OK)
  {
    /* Read block of 512 bytes from address 0 */
    Status = SD_ReadBlock(Buffer_Block_Rx, 0x00, BLOCK_SIZE);
    /* Check if the Transfer is finished */
    Status = SD_WaitReadOperation();
    while(SD_GetStatus() != SD_TRANSFER_OK);
  }

  /* Check the correctness of written data */
  if (Status == SD_OK)
  {
    TransferStatus1 = Buffercmp(Buffer_Block_Tx, Buffer_Block_Rx, BLOCK_SIZE);
  }
  
  if(TransferStatus1 == PASSED)
  {
//    STM_EVAL_LEDOn(LED2);
  }
  else
  {
//    STM_EVAL_LEDOff(LED2);
//    STM_EVAL_LEDOn(LED4);    
  }
}

/**
  * @brief  Tests the SD card Multiple Blocks operations.
  * @param  None
  * @retval None
  */
void SD_MultiBlockTest(void)
{
  /*--------------- Multiple Block Read/Write ---------------------*/
  /* Fill the buffer to send */
  Fill_Buffer(Buffer_MultiBlock_Tx, MULTI_BUFFER_SIZE, 0x0);

  if (Status == SD_OK)
  {
    /* Write multiple block of many bytes on address 0 */
    Status = SD_WriteMultiBlocks(Buffer_MultiBlock_Tx, 0x00, BLOCK_SIZE, NUMBER_OF_BLOCKS);
    /* Check if the Transfer is finished */
    Status = SD_WaitWriteOperation();
    while(SD_GetStatus() != SD_TRANSFER_OK);
  }

  if (Status == SD_OK)
  {
    /* Read block of many bytes from address 0 */
    Status = SD_ReadMultiBlocks(Buffer_MultiBlock_Rx, 0x00, BLOCK_SIZE, NUMBER_OF_BLOCKS);
    /* Check if the Transfer is finished */
    Status = SD_WaitReadOperation();
    while(SD_GetStatus() != SD_TRANSFER_OK);
  }

  /* Check the correctness of written data */
  if (Status == SD_OK)
  {
    TransferStatus2 = Buffercmp(Buffer_MultiBlock_Tx, Buffer_MultiBlock_Rx, MULTI_BUFFER_SIZE);
  }
  
  if(TransferStatus2 == PASSED)
  {
//    STM_EVAL_LEDOn(LED3);
  }
  else
  {
//    STM_EVAL_LEDOff(LED3);
//    STM_EVAL_LEDOn(LED4);    
  }
}

/**
  * @brief  Compares two buffers.
  * @param  pBuffer1, pBuffer2: buffers to be compared.
  * @param  BufferLength: buffer's length
  * @retval PASSED: pBuffer1 identical to pBuffer2
  *         FAILED: pBuffer1 differs from pBuffer2
  */
TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint32_t BufferLength)
{
  while (BufferLength--)
  {
    if (*pBuffer1 != *pBuffer2)
    {
      return FAILED;
    }

    pBuffer1++;
    pBuffer2++;
  }

  return PASSED;
}

/**
  * @brief  Fills buffer with user predefined data.
  * @param  pBuffer: pointer on the Buffer to fill
  * @param  BufferLength: size of the buffer to fill
  * @param  Offset: first value to fill on the Buffer
  * @retval None
  */
void Fill_Buffer(uint8_t *pBuffer, uint32_t BufferLength, uint32_t Offset)
{
  uint16_t index = 0;

  /* Put in global buffer same values */
  for (index = 0; index < BufferLength; index++)
  {
    pBuffer[index] = index + Offset;
  }
}

/**
  * @brief  Checks if a buffer has all its values are equal to zero.
  * @param  pBuffer: buffer to be compared.
  * @param  BufferLength: buffer's length
  * @retval PASSED: pBuffer values are zero
  *         FAILED: At least one value from pBuffer buffer is different from zero.
  */
TestStatus eBuffercmp(uint8_t* pBuffer, uint32_t BufferLength)
{
  while (BufferLength--)
  {
    /* In some SD Cards the erased state is 0xFF, in others it's 0x00 */
    if ((*pBuffer != 0xFF) && (*pBuffer != 0x00))
    {
      return FAILED;
    }

    pBuffer++;
  }

  return PASSED;
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {}
}
#endif

在头文件中加入

c 复制代码
#include "pbdata.h"



/* Private typedef -----------------------------------------------------------*/
typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;

/* Private define ------------------------------------------------------------*/
#define BLOCK_SIZE            512 /* Block Size in Bytes */

#define NUMBER_OF_BLOCKS      32  /* For Multi Blocks operation (Read/Write) */
#define MULTI_BUFFER_SIZE    (BLOCK_SIZE * NUMBER_OF_BLOCKS)

#define SD_OPERATION_ERASE          0
#define SD_OPERATION_BLOCK          1
#define SD_OPERATION_MULTI_BLOCK    2 
#define SD_OPERATION_END            3





extern  __IO uint32_t SDCardOperation;

在中断中加入

c 复制代码
/**
  * @brief  This function handles SDIO global interrupt request.
  * @param  None
  * @retval None
  */
void SDIO_IRQHandler(void)
{
  /* Process All SDIO Interrupt Sources */
  SD_ProcessIRQSrc();
}

进行测试

c 复制代码
  /*------------------------------ SD Init ---------------------------------- */
  if((gStatus = SD_Init()) != SD_OK)
  {
//    STM_EVAL_LEDOn(LED4); 
  }
        
  while((gStatus == SD_OK) && (SDCardOperation != SD_OPERATION_END) && (SD_Detect()== SD_PRESENT))
  {
    switch(SDCardOperation)
    {
      /*-------------------------- SD Erase Test ---------------------------- */
      case (SD_OPERATION_ERASE):
      {
        SD_EraseTest();
        SDCardOperation = SD_OPERATION_BLOCK;
        break;
      }
      /*-------------------------- SD Single Block Test --------------------- */
      case (SD_OPERATION_BLOCK):
      {
        SD_SingleBlockTest();
        SDCardOperation = SD_OPERATION_MULTI_BLOCK;
        break;
      }       
      /*-------------------------- SD Multi Blocks Test --------------------- */
      case (SD_OPERATION_MULTI_BLOCK):
      {
        SD_MultiBlockTest();
        SDCardOperation = SD_OPERATION_END;
        break;
      }              
    }
  }

SD卡读写内容一致,就可以正常使用了
相关推荐
天庭鸡腿哥1 小时前
国外软件,安装即时专业版!
stm32·microsoft·macos·everything
214实验室1 小时前
STM32串口打印使用printf乱码问题
stm32·单片机·嵌入式硬件
沐欣工作室_lvyiyi2 小时前
基于单片机的电厂烟道粉尘浓度检测系统(论文+源码)
单片机·嵌入式硬件·毕业设计
Groundwork Explorer3 小时前
异步框架+POLL混合方案应对ESP32 MPY多任务+TCP多连接
python·单片机
d111111111d4 小时前
什么是内存对齐?在STM32上面如何通过编辑器指令来实现内存对齐。
笔记·stm32·单片机·嵌入式硬件·学习·编辑器
bai5459365 小时前
STM32 CuberIDE 中断
stm32·单片机·嵌入式硬件
小叶子来了啊5 小时前
5Arduino 程序结构
单片机·嵌入式硬件
小叶子来了啊6 小时前
1Arduino 简介
单片机·嵌入式硬件
雾岛听风眠6 小时前
电路板维修
单片机·嵌入式硬件
少一倍的优雅6 小时前
hi3863(WS63) 智能小车 (一) 简单介绍
单片机·嵌入式硬件·harmonyos·hi3863