当前位置: 代码迷 >> 综合 >> 学习日记——SDIO—SDMMC1(2020.2.13)
  详细解决方案

学习日记——SDIO—SDMMC1(2020.2.13)

热度:24   发布时间:2023-12-11 16:17:50.0

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);