一、HAL库配置
配置USART1
配置SPI1
配置FATFS
GPIO配置
时钟配置
Serial Wire配置
生成工程
二、移植并添加工程
(一)移植驱动文件
将SDdriver.c 和SDdriver.h 文件添加到工程中 复制到与工程同一路径后后,在工程里面添加SDdriver.c 文件,并添加包含该文件的路径。
(二)修改user_diskio.c文件
①添加包含的头文件
#include "diskio.h"
#include "SDdriver.h"
接下来分别对USER_initialize、USER_status、USER_read、USE_WRITE、USE_IOCTL函数进行修改,将其内容替换为下面对应函数相关内容
②修改USER_initialize 函数
uint8_t res;
res = SD_init();
if(res)
{
SPI_setspeed(SPI_BAUDRATEPRESCALER_256);
spi_readwrite(0xff);
SPI_setspeed(SPI_BAUDRATEPRESCALER_2);
}
if(res)
return STA_NOINIT;
else
return RES_OK;
③修改USER_status 函数
switch (pdrv)
{
case 0 :
return RES_OK;
case 1 :
return RES_OK;
case 2 :
return RES_OK;
default:
return STA_NOINIT;
}
④修改USER_read 函数
uint8_t res;
if( !count )
{
return RES_PARERR;
}
switch (pdrv)
{
case 0:
res=SD_ReadDisk(buff,sector,count);
if(res == 0){
return RES_OK;
}else{
return RES_ERROR;
}
default:
return RES_ERROR;
}
⑤修改USE_WRITE 函数
uint8_t res;
if( !count )
{
return RES_PARERR;
}
switch (pdrv)
{
case 0:
res=SD_WriteDisk((uint8_t *)buff,sector,count);
if(res == 0){
return RES_OK;
}else{
return RES_ERROR;
}
default:return RES_ERROR;
}
⑥修改USE_IOCTL 函数
DRESULT res;
switch(cmd)
{
case CTRL_SYNC:
SD_CS(1);
do{
HAL_Delay(20);
}while(spi_readwrite(0xFF)!=0xFF);
res=RES_OK;
SD_CS(0);
break;
case GET_SECTOR_SIZE:
*(WORD*)buff = 512;
res = RES_OK;
break;
case GET_BLOCK_SIZE:
*(WORD*)buff = 8;
res = RES_OK;
break;
case GET_SECTOR_COUNT:
*(DWORD*)buff = SD_GetSectorCount();
res = RES_OK;
break;
default:
res = RES_PARERR;
break;
}
return res;
(三)main文件配置
包含头文件
#include "SDdriver.h"
在main函数前添加变量与函数定义
uint16_t uart_value[3];
uint8_t aRxBuffer1;
void WritetoSD(BYTE write_buff[],uint8_t bufSize);
char SD_FileName[] = "test.txt";
uint8_t WriteBuffer[] = "山有木兮\r\n";
uint8_t write_cnt =0;
void WritetoSD(BYTE write_buff[],uint8_t bufSize)
{
FATFS fs;
FIL file;
uint8_t res=0;
UINT Bw;
res = SD_init();
if(res == 1)
{
printf("SD卡初始化失败! \r\n");
}
res=f_mount(&fs,"0:",1);
if(res == FR_NO_FILESYSTEM)
{
printf("没有文件系统! \r\n");
res = f_mkfs("", 0, 0);
if(res == FR_OK)
{
res = f_mount(NULL,"0:",1);
res = f_mount(&fs,"0:",1);
if(res == FR_OK)
{
}
}
else
{
printf("格式化失败! \r\n");
}
}
else if(res == FR_OK)
{
}
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)
{
res = f_write(&file,write_buff,bufSize,&Bw);
if(res == FR_OK)
{
printf("文件写入成功! \r\n");
}
else
{
printf("文件写入失败! \r\n");
}
}
else
{
printf("打开文件失败!\r\n");
}
f_close(&file);
f_mount(NULL,"0:",1);
}
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();
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;
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);
}
}
将main函数替代为以下内容
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI1_Init();
MX_FATFS_Init();
MX_USART1_UART_Init();
HAL_UART_Receive_IT(&huart1,&aRxBuffer1,1);
printf(" mian \r\n");
Get_SDCard_Capacity();
while (1)
{
WritetoSD(WriteBuffer,sizeof(WriteBuffer));
printf("writing\r\n");
}
}
(四)其他配置及接线
在usart.c中重定向printf()函数
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (unsigned char *)&ch, 1, 0xFFFF);
return ch;
}
在usart.h声明并包含头文件stdio.h 打开Micro LIB 编译完成即可 本实验是基于源码自己重新新建了一个工程,如果怕麻烦,可直接下载源码
源码: 提取码27r2
三、实例演示
接线方式
SD卡 | stm32系统板 |
---|
CS | PA4 | SCK | PA5 | MISO | PA6 | MOSI | PA7 | VCC | 5V | GND | GND |
上位机显示
初始化成功,正在写入数据
写数据成功,查看已写好的数据
总结
驱动SD卡的时候,最好将供电电压提高到5V,提高更强的驱动能力。我之前默认使用3.3v由于驱动能力不够,所以一直初始化失败,卡顿了好久。所以基于硬件,稍微有一点有错就会导致整体失败,要特别注意细节。
STM32用cube配置FATFS模式下SPI读写SD卡
|