本文基于STM32H750核心,学习使用SDMMC1(SDIO)外设,用CubeMX创建HAL库工程,用SDIO读取TF卡,用FATFS文件系统读出里面的文件。
文末有工程链接。
一、CubeMX创建工程
这里跳过H750时钟的配置,主要是SDMMC1(SDIO)的配置和FATFS文件系统配置。因为CubeMX自带了FATFS,所以不需要去网上拷贝。
再配置一个串口,方便打印信息查看状态。
FAT需要选择一个检测SDIO插入的GPIO引脚,可以任意选择一个GPIO脚,然后在代码里把检测的代码注释掉,也可以不选择GPIO引脚,但是生成工程时会警告。
二、代码
在keil里选择Use microlib,然后做printf的重定向。
int fputc(int ch , FILE*f)
{
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch , 1 , 0xffff);
return ch;
}
1.f_mount挂载
FRESULT f_mount (
FATFS* fs, /* Pointer to the file system object (NULL:unmount)*/
const TCHAR* path, /* Logical drive number to be mounted/unmounted */
BYTE opt /* Mode option 0:Do not mount (delayed mount), 1:Mount immediately */
)
@fs:文件系统指针
@path:挂载路径
@ opt:操作,0-卸载 1-挂载
2.f_open()打开文件
FRESULT f_open (
FIL* fp, /* Pointer to the blank file object */
const TCHAR* path, /* Pointer to the file name */
BYTE mode /* Access mode and file open mode flags */
)
@fp:文件指针
@path:文件路径
@mode:方式
#define FA_READ 0x01
#define FA_WRITE 0x02
#define FA_OPEN_EXISTING 0x00
#define FA_CREATE_NEW 0x04
#define FA_CREATE_ALWAYS 0x08
#define FA_OPEN_ALWAYS 0x10
#define FA_OPEN_APPEND 0x30
3.f_read()和f_write()
FRESULT f_write (
FIL* fp, /* Pointer to the file object */
const void* buff, /* Pointer to the data to be written */
UINT btw, /* Number of bytes to write */
UINT* bw /* Pointer to number of bytes written */
)
@fp:文件指针
@buff:写入的字节
@btw:要写入的长度(这个是我们需要写入的长度)
@bw:写入了的长度(这里会返回一个它实际写入的长度,通过比较这两个长度可以知道写入是否成功)
FRESULT f_read (
FIL* fp, /* Pointer to the file object */
void* buff, /* Pointer to data buffer */
UINT btr, /* Number of bytes to read */
UINT* br /* Pointer to number of bytes read */
)
@btr:要读出的字节长度
@br:实际读出的字节长度
三、测试
//在全局变量中定义:
FRESULT f_res; /* 操作结果 */
FATFS fs; /* FAT句柄 */
FIL file; /* 文件句柄 */
uint16_t bw; /* 写入字节长度 */
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_SDMMC1_SD_Init();
MX_USART1_UART_Init();
MX_FATFS_Init();
/* USER CODE BEGIN 2 */
printf("初始化成功\n");
f_res = f_mount(&fs , "0:" , 1); //0:不挂载 1:挂载
if(f_res != FR_OK)
{
printf("挂载失败\n");
}
f_res = f_open(&file , "0:test.txt" , FA_OPEN_ALWAYS|FA_WRITE); //如果文件存在则打开,如果文件不存在则创建并打开
if(f_res != FR_OK)
{
printf("打开文件失败\n");
}
f_res = f_write(&file , "test hello world" , 16 , &bw);
if(f_res != FR_OK)
{
printf("写入失败\n");
}
f_res = f_close(&file);
if(f_res != FR_OK)
{
printf("关闭文件失败\n");
}
f_res = f_mount(&fs , "0:" , 0); //0:不挂载 1:挂载
if(f_res != FR_OK)
{
printf("卸载失败\n");
}
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
从读卡器中可以读出,测试成功。
注意:文件指针、系统指针要放在全局变量,不要放在main函数里,不然跑不起,没搞明报什么原因。
测试工程下载:提取码:ebo7