OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9759|回复: 38

【分享】用STM32CubeMX快速生成一个SD卡读写程序

[复制链接]

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
金钱
1730
注册时间
2016-3-8
在线时间
678 小时
发表于 2016-6-4 16:35:07 | 显示全部楼层 |阅读模式
本帖最后由 adlu 于 2016-6-4 16:41 编辑

本帖介绍一个用 STM32CubeMX 快速生成一个 SD 卡读写程序的方法。

程序员只需要简单的配置步骤,就可以创建一个MDK工程。

输入少量代码,无需了解SD卡底层操作和繁杂的初始化过程,即可实现对SD卡扇区读/写访问。

真正的做到了解放程序员的目的,让程序员可以把精力放在更重要的事情上。

由于主要是配置操作,图片较多,因此只上传两张图片,有兴趣的朋友可以下载文档查看。
1.jpg
2.jpg
用STM32CubeMX快速生成一个SD卡读写程序.pdf (1.35 MB, 下载次数: 2455)
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

27

主题

711

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
12222
金钱
12222
注册时间
2015-11-5
在线时间
2117 小时
发表于 2016-6-4 21:42:28 | 显示全部楼层
回复 支持 反对

使用道具 举报

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
金钱
1730
注册时间
2016-3-8
在线时间
678 小时
 楼主| 发表于 2016-6-6 10:03:19 | 显示全部楼层

官方提供这么好用的工具,貌似坛子里没多少人使用Cube开发,可惜了。
回复 支持 反对

使用道具 举报

7

主题

185

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2729
金钱
2729
注册时间
2015-12-27
在线时间
469 小时
发表于 2016-6-7 11:22:23 | 显示全部楼层
adlu 发表于 2016-6-6 10:03
官方提供这么好用的工具,貌似坛子里没多少人使用Cube开发,可惜了。

至少我不愿意用的原因是,太难用了,用的不习惯
回复 支持 反对

使用道具 举报

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
金钱
1730
注册时间
2016-3-8
在线时间
678 小时
 楼主| 发表于 2016-6-7 12:06:44 | 显示全部楼层
钩月黄昏 发表于 2016-6-7 11:22
至少我不愿意用的原因是,太难用了,用的不习惯

刚开始我也觉得很难用。主要障碍不是软件本身,而是HAL库的使用方法。
现在搞清楚了,用起来很轻松。特别是在外设的配置上,可以节约很多时间。
Cube对于FATFS和FREERTOS等中间件的支持,更显示了其强大的威力。
回复 支持 反对

使用道具 举报

7

主题

185

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2729
金钱
2729
注册时间
2015-12-27
在线时间
469 小时
发表于 2016-6-7 13:11:51 | 显示全部楼层
adlu 发表于 2016-6-7 12:06
刚开始我也觉得很难用。主要障碍不是软件本身,而是HAL库的使用方法。
现在搞清楚了,用起来很轻松。特 ...

看来我得强迫自己体验一下了
回复 支持 反对

使用道具 举报

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
金钱
1730
注册时间
2016-3-8
在线时间
678 小时
 楼主| 发表于 2016-6-7 14:27:04 | 显示全部楼层
本帖最后由 adlu 于 2016-6-7 14:28 编辑
钩月黄昏 发表于 2016-6-7 13:11
看来我得强迫自己体验一下了

从我的亲身体验说,真的值得一试!

你可以试一下,用标准库完成本帖这个SD卡读写程序的功能。如果是移植别人的程序,可能会快一点。如果从SDIO配置,到SD卡初始化,再到扇区读写都是自己一步一步做的话,没有三五天是搞不定的(当然是根据我自己的水平来说),而且未必好用。先不说SD卡初始化的复杂流程了,就是SDIO+DMA配置要查的寄存器,就够花半天时间的了。
按照本帖的方法,用Cube配置,最多20分钟。

其实HAL库基本的外设操作跟标准库的没有太大区别,最大的区别应该是回调函数机制,明白这个机制之后就用的比较顺手了。
比如,可以先从UART的使用就是这样,刚开始的时候,感觉根本不会用,真TM难用。然后就停用了一段时间。后来静下心来分析清楚了其中的流程,总算走上正轨了。

