记录下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卡读写内容一致,就可以正常使用了