SDMMC理论基础知识
? SDMMC指的是SD、SDIO 、MMC 卡主机接口,提供APB2外设总线 多媒体卡(MMCs),数字安全记忆卡(SD)和SDIO卡。
? MMC的全称是”MultiMediaCard”――所以也通常被叫做”多媒 体卡”,是一种小巧大容量的快闪存储卡,特别应用于移动电话 和数字影像及其他移动终端中。
? SD卡,数字安全记忆卡(Secure Digital Memory Card),是 用于移动设备的标准记忆卡。SD卡数据传送和物理规范由MMC发 展而来,大小和MMC差不多。长宽和MMC一样,比MMC稍微厚了一 点。兼容性方面SD卡向下兼容多媒体卡(Multi Media Card)
? SDIO是在SD内存卡接口的基础上发展起来的外设接口,SDIO接 口兼容以前的SD内存卡,并且可以连接SDIO接口的设备,目前 根据SDIO协议的SPEC,SDIO接口支持的设备总类有蓝牙,网卡, 电视卡等。
查找开发板上的SD卡槽
图片中1口为开发板的SD卡槽,可将SD卡插入到1中
查看引脚
1)PD2为SDMMC1_CMD;
2)PC12为SDMMC1_SCK;
3)PC8为SDMMC1_DO;
6)PA9为UART1发送引脚;
7)P10为UART1接收引脚;
8)PC13为LED引脚
根据以上信息配置引脚
配置引脚
配置时钟
采用内部时钟(默认)
配置系统时钟最高80MHZ
SDMMC1时钟24MHZ
配置SDMMC1参数
SDMMCCLK clock divid 也可为默认0
生成SDMMC1工程
1、自定义工程名称。
2、选择英文路径,否则会丢 失启动文件而无法编译通过, 需要手动添加启动文件: startup_stm32l431xx.s
3、选择MDK-ARM V5开发软件, 即KEIL5软件。
代码编写说明
1、初始化microSD
2、读取microSD卡参数
3、写数据到microSD卡
4、读取写入microSD卡数据
调用函数:
1、HAL_SD_CardStateTypedef HAL_SD_GetCardState(SD_HandleTypeDef *hsd);//获取SD状态
2、HAL_SD_GetCardCID(SD_HandleTypeDef *hsd, HAL_SD_CardCIDTypedef *pCID);//获取SD卡ID
3、HAL_SD_WriteBlocks (SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, int32_t Timeout);
4、HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint8_t pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
5、HAL_GPIO_TogglePin(GPIO_TypeDef GPIOx, uint16_t GPIO_Pin);// 运行LED
6、void HAL_Delay(uint32_t Delay);//延时
7、printf();//打印数据到串口函数 需要重新定义函数fputc();才能正常使用printf();
int fputc(int ch,FILE*f)
{uint8_t temp[1]={ch}HAL_UART_Transmit(&huert,temp,1,2);return HAL_OK;
}
代码编写实现
添加头文件:
#include “stdio.h”
#include “string.h”
main函数内定义变量
uint8_t temp[]=“欢迎来到物联网俱乐部”;
uint8_t temp1[]=“Welcome to IoT”;
main函数外定义变量:
HAL_SD_CardCIDTypedef SD_CardCID;
#define BLOCK_SIZE 512//块大小
#define NUMBER_OF_BLOCKS 8//块数量、
#define WRITE_READ_ADDRESS 0x00002000//读写地址
#define WRITE_READ_ADDRESS2 0x00004000//读写地址
uint32_t Buffer_Block_Tx[BLOCK_SIZE*NUMBER_OF_BLOCKSS];//数据缓存
uint32_t Buffer_Block_Rx[BLOCK_SIZE*NUMBER_OF_BLOCKSS]={1,2};//数据缓存
HAL_StatusTypeDef sd_status;//HAL返回值
void ReadSD(void);
void SD_Write_Read_Test(int32_t addr,uint8_t*temp);
代码编写实现
void SD_Write_Read_Test(int32_t addr,uint8_t* temp)//写入SD卡数据并读出数据
{int i,j = 0; printf("\r\n\r\n*************Write SD card data *************\r\n"); sd_status=HAL_SD_WriteBlocks(&hsd1(uint8_t*)temp,addr,NUMBER_OF_BLOCKS,0xffff); printf("Write data:%s,address:%x\r\n",temp,addr); HAL_Delay(480); if(sd_status == 0) { printf("Write data test is OK\r\n" ); }elseprintf("Write data test is fail!\r\n " ); printf("*************Read SD card data *************\r\n"); sd_status=HAL_SD_ReadBlocks(&hsd1(uint8_t*)Buffer_Block_Rx,addr,NUMBER_OF_BLOCKS,0xffff); printf("ReadSDData:%s,address:%x\r\n",(char*)Buffer_Block_Rx,addr); if(sd_status == 0){ printf("Read data test is OK\r\n" ); }
else printf("Read data test is fail!\r\n " );
}void ReadSD(void)//读取SD出厂参数{ int State=0; State = HAL_SD_GetCardState(&hsd1); if(State == HAL_SD_CARD_TRANSFER) {HAL_SD_GetCardCID(&hsd1,&SD_CardCID); printf("\r\n Initialize SD card successfully!\r\n\r\n"); printf(" SD card information! \r\n"); printf(" CardCapacity : %llu \r\n",((unsigned long long)hsd1.SdCard.BlockSize*hsd1.SdCard.BlockNbr)); printf(" CardBlockSize : %d \r\n",hsd1.SdCard.BlockSize); printf(" RCA : %d \r\n",hsd1.SdCard.RelCardAdd);printf(" CardType : %d \r\n",hsd1.SdCard.CardType); printf(" ManufacturerID: %d \r\n",SD_CardCID.ManufacturerID); }else {printf("SD card init fail!\r\n" ); while(1); // 停机 }
}while(1)循环外程序:
ReadSD();//读取SD卡初始化参数
HAL_SD_ReadBlocks(&hsd1(uint8_t*)Buffer_Block_Rx,WRITE_READ_ADDRESS,NUMBER_OF_BLOCKS,0xffff);
printf("Read SD old data1:%s,address:%x\r\n",(char*)Buffer_Block_Rx,WRITE_READ_ADDRESS); memset(Buffer_Block_Rx,0x00,sizeof(Buffer_Block_Rx));
HAL_SD_ReadBlocks(&hsd1(uint8_t*)Buffer_Block_Rx,WRITE_READ_ADDRESS2,NUMBER_OF_BLOCKS,0xffff);
printf("Read SD old data2:%s,address:%x\r\n",(char*)Buffer_Block_Rx,WRITE_READ_ADDRESS2); memset(Buffer_Block_Rx,0x00,sizeof(Buffer_Block_Rx)); SD_Write_Read_Test(WRITE_READ_ADDRESS,temp); memset(Buffer_Block_Rx,0x00,sizeof(Buffer_Block_Rx)); SD_Write_Read_Test(WRITE_READ_ADDRESS2,temp1); memset(Buffer_Block_Rx,0x00,sizeof(Buffer_Block_Rx)); while(1)循环内程序:
HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13);
HAL_Delay(1000);