在此特别强调一下,我不特意为谁打广告,是真心推荐STM32CubeMX。
本帖的实验我是在正点原子的探索者开发板上进行的,当然也可以在任何使用SDIO访问SD卡的开发板上进行。
回复 支持 反对

使用道具 举报

7

主题

185

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2729
金钱
2729
注册时间
2015-12-27
在线时间
469 小时
发表于 2016-6-7 14:34:30 | 显示全部楼层
adlu 发表于 2016-6-7 14:27
从我的亲身体验说,真的值得一试!

你可以试一下,用标准库完成本帖这个SD卡读写程序的功能。如果是移 ...

我正在试了
回复 支持 反对

使用道具 举报

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
金钱
1730
注册时间
2016-3-8
在线时间
678 小时
 楼主| 发表于 2016-6-7 14:38:15 | 显示全部楼层

坛子里Cube的帖子很少,在STM社区有比较多人在研究,可以到那儿看看。
回复 支持 反对

使用道具 举报

26

主题

193

帖子

8

精华

金牌会员

Rank: 6Rank: 6

积分
1800
金钱
1800
注册时间
2012-8-23
在线时间
57 小时
发表于 2016-6-7 17:42:17 | 显示全部楼层
楼主用哪些容量的卡测试过?比如8G,16G,32G的卡测试下试试?
回复 支持 反对

使用道具 举报

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
金钱
1730
注册时间
2016-3-8
在线时间
678 小时
 楼主| 发表于 2016-6-8 08:49:41 | 显示全部楼层
beyond696 发表于 2016-6-7 17:42
楼主用哪些容量的卡测试过?比如8G,16G,32G的卡测试下试试?

手上只有4G,8G卡,测试了没问题。再大的没测。

如果你测了,请告诉我结果。
回复 支持 反对

使用道具 举报

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
金钱
1730
注册时间
2016-3-8
在线时间
678 小时
 楼主| 发表于 2016-6-12 12:08:06 | 显示全部楼层
本帖最后由 adlu 于 2016-6-14 16:44 编辑
beyond696 发表于 2016-6-7 17:42
楼主用哪些容量的卡测试过?比如8G,16G,32G的卡测试下试试?

已经测试。32G,64G,128G都没问题!
回复 支持 反对

使用道具 举报

0

主题

9

帖子

0

精华

初级会员

Rank: 2

积分
170
金钱
170
注册时间
2016-1-28
在线时间
40 小时
发表于 2016-6-14 16:02:00 | 显示全部楼层
谢谢楼主分享!
回复 支持 反对

使用道具 举报

10

主题

146

帖子

0

精华

高级会员

Rank: 4

积分
764
金钱
764
注册时间
2015-12-19
在线时间
99 小时
发表于 2016-6-19 13:50:29 | 显示全部楼层
学习   楼主这个官方提供的  现在确实很少有人用  
回复 支持 反对

使用道具 举报

4

主题

34

帖子

0

精华

初级会员

Rank: 2

积分
88
金钱
88
注册时间
2016-5-28
在线时间
14 小时
发表于 2016-6-21 10:18:11 | 显示全部楼层
谢谢分享 学习下
回复 支持 反对

使用道具 举报

4

主题

47

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
299
金钱
299
注册时间
2014-10-26
在线时间
29 小时
发表于 2016-6-28 11:36:44 | 显示全部楼层
跟原来的代码框架差异太大,现在不考虑。
回复 支持 反对

使用道具 举报

5

主题

62

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
425
金钱
425
注册时间
2016-3-9
在线时间
74 小时
发表于 2016-8-29 17:00:20 | 显示全部楼层
mark一下
回复 支持 反对

使用道具 举报

6

主题

54

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2015-3-9
在线时间
20 小时
发表于 2016-9-9 14:40:19 | 显示全部楼层
配置完成正确,不知道哪里出问题了,读不出来数据,但是初始化能过
回复 支持 反对

使用道具 举报

6

主题

