STM32CUBEMX_SPI接口读写操作TF卡

实验1:点亮LED
实验2:按键控制LED
实验3:外部中断检测按键
实验4:扩展芯片检测按键
实验5:定时器实现LED闪烁
实验6:基于PWM的呼吸灯
实验7:检测输入的PWM频率和脉宽
实验8:串口的输入和输出
实验9:串口使用PRINTF函数
实验10:SPI接口操作片外FLASH
实验11:SPI接口操作TF卡
实验12:IIC接口操作OLED屏幕
实验13:ADC电压采样

TF卡,也就是我们平时手机上用的内存卡,它是支持SPI接口的。本节实验,我们使用SPI接口控制TF卡,读取卡的容量,并在卡内创建txt文件。

SPI接口和上一节一样,使用SPI1,片选引脚使用PC14。

步骤如下:

1、新建工程,进行基本配置。通过点击“ACCESS TO MCU SELECTOR”来创建一个新的工程:

参照实验1,芯片选择“STM32F103C8”。

打开外部时钟,点击“System Core”,选择RCC,在右侧弹出的菜单栏中选择“Crystal/Ceramic Resonator”。

选择调试接口,点击“System Core”,选择RCC。,在右侧弹出的菜单栏中选择“Serial Wire”。

2、片选信号。如图,配置PC14为TF卡的片选信号,将其配置为输出模式,并命名为“SD_CS”,注意大写。

3、配置SPI接口。如图,位置1选中SPI1,位置2选择“Full-Duplex Master”,NSS那里选择“Disable”。

位置3,主要配置SPI的速度,也就是“Buad Rate”,通过上面的分频系数来控制“Prescaler”。

4、配置串口。参照上一节,打开串口1,设置波特率为115200。在后续的工程中,使用printf函数打印相关信息。

5、添加FATFS中间件。因为涉及到文件系统的操作,所以使能该配置,如图:

6、时钟配置。参照实验1.

7、生成工程。参照实验1的步骤7,进行相应配置,生成工程文件。

8、添加TF卡驱动程序。该驱动程序为网上分享,直接使用即可。参照实验4的步骤6,将下面文件添加到工程中。

9、串口printf。参照实验9,添加相关代码。

10、TF卡相关函数。位置1,进行相关变量定义与函数声明。

代码:

void WritetoSD(BYTE write_buff[],uint8_t bufSize);

uint8_t aRxBuffer1;	//uart rx buff 
char SD_FileName[] = "hello.txt";
uint8_t WriteBuffer[] = "01 write buff to tf \r\n";
uint8_t write_cnt =0;	//дSD¿¨´ÎÊý

位置2,写TF卡操作函数。

代码:

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(res == FR_NO_FILESYSTEM)		//ûÓÐÎļþϵͳ£¬¸ñʽ»¯
	{
		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);		 //È¡Ïû¹ÒÔØ
	
}

位置3,获取TF卡容量函数。

代码:

void Get_SDCard_Capacity(void)
{
	FRESULT result;
	FATFS FS;
	FATFS *fs;
	DWORD fre_clust,AvailableSize,UsedSize;  
	uint16_t TotalSpace;
	uint8_t res;
	
	res = SD_init();		//SD¿¨³õʼ»¯
	if(res == 1)
	{
		printf("SD¿¨³õʼ»¯Ê§°Ü! \r\n");		
	}
	else
	{
		printf("SD¿¨³õʼ»¯³É¹¦£¡ \r\n");		
	}
	
	/* ¹ÒÔØ */
	res=f_mount(&FS,"0:",1);		//¹ÒÔØ
	if (res != FR_OK)
	{
		printf("FileSystem Mounted Failed (%d)\r\n", result);
	}

	res = f_getfree("0:", &fre_clust, &fs);  /* ¸ùĿ¼ */
	if ( res == FR_OK ) 
	{
		TotalSpace=(uint16_t)(((fs->n_fatent - 2) * fs->csize ) / 2 /1024);
		AvailableSize=(uint16_t)((fre_clust * fs->csize) / 2 /1024);
		UsedSize=TotalSpace-AvailableSize;              
		/* Print free space in unit of MB (assuming 512 bytes/sector) */
		printf("\r\n%d MB total drive space.\r\n""%d MB available.\r\n""%d MB  used.\r\n",TotalSpace, AvailableSize,UsedSize);
	}
	else 
	{
		printf("Get SDCard Capacity Failed (%d)\r\n", result);
	}		
}

位置4,对TF卡进行初始化操作,并打印相关信息:

	HAL_UART_Receive_IT(&huart1,&aRxBuffer1,1); 	//enable uart	
	printf(" start! \r\n");
	Get_SDCard_Capacity();	//µÃµ½Ê¹ÓÃÄڴ沢ѡÔñ¸ñʽ»¯
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

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

位置5,添加头文件

代码:

#include <stdio.h>
#include "SDdriver.h"

修改后,保存,编译、下载,重新上电。使用串口助手连接板子和电脑,可以看到串口助手收到打印信息。

整个过程有PPT、数据手册、原理图、源码、相关软件,在公众号(单片机爱好者)回复关键词:002或者STM32CUBEMX教程,即可获取下载链接。

《STM32CUBEMX_SPI接口读写操作TF卡》有2条留言

  1. 您好,我跟着教程但是没有运行成功,SD卡一直挂载失败,请问您知道是什么原因吗,麻烦您细说一下。
    返回值如下。
    start!
    SD卡初始化成功!
    FileSystem Mounted Failed (256)
    Get SDCard Capacity Failed (256)

    回复

留下评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据