实验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教程,即可获取下载链接。
您好,我跟着教程但是没有运行成功,SD卡一直挂载失败,请问您知道是什么原因吗,麻烦您细说一下。
返回值如下。
start!
SD卡初始化成功!
FileSystem Mounted Failed (256)
Get SDCard Capacity Failed (256)
一般是SPI没配好,或者FATFS那里配置错误,建议直接在我的例程基础上修改。
解决了吗?最后是啥问题
同问,我遇到了一摸一样的问题,现在解决了吗?