54

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2015-3-9
在线时间
20 小时
发表于 2016-9-9 15:25:20 | 显示全部楼层
释怀过客 发表于 2016-9-9 14:40
配置完成正确,不知道哪里出问题了,读不出来数据,但是初始化能过

可以读了,怎么加Fatfs文件系统呢?求指导
回复 支持 反对

使用道具 举报

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
金钱
1730
注册时间
2016-3-8
在线时间
678 小时
 楼主| 发表于 2016-9-9 16:18:05 | 显示全部楼层
释怀过客 发表于 2016-9-9 15:25
可以读了,怎么加Fatfs文件系统呢?求指导

请参考另一帖“【分享】用STM32CubeMX快速生成一个SDIO+FATFS程序”。
http://www.openedv.com/forum.php ... mp;extra=#pid475355
回复 支持 反对

使用道具 举报

6

主题

54

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2015-3-9
在线时间
20 小时
发表于 2016-9-9 16:57:30 | 显示全部楼层
adlu 发表于 2016-9-9 16:18
请参考另一帖“【分享】用STM32CubeMX快速生成一个SDIO+FATFS程序”。
http://www.openedv.com/forum.ph ...

初始化能过,读写不行是什么原因的啊
回复 支持 反对

使用道具 举报

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
金钱
1730
注册时间
2016-3-8
在线时间
678 小时
 楼主| 发表于 2016-9-9 17:08:26 | 显示全部楼层
释怀过客 发表于 2016-9-9 16:57
初始化能过,读写不行是什么原因的啊

这个笼统的问题,只能给你个笼统的答案。
可能原因有:硬件连接问题,SD卡问题,SDIO速度太快。
回复 支持 反对

使用道具 举报

6

主题

54

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2015-3-9
在线时间
20 小时
发表于 2016-9-9 17:32:27 | 显示全部楼层
adlu 发表于 2016-9-9 17:08
这个笼统的问题,只能给你个笼统的答案。
可能原因有:硬件连接问题,SD卡问题,SDIO速度太快。

能读回来SD卡的的信息,(内存),但是进行读写的时候就卡主了。你另外帖子里附件弄进去了吗
回复 支持 反对

使用道具 举报

6

主题

54

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2015-3-9
在线时间
20 小时
发表于 2016-9-9 17:41:55 | 显示全部楼层
adlu 发表于 2016-9-9 17:08
这个笼统的问题,只能给你个笼统的答案。
可能原因有:硬件连接问题,SD卡问题,SDIO速度太快。

  while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT))
  {
  }    用在线调试,程序卡死在这里
回复 支持 反对

使用道具 举报

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
金钱
1730
注册时间
2016-3-8
在线时间
678 小时
 楼主| 发表于 2016-9-10 08:30:34 | 显示全部楼层
释怀过客 发表于 2016-9-9 17:41
while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) ...

这个问题我遇到过。但是忘了是怎么解决的了。
你看一下SDIO+FATFS的那个帖子,我在探索者F4开发板上验证过,确认没问题。
如遇问题,请继续留言。
回复 支持 反对

使用道具 举报

6

主题

54

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2015-3-9
在线时间
20 小时
发表于 2016-9-10 15:23:12 | 显示全部楼层
adlu 发表于 2016-9-10 08:30
这个问题我遇到过。但是忘了是怎么解决的了。
你看一下SDIO+FATFS的那个帖子,我在探索者F4开发板上验证 ...

好的,我试一下,谢谢!
回复 支持 反对

使用道具 举报

6

主题

54

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2015-3-9
在线时间
20 小时
发表于 2016-9-11 11:21:50 | 显示全部楼层
adlu 发表于 2016-9-10 08:30
这个问题我遇到过。但是忘了是怎么解决的了。
你看一下SDIO+FATFS的那个帖子,我在探索者F4开发板上验证 ...

if(f_open(&MyFile, "STM32.TXT", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
      {
        /* 'STM32.TXT' file Open for write Error */
        while(1);
      }
Debuge程序死在这里,   操作完成正确,堆栈也改了,但是依旧只能初始化通过,并不能进行读写操作,表示很奇怪
回复 支持 反对

使用道具 举报

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
金钱
1730
注册时间
2016-3-8
在线时间
678 小时
 楼主| 发表于 2016-9-12 08:59:09 | 显示全部楼层
释怀过客 发表于 2016-9-9 17:41
while(!__HAL_SD_SDIO_GET_FLAG(hsd, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT)) ...

参考该帖,http://www.stmcu.org/module/forum/thread-605532-1-1.html
请确认SDIO使用DMA。
回复 支持 反对

使用道具 举报

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
金钱
1730
注册时间
2016-3-8
在线时间
678 小时
 楼主| 发表于 2016-9-12 09:06:16 | 显示全部楼层
释怀过客 发表于 2016-9-11 11:21
if(f_open(&MyFile, "STM32.TXT", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
      {
        /* 'STM ...

请先查看SD卡,确认SD卡是否进行了写保护。
或者先在电脑上进行操作,写文件进去,或者格式化SD卡。

调试的时候,写个变量res = f_open( ),看看res是什么值,对应的错误是什么。
回复 支持 反对

使用道具 举报

6

主题

54

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2015-3-9
在线时间
20 小时
发表于 2016-9-12 11:44:05 | 显示全部楼层
adlu 发表于 2016-9-12 09:06
请先查看SD卡,确认SD卡是否进行了写保护。
或者先在电脑上进行操作,写文件进去,或者格式化SD卡。

错误在SD_DATA_TIMEOUT
回复 支持 反对

使用道具 举报

6

主题

54

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2015-3-9
在线时间
20 小时
发表于 2016-9-12 11:44:31 | 显示全部楼层
adlu 发表于 2016-9-12 08:59
参考该帖,http://www.stmcu.org/module/forum/thread-605532-1-1.html
请确认SDIO使用DMA。

DMA用了
回复 支持 反对

使用道具 举报

6

主题

54

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2015-3-9
在线时间
20 小时
发表于 2016-9-12 16:36:23 | 显示全部楼层
adlu 发表于 2016-9-12 09:06
请先查看SD卡,确认SD卡是否进行了写保护。
或者先在电脑上进行操作,写文件进去,或者格式化SD卡。

res = 0X0D,  FR_NO_FILESYSTEM,                /* (13) There is no valid FAT volume */  这个错误,该怎么解决呢?
回复 支持 反对

使用道具 举报

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
金钱
1730
注册时间
2016-3-8
在线时间
678 小时
 楼主| 发表于 2016-9-12 16:47:20 | 显示全部楼层
释怀过客 发表于 2016-9-12 16:36
res = 0X0D,  FR_NO_FILESYSTEM,                /* (13) There is no valid FAT volume */  这个错误,该怎么解决呢?

贴你的main函数出来看看
回复 支持 反对

使用道具 举报

6

主题

54

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2015-3-9
在线时间
20 小时
发表于 2016-9-12 17:14:41 | 显示全部楼层
adlu 发表于 2016-9-12 16:47
贴你的main函数出来看看

int main(void)
{

  /* USER CODE BEGIN 1 */
        FRESULT res;                                          /* FatFs function common result code */
  uint32_t byteswritten, bytesread;                     /* File write/read counts */
  uint8_t wtext[] = "This is STM32 working with FatFs"; /* File write buffer */
  uint8_t rtext[100];                                   /* File read buffer */
  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_SDIO_SD_Init();
  MX_FATFS_Init();

  /* USER CODE BEGIN 2 */
//        BSP_SD_Init();
        BSP_SD_GetCardInfo(&SDCardInfo);
  /* USER CODE END 2 */

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

  /* USER CODE BEGIN 3 */
                if(f_mount(&SDFatFs, (TCHAR const*)SD_Path, 0) != FR_OK)
                {
                        /* FatFs Initialization Error */
                        while(1);
                }
                else
                {
                                /* Create and Open a new text file object with write access */
//                                if(f_open(&MyFile, "STM32.TXT", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
//                                {
//                                        /* 'STM32.TXT' file Open for write Error */
//                                        while(1);
//                                }
                        ret_Error = f_open(&MyFile, "STM32.TXT", FA_CREATE_ALWAYS | FA_WRITE);
                        if(ret_Error != FR_OK)
                        {
                                if(ret_Error == FR_NO_FILESYSTEM)
                                {
                                        HAL_GPIO_WritePin(GPIOD,GPIO_PIN_12,GPIO_PIN_SET);
                                }
                                while(1);
                        }
                                else
                                {
                                        /* Write data to the text file */
                                        res = f_write(&MyFile, wtext, sizeof(wtext), (void *)&byteswritten);
                                       
                                        if((byteswritten == 0) || (res != FR_OK))
                                        {
                                                /* 'STM32.TXT' file Write or EOF Error */
                                                while(1);
                                        }
                                        else
                                        {
                                                /* Close the open text file */
                                                f_close(&MyFile);
                                               
                                        /* Open the text file object with read access */
                                        if(f_open(&MyFile, "STM32.TXT", FA_READ) != FR_OK)
                                        {
                                                /* 'STM32.TXT' file Open for read Error */
                                                while(1);
                                        }
                                        else
                                        {
                                                /* Read data from the text file */
                                                res = f_read(&MyFile, rtext, sizeof(rtext), (void *)&bytesread);
                                               
                                                if((bytesread == 0) || (res != FR_OK))
                                                {
                                                        /* 'STM32.TXT' file Read or EOF Error */
                                                        while(1);
                                                }
                                                else
                                                {
                                                        /* Close the open text file */
                                                        f_close(&MyFile);
                                                       
                                                        /* Compare read data with the expected data */
                                                        if((bytesread != byteswritten))
                                                        {               
                                                                /* Read data is different from the expected data */
                                                                while(1);
                                                        }
                                                        else
                                                        {
                                                /* Success of the demo: no error occurrence */
                                                                while(1);
                                                        }
                                                }
                                        }
                                }
                        }
                }
  }
  /* USER CODE END 3 */

}
回复 支持 反对

使用道具 举报

6

主题

54

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
251
金钱
251
注册时间
2015-3-9
在线时间
20 小时
发表于 2016-9-12 17:16:10 | 显示全部楼层
adlu 发表于 2016-9-12 16:47
贴你的main函数出来看看

在线调试,程序卡在
if(ret_Error != FR_OK)
                        {
                                if(ret_Error == FR_NO_FILESYSTEM)
                                {
                                        HAL_GPIO_WritePin(GPIOD,GPIO_PIN_12,GPIO_PIN_SET);
                                }
                                while(1);
                        }
这个里面,错误类型res = 0X0D,  FR_NO_FILESYSTEM,                /* (13) There is no valid FAT volume */
回复 支持 反对

使用道具 举报

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
金钱
1730
注册时间
2016-3-8
在线时间
678 小时
 楼主| 发表于 2016-9-12 17:53:38 | 显示全部楼层
释怀过客 发表于 2016-9-12 17:16
在线调试,程序卡在
if(ret_Error != FR_OK)
                        {

我在探索者开发板测试了,没有遇到你说的问题。
另外,我发的pdf里面描述的,用户测试的代码放在while(1)之前,在下面两个注释行之间。
/* USER CODE BEGIN 2 */
测试代码放在这里
/* USER CODE END 2 */
回复 支持 反对

使用道具 举报

盼盼 该用户已被删除
发表于 2016-12-6 11:18:04 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

12

主题

228

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1730
金钱
1730
注册时间
2016-3-8
在线时间
678 小时
 楼主| 发表于 2016-12-6 11:53:34 | 显示全部楼层
本帖最后由 adlu 于 2016-12-6 11:54 编辑
盼盼 发表于 2016-12-6 11:18
想咨询一下128G的卡使用FAT是否可以正常操作文件创建以及读写?我用的探索者F407,用的FAT的例程,4G的卡 ...

参考此帖“用STM32CubeMX快速生成一个SDIO+FATFS程序”
http://www.openedv.com/forum.php ... =1&extra=#pid475355

自己测试一下就知道结果了
回复 支持 反对

使用道具 举报

盼盼 该用户已被删除
发表于 2016-12-7 11:26:54 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-3-1 20:08

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表