记录下SD卡的使用
1.首先需要正确移植SD卡的程序
由于SD卡的管脚是固定的,标准库参考官方例程就行
加入 stm32_eval_sdio_sd.c 这是官方写的
2.加入在其他文件中定义的缺少的东西
#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的函数
#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
在头文件中加入
#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 3extern __IO uint32_t SDCardOperation;
在中断中加入
/*** @brief This function handles SDIO global interrupt request.* @param None* @retval None*/
void SDIO_IRQHandler(void)
{/* Process All SDIO Interrupt Sources */SD_ProcessIRQSrc();
}
进行测试
/*------------------------------ 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卡读写内容一致,就可以正常使用了