STM32F407ZG cubemx+SDIO+ DMA+FATFS +FreeRtos使用记录
cubemx+SDIO+ DMA+FATFS +FreeRtos使用记录)
前言
历经三个星期,终于把sd卡读写测试弄出来了
这边主要是靠这位博主的教程
版权声明:本文为CSDN博主「zl199203」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zl199203/article/details/83513768
建议看完再来
一、普通方式控制SD
一步步跟着上面博主的步骤之后,可能会发现并不能达到他的效果
但是评论区有位小哥的方法挺好用的
在/* USER CODE BEGIN 2 /与 / USER CODE END 2 */之间
调用
HAL_SD_InitCard(&hsd);
(这个超关键!!)
具体位置如下:
再编译一下应该就可以了
但如果还不行
建议把板子断电然后重新插拔sd卡
ps:这方法可能只适用我这板子也有可能,但可以尝试一下
二、使用DMA控制SDIO
上面操作完,能出现上面推荐博主的测试结果就可以
看他的第二篇文章
这边我也给出链接
https://blog.csdn.net/zl199203/article/details/83514030
这边跟着博主的步骤走没什么大问题
但我一开始还是卡住了
因为一个DMA2的时钟使能位置的问题
这边我提供俩个修改方法
- 直接修改初始化顺序
如果你一开始的程序初始化顺序是这样的
那么你可以把MX_DMA_Init();剪切了
然后粘贴到MX_SDIO_SD_Init();函数的上面
如图
就调换一下顺序就行
2.在sdio.c文件下添加代码
可以保持上面第一张图片的顺序不变
打开sdio.c文件
找到HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)
这个函数 你会看到
然后在红框里的空白处 添加代码
__HAL_RCC_DMA2_CLK_ENABLE();
//这句话可以在MX_DMA_Init();函数里找到
效果如图
然后编译
但如果还不行
也建议把板子断电然后重新插拔sd卡
亲身尝试过还是挺有效
三、使用FatFs文件系统
一样贴上博主文章的链接
https://blog.csdn.net/zl199203/article/details/83514105
如果您跟我用的是同一个板子(正点原子探索者)的话
我尝试过博主后面添加的 做出来达不到博主的效果
接下来重点来了!
只要添加几句代码就可以实现博主的效果
首先我们现在/* USER CODE END PV */上面
添加代码
BYTE work[512];
效果如图
然后去到main()函数
添加代码(前提是你有bsp_driver_sd.c文件 ,这个好像是用stm32cubemx配出来的)
BSP_SD_Init();
f_mkfs((TCHAR const*)SDPath,FM_ANY,0,work,512);
具体位置如下:
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_SDIO_SD_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
BSP_SD_Init();//添加的
MX_FATFS_Init();
f_mkfs((TCHAR const*)SDPath,FM_ANY,0,work,512);//添加的
/* USER CODE BEGIN 2 */
HAL_SD_InitCard(&hsd);
// SD_EraseTest();
// SD_Write_Read_Test();
Fatfs_RW_test();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}。
/* USER CODE END 3 */
}
添加完成后应该就可以了
这边我附上 f_mkfs()函数里参数的定义 担心有朋友可能没有
work : 上面第一步已经定义好了
SDPath: 我这边好像是自动定义在fatfs.c 和fatfs.h
fatfs.c :
uint8_t retSD; /* Return value for SD */
char SDPath[4]; /* SD logical drive path */
FATFS SDFatFS; /* File system object for SD logical drive */
FIL SDFile; /* File object for SD */
fatfs.h
extern uint8_t retSD; /* Return value for SD */
extern char SDPath[4]; /* SD logical drive path */
extern FATFS SDFatFS; /* File system object for SD logical drive */
extern FIL SDFile; /* File object for SD */
FM_ANY: 定义在ff.h(这也是自动生成的,应该都有)
#define FM_ANY 0x07
四、添加FreeRtos支持。
一样附上博主的链接
https://blog.csdn.net/zl199203/article/details/83514223
这边感觉跟我们界面开始有点不太一样了
主要附上cubemx配置 FREERTOS界面 其他没放出来的 都跟前面的差不多
NVIC :
然后生成代码后
把之前的下面这句代码在main()里的注释掉或者剪切
BSP_SD_Init();
MX_FATFS_Init();
f_mkfs((TCHAR const*)SDPath,FM_ANY,0,work,512);
HAL_SD_InitCard(&hsd);
Fatfs_RW_test();
然后把上面几句放在freertos.c文件下的
void StartDefaultTask(void *argument)函数里
函数内容如下:
void StartDefaultTask(void *argument)
{
/* USER CODE BEGIN StartDefaultTask */
BSP_SD_Init();
MX_FATFS_Init();
f_mkfs((TCHAR const*)SDPath,FM_ANY,0,work,512);
HAL_SD_InitCard(&hsd);
Fatfs_RW_test();
/* Infinite loop */
for(;;)
{
osDelay(1);
}
/* USER CODE END StartDefaultTask */
}
然后main()是这样的就可以了
总结
第一次写博客
有些地方可能不太好
还请见谅
希望能帮到大家!
谢谢