新發基金的好處和壞處是什么?新基金的封閉期一般是多久?
新發基金的好處和壞處是什么?新發基金的優點:1、認購費率低:一般
2023/07/06
導語“生活中我們經常使用SD卡,一般SD卡有兩種接口,SDIO和SPI,SPI接口在前面的教程中已經使用過了。本教程來介紹SDIO接口CubeMx如何配置使用,將以SD卡為例來講解SDIO接口。”
?硬件
(相關資料圖)
野火指南者開發版、SD卡
?軟件
CubeMx & MDK & 串口助手
(1) STM32CubeMx 2021年最新版Version 6.1.0
(2) DMK V5.15
?原理圖
F103只有一個SDIO接口,野火開發板中WiFi和SD卡公用這個接口,在使用中要注意不能同時操作。
SDIO 有4根數據線:D0~D1, 一次傳輸4位數據,CK為時鐘線,CMD為控制線(操作命令通過這條線)。
本次教程的使用同樣以UART串口使用的教程項目為基礎進行配置,將測試結果打印出來,串口的配置這兒就不寫了,可參考相關章節。
這次配置我們只是使用SDIO接口的基本模式,通過輪詢模式來操作,下一節使用DMA模式。,完成上述操作后進行代碼生成。
按上述配置初始化代碼生成后,使用MDK打開項目進行應用代碼編寫。
/*SD 操作*/typedef enum {FAILED= 0, PASSED = !FAILED} TestStatus;/* 私有宏定義 ----------------------------------------------------------------*/#define BLOCK_SIZE 512 // SD卡塊大小 #define NUMBER_OF_BLOCKS 8 // 測試塊數量(小于15)#define WRITE_READ_ADDRESS 0x00002000 // 測試讀寫地址#define SDMMC hsd/* 私有變量 ------------------------------------------------------------------*/__align(4) uint32_t Buffer_Block_Tx[BLOCK_SIZE*NUMBER_OF_BLOCKS]; // 寫數據緩存__align(4) uint32_t Buffer_Block_Rx[BLOCK_SIZE*NUMBER_OF_BLOCKS]; // 讀數據緩存HAL_StatusTypeDef sd_status; // HAL庫函數操作SD卡函數返回值:操作結果TestStatus test_status; // 數據測試結果void SD_EraseTes();void SD_Write_Read_Test();HAL_StatusTypeDef Return_Status;HAL_SD_CardStateTypeDef SD_Card_Status;/*************************************/ TestStatus eBuffercmp(uint32_t* pBuffer, uint32_t BufferLength) { while (BufferLength--) { /* SD卡擦除后的可能值為0xff或0 */ if ((*pBuffer != 0xFFFFFFFF) && (*pBuffer != 0)) { return FAILED; } pBuffer++; } return PASSED; } void SD_EraseTest(void) { /* 第1個參數為SD卡句柄,第2個參數為擦除起始地址,第3個參數為擦除結束地址 */ sd_status=HAL_SD_Erase(&SDMMC,WRITE_READ_ADDRESS,WRITE_READ_ADDRESS+NUMBER_OF_BLOCKS*4); printf("《SD》""erase status:%drn",sd_status); HAL_Delay(500); if (sd_status == HAL_OK) { /* 讀取剛剛擦除的區域 */ sd_status = HAL_SD_ReadBlocks(&SDMMC,(uint8_t *)Buffer_Block_Rx,WRITE_READ_ADDRESS,NUMBER_OF_BLOCKS); printf("《SD》""erase read status:%drn",sd_status); /* 把擦除區域讀出來對比 */ test_status = eBuffercmp(Buffer_Block_Rx,BLOCK_SIZE*NUMBER_OF_BLOCKS); if(test_status == PASSED) printf("《SD》""除測試成功!rn" ); else printf("《SD》""擦除不成功,數據出錯!rn" ); } else { printf("《SD》""擦除測試失敗!部分SD不支持擦除,只要讀寫測試通過即可rn" ); } } void Fill_Buffer(uint32_t *pBuffer, uint32_t BufferLength, uint32_t Offset) { uint32_t index = 0; /* 填充數據 */ for(index = 0; index < BufferLength; index++ ) { pBuffer[index] = index + Offset; } } TestStatus Buffercmp(uint32_t* pBuffer1, uint32_t* pBuffer2, uint32_t BufferLength) { while (BufferLength--) { if(BufferLength%50==0) { printf("buf:0x%08X - 0x%08Xrn",*pBuffer1,*pBuffer2); } if (*pBuffer1 != *pBuffer2) { return FAILED; } pBuffer1++; pBuffer2++; } return PASSED; } void SD_Write_Read_TestA(void) { printf(" Warning: this programmay erase all the TFcard data. rn"); printf("rn Initialize SD card successfully!rnrn"); printf(" SD card information! rn"); printf(" CardCapacity : %llu rn",((unsigned long long)SDMMC.SdCard.BlockSize*hsd.SdCard.BlockNbr)); printf(" CardBlockSize : %d rn",SDMMC.SdCard.BlockSize); printf(" RCA : %d rn",SDMMC.SdCard.RelCardAdd); printf(" CardType : %d rn",SDMMC.SdCard.CardType); int i,j = 0; /* 填充數據到寫緩存 */ Fill_Buffer(Buffer_Block_Tx,BLOCK_SIZE*NUMBER_OF_BLOCKS, 0x6666); /* 往SD卡寫入數據 */ sd_status = HAL_SD_WriteBlocks(&SDMMC,(uint8_t *)Buffer_Block_Tx,WRITE_READ_ADDRESS,NUMBER_OF_BLOCKS); printf("《SD》""write status:%drn",sd_status); HAL_Delay(600); /* 從SD卡讀取數據 */ sd_status =HAL_SD_ReadBlocks(&SDMMC,(uint8_t *)Buffer_Block_Rx,WRITE_READ_ADDRESS,NUMBER_OF_BLOCKS); printf("《SD》""read status:%drn",sd_status); /* 比較數據 */ test_status = Buffercmp(Buffer_Block_Tx, Buffer_Block_Rx, BLOCK_SIZE*NUMBER_OF_BLOCKS/4); //比較 if(test_status == PASSED) { printf("《SD》""》讀寫測試成功!rn" ); for(i=0;i
(1)SD卡寫入前必須對塊進行擦除,調用HAL庫函數HALSDErase();
( 2 ) SD 卡的讀調用HAL庫函數HALSDReadBlocks();
( 3 ) SD 卡的寫調用HAL庫的HALSDWriteBlocks()。
我們先對相關塊進行擦除操作,再將數據寫入,重新讀出來進行比較是否一致來完成SD卡讀寫操作。
使用了聯想的32GSD卡。
micro-sd
標簽: