STM32下SD卡的读取

一、SD卡模块介绍

1.1 什么是SD卡

SD存储卡是一种基于半导体快闪记忆器的新一代记忆设备,由于它体积小、数据传输速度快、可热插拔等优良的特性,被广泛地于便携式装置上使用,例如数码相机、平板电脑和多媒体播放器等。控制器对 SD 卡进行读写通信操作一般有两种通信接口可选,一种是 SPI 接口,另外一种是 SDIO 接口。

1.2 SD卡的物理结构

一张SD卡包括有存储单元、存储单元接口、电源检测、卡及接口控制器和接口驱动器5 个部分。
存储单元是存储数据部件,存储单元通过存储单元接口与卡控制单元进行数据传输;
电源检测单元保证SD卡工作在合适的电压下,如出现掉电或上状态时,它会使控制单元和存储单元接口复位;
卡及接口控制单元控制SD卡的运行状态,它包括有8个寄存器;
接口驱动器控制 SD 卡引脚的输入输出。

 

 

二、项目代码

 

 

 已挂载在Github上

项目链接:https://github.com/LinZJ0423/STM32

烧录程序成功后:

主要函数代码分析:

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */
  

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI1_Init();
  MX_FATFS_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
    
    HAL_UART_Receive_IT(&huart1,&aRxBuffer1,1);     //enable uart    

    printf(" mian \r\n");

    Get_SDCard_Capacity();    //得到使用内存并选择格式化



  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {        
        WritetoSD(WriteBuffer,sizeof(WriteBuffer));            
        HAL_Delay(500);
        WriteBuffer[0] = WriteBuffer[0] +0;
        WriteBuffer[1] = WriteBuffer[1] +1;
        write_cnt ++;        
        while(write_cnt > 10)
        {    
            printf(" while \r\n");
            HAL_Delay(500);
        }            
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}


void WritetoSD(BYTE write_buff[],uint8_t bufSize)
{
    FATFS fs;
    FIL file;
    uint8_t res=0;
    UINT Bw;    
    
    res = SD_init();        //SD卡初始化
    
    if(res == 1)
    {
        printf("SD卡初始化失败! \r\n");        
    }
    else
    {
        printf("SD卡初始化成功! \r\n");        
    }
    
    res=f_mount(&fs,"0:",1);        //挂载
    
//    if(test_sd == 0)        //用于测试格式化
    if(res == FR_NO_FILESYSTEM)        //没有文件系统,格式化
    {
//        test_sd =1;                //用于测试格式化
        printf("没有文件系统! \r\n");        
        res = f_mkfs("", 0, 0);        //格式化sd卡
        if(res == FR_OK)
        {
            printf("格式化成功! \r\n");        
            res = f_mount(NULL,"0:",1);         //格式化后先取消挂载
            res = f_mount(&fs,"0:",1);            //重新挂载    
            if(res == FR_OK)
            {
                printf("SD卡已经成功挂载,可以进进行文件写入测试!\r\n");
            }    
        }
        else
        {
            printf("格式化失败! \r\n");        
        }
    }
    else if(res == FR_OK)
    {
        printf("挂载成功! \r\n");        
    }
    else
    {
        printf("挂载失败! \r\n");
    }    
    
    res = f_open(&file,SD_FileName,FA_OPEN_ALWAYS |FA_WRITE);
    if((res & FR_DENIED) == FR_DENIED)
    {
        printf("卡存储已满,写入失败!\r\n");        
    }
    
    f_lseek(&file, f_size(&file));//确保写词写入不会覆盖之前的数据
    if(res == FR_OK)
    {
        printf("打开成功/创建文件成功! \r\n");        
        res = f_write(&file,write_buff,bufSize,&Bw);        //写数据到SD卡
        if(res == FR_OK)
        {
            printf("文件写入成功! \r\n");            
        }
        else
        {
            printf("文件写入失败! \r\n");
        }        
    }
    else
    {
        printf("打开文件失败!\r\n");
    }    
    
    f_close(&file);                        //关闭文件        
    f_mount(NULL,"0:",1);         //取消挂载
    
}

程序首先进行相关初始化,完成后输出mian,之后进行SD卡格式化,成功后进入循环,进入SD卡读写函数,先后进行SD卡的初始化,挂载,创文件,写入,写入超过10次,输出while

三、相关引脚的配置

CS -> PB0
SCK -> PA5
MISO -> PA6
MOSI -> PA7

四、实验结果

SD卡中生成一个新的hello.txt文件
内容如下

 

更改写入内容

 

写入结果如下:

 

 

 

五、心得体会

在初始化过程中确保SD格式化成FAT文件模式,确保单片机的供电和SD卡模块的供电最好是5V,不然可能带不动SD卡驱动导致实验失败。杜邦线连接要尽可能的短,因为实验过程中,采用过长的杜邦线经常导致出不来结果。初始化的过程中需要耐心等待。本次实验遇到了很多的问题,通过查阅相关博客,请教同学和老师问题得以解决,在解决的过程中提高了我们的动手能力以及学会了在SD卡读写东西,这是一个十分有意思的过程,在学习的过程中让我受益匪浅。

 

posted @ 2021-12-25 10:44  LinZJ0423  阅读(962)  评论(0编辑  收藏  举报