你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

查看: 5546|回复: 4

【HAL库每天一例】第044例: SDIO-基于SD卡FatFS文件系统

[复制链接]

122

主题

129

回帖

0

蝴蝶豆

论坛元老

最后登录
2019-5-28
发表于 2016-6-18 09:28:52 | 显示全部楼层 |阅读模式
【HAL库每天一例】系列例程从今天开始持续更新。。。。。
我们将坚持每天至少发布一个基于YS-F1Pro开发板的HAL库例程,
该系列例程将带领大家从零开始使用HAL库,后面会持续添加模块应用例程。
同样的,我们还程序发布基于HAL库的指导文档和视频教程,欢迎持续关注,并提出改进意见。
例程下载:
资料包括程序、相关说明资料以及软件使用截图
链接:https://pan.baidu.com/s/1i574oPv
密码:r3s3
(硬石YS-F1Pro开发板HAL库例程持续更新\1. 软件设计之基本裸机例程(HAL库版本)YSF1_HAL-043. SDIO-SD卡读写

/**
  ******************************************************************************
  *                           硬石YS-F1Pro开发板例程功能说明
  *
  *  例程名称: YSF1_HAL-044. SDIO-基于SD卡FatFS文件系统
  *   
  ******************************************************************************
  * 说明:
  * 本例程配套硬石stm32开发板YS-F1Pro使用。
  *
  * 淘宝:
  * 论坛:www ing10bbs com
  * 版权归硬石嵌入式开发团队所有,请勿商用。
  ******************************************************************************
  */

【1】例程简介
  SDIO是安全输入输出接口,采用在SD卡上。SD卡做为一种性价比极高的存储介质,在生活中非常
普遍可见。
  上个例程是直接对SD卡进行读写操作,一般使用SD卡都需要通过文件系统,使得类似电脑操作文件
一样简单明了。
  FatFS是一个专门为嵌入式开发的开源小型文件系统。
  本例程移植FatFS,实现SD卡文件读写。
  
【2】跳线帽情况
******* 为保证例程正常运行,必须插入以下跳线帽 **********
丝印编号     IO端口      目标功能引脚        出厂默认设置
  JP1        PA10        TXD(CH340G)          已接入
  JP2        PA9         RXD(CH340G)          已接入
  
【3】操作及现象
  将一张小于32G大小的Micro SD卡插入到开发板上的SD卡槽内,使用开发板配套的MINI USB线连
接到开发板标示“调试串口”字样的MIMI USB接口(需要安装驱动),在电脑端打开串口调试助手
工具,设置参数为115200 8-N-1。下载完程序之后,在串口调试助手窗口可接收到信息。

/******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/

CubeMX_1.jpg
CubeMX_2.jpg
CubeMX_3.jpg
CubeMX_4.jpg
CubeMX_5.jpg
CubeMX_6.jpg
CubeMX_7.jpg
CubeMX_8.jpg
CubeMX_9.jpg
CubeMX_10.jpg


bsp_sdcard.c文件内容
  1. /**
  2.   ******************************************************************************
  3.   * 文件名程: bsp_sdcard.c
  4.   * 作    者: 硬石嵌入式开发团队
  5.   * 版    本: V1.0
  6.   * 编写日期: 2015-10-04
  7.   * 功    能: SD卡底层驱动实现
  8.   ******************************************************************************
  9.   * 说明:
  10.   * 本例程配套硬石stm32开发板YS-F1Pro使用。
  11.   *
  12.   * 淘宝:
  13.   * 论坛:http://www.ing10bbs.com
  14.   * 版权归硬石嵌入式开发团队所有,请勿商用。
  15.   ******************************************************************************
  16.   */

  17. /* 包含头文件 ----------------------------------------------------------------*/
  18. #include "sdio/bsp_sdcard.h"

  19. /* 私有类型定义 --------------------------------------------------------------*/
  20. /* 私有宏定义 ----------------------------------------------------------------*/
  21. /* 私有变量 ------------------------------------------------------------------*/
  22. SD_HandleTypeDef hsdcard;
  23. HAL_SD_CardInfoTypedef SDCardInfo;
  24. DMA_HandleTypeDef hdma_sdio;

  25. /* 扩展变量 ------------------------------------------------------------------*/
  26. /* 私有函数原形 --------------------------------------------------------------*/
  27. /* 函数体 --------------------------------------------------------------------*/
  28. /**
  29.   * 函数功能: SD卡初始化配置
  30.   * 输入参数: 无
  31.   * 返 回 值: 无
  32.   * 说    明: 无
  33.   */
  34. void MX_SDIO_SD_Init(void)
  35. {
  36.   hsdcard.Instance = SDIO;
  37.   hsdcard.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
  38.   hsdcard.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
  39.   hsdcard.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
  40.   hsdcard.Init.BusWide = SDIO_BUS_WIDE_1B;
  41.   hsdcard.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
  42.   hsdcard.Init.ClockDiv = 2;
  43.   HAL_SD_Init(&hsdcard, &SDCardInfo);
  44.   
  45.   HAL_SD_WideBusOperation_Config(&hsdcard, SDIO_BUS_WIDE_4B); // 设置为4bit SDIO
  46. }

  47. /**
  48.   * 函数功能: SDIO外设初始化配置
  49.   * 输入参数: hsd:SDIO句柄类型指针
  50.   * 返 回 值: 无
  51.   * 说    明: 该函数被HAL库内部调用
  52.   */
  53. void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
  54. {
  55.   GPIO_InitTypeDef GPIO_InitStruct;
  56.   if(hsd->Instance==SDIO)
  57.   {
  58.     /* 使能SDIO外设时钟*/
  59.     __HAL_RCC_SDIO_CLK_ENABLE();
  60.    
  61.     /* Enable DMA2 clocks */
  62.     __HAL_RCC_DMA2_CLK_ENABLE();
  63.    
  64.     /* 使能GPIO端口时钟 */
  65.     __HAL_RCC_GPIOC_CLK_ENABLE();
  66.     __HAL_RCC_GPIOD_CLK_ENABLE();
  67.    
  68.     /**SDIO GPIO Configuration   
  69.     PC8     ------> SDIO_D0
  70.     PC9     ------> SDIO_D1
  71.     PC10     ------> SDIO_D2
  72.     PC11     ------> SDIO_D3
  73.     PC12     ------> SDIO_CK
  74.     PD2     ------> SDIO_CMD
  75.     */
  76.     GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
  77.                           |GPIO_PIN_12;
  78.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  79.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  80.     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  81.     GPIO_InitStruct.Pin = GPIO_PIN_2;
  82.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  83.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  84.     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
  85.    
  86.     /* 配置DMA传输:读SD卡内容时使用 */  
  87.     hdma_sdio.Instance = DMA2_Channel4;
  88.     hdma_sdio.Init.Direction = DMA_PERIPH_TO_MEMORY;
  89.     hdma_sdio.Init.PeriphInc = DMA_PINC_DISABLE;
  90.     hdma_sdio.Init.MemInc = DMA_MINC_ENABLE;
  91.     hdma_sdio.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  92.     hdma_sdio.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  93.     hdma_sdio.Init.Mode = DMA_NORMAL;
  94.     hdma_sdio.Init.Priority = DMA_PRIORITY_HIGH;
  95.     HAL_DMA_Init(&hdma_sdio);
  96.    
  97.     /* 链接SDIO的DMA接收 */
  98.     __HAL_LINKDMA(hsd,hdmarx,hdma_sdio);
  99.    
  100.     /* SDIO外设中断配置 */
  101.     HAL_NVIC_SetPriority(SDIO_IRQn, 0, 1);
  102.     HAL_NVIC_EnableIRQ(SDIO_IRQn);
  103.    
  104.     /* DMA中断配置 */
  105.     HAL_NVIC_SetPriority(DMA2_Channel4_5_IRQn, 0, 2);
  106.     HAL_NVIC_EnableIRQ(DMA2_Channel4_5_IRQn);
  107.   }
  108. }

  109. /**
  110.   * 函数功能: SDIO外设反初始化配置
  111.   * 输入参数: hsd:SDIO句柄类型指针
  112.   * 返 回 值: 无
  113.   * 说    明: 该函数被HAL库内部调用
  114.   */
  115. void HAL_SD_MspDeInit(SD_HandleTypeDef* hsd)
  116. {
  117.   if(hsd->Instance==SDIO)
  118.   {
  119.     /* 禁用SDIO时钟 */
  120.     __HAL_RCC_SDIO_CLK_DISABLE();
  121.   
  122.     /**SDIO GPIO Configuration   
  123.     PC8     ------> SDIO_D0
  124.     PC9     ------> SDIO_D1
  125.     PC10     ------> SDIO_D2
  126.     PC11     ------> SDIO_D3
  127.     PC12     ------> SDIO_CK
  128.     PD2     ------> SDIO_CMD
  129.     */
  130.     HAL_GPIO_DeInit(GPIOC, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
  131.                           |GPIO_PIN_12);

  132.     HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2);
  133.    
  134.     /* Peripheral DMA DeInit*/
  135.     HAL_DMA_DeInit(hsd->hdmarx);
  136.    
  137.     /* 关闭中断 */
  138.     HAL_NVIC_DisableIRQ(SDIO_IRQn);
  139.     HAL_NVIC_DisableIRQ(DMA2_Channel4_5_IRQn);
  140.   }
  141. }

  142. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码

sd_diskio.c文件内容
  1. /**
  2.   ******************************************************************************
  3.   * 文件名程: sd_diskio.c
  4.   * 作    者: 硬石嵌入式开发团队
  5.   * 版    本: V1.0
  6.   * 编写日期: 2015-10-04
  7.   * 功    能: SD卡与FatFS文件系统桥接函数实现
  8.   ******************************************************************************
  9.   * 说明:
  10.   * 本例程配套硬石stm32开发板YS-F1Pro使用。
  11.   *
  12.   * 淘宝:
  13.   * 论坛:http://www.ing10bbs.com
  14.   * 版权归硬石嵌入式开发团队所有,请勿商用。
  15.   ******************************************************************************
  16.   */

  17. /* 包含头文件 ----------------------------------------------------------------*/
  18. #include <string.h>
  19. #include "sdio/bsp_sdcard.h"
  20. #include "ff_gen_drv.h"

  21. /* 私有类型定义 --------------------------------------------------------------*/
  22. /* 私有宏定义 ----------------------------------------------------------------*/
  23. #define BLOCK_SIZE                512

  24. /* 私有变量 ------------------------------------------------------------------*/
  25. static volatile DSTATUS Stat = STA_NOINIT;


  26. /* 扩展变量 ------------------------------------------------------------------*/
  27. /* 私有函数原形 --------------------------------------------------------------*/
  28. DSTATUS SD_initialize (BYTE);
  29. DSTATUS SD_status (BYTE);
  30. DRESULT SD_read (BYTE, BYTE*, DWORD, UINT);

  31. #if _USE_WRITE == 1   // 如果允许写操作
  32.   DRESULT SD_write (BYTE, const BYTE*, DWORD, UINT);
  33. #endif /* _USE_WRITE == 1 */

  34. #if _USE_IOCTL == 1   // 如果输入输出操作控制
  35.   DRESULT SD_ioctl (BYTE, BYTE, void*);
  36. #endif  /* _USE_IOCTL == 1 */

  37. /* 定义SD卡接口函数 */
  38. const Diskio_drvTypeDef  SD_Driver =
  39. {
  40.   SD_initialize,                   // SD卡初始化
  41.   SD_status,                       // SD卡状态获取
  42.   SD_read,                         // SD卡读数据
  43. #if  _USE_WRITE == 1
  44.   SD_write,                        // SD卡写数据
  45. #endif /* _USE_WRITE == 1 */
  46.   
  47. #if  _USE_IOCTL == 1
  48.   SD_ioctl,                         // 获取SD卡信息
  49. #endif /* _USE_IOCTL == 1 */
  50. };

  51. /* 函数体 --------------------------------------------------------------------*/
  52. /**
  53.   * 函数功能: SD卡初始化配置
  54.   * 输入参数: 无
  55.   * 返 回 值: 无
  56.   * 说    明: 无
  57.   */
  58. DSTATUS SD_initialize(BYTE lun)
  59. {
  60.   Stat = STA_NOINIT;
  61.   /* 初始化SDIO外设 */
  62.   MX_SDIO_SD_Init();
  63.   /* 获取SD卡状态 */
  64.   if(HAL_SD_GetStatus(&hsdcard)==SD_TRANSFER_OK)
  65.   {
  66.     Stat &= ~STA_NOINIT;
  67.   }
  68.   return Stat;
  69. }

  70. /**
  71.   * 函数功能: SD卡状态获取
  72.   * 输入参数: lun : 不用
  73.   * 返 回 值: DSTATUS:SD卡状态返回值
  74.   * 说    明: 无
  75.   */
  76. DSTATUS SD_status(BYTE lun)
  77. {
  78.   Stat = STA_NOINIT;

  79.   if(HAL_SD_GetStatus(&hsdcard) == SD_TRANSFER_OK)
  80.   {
  81.     Stat &= ~STA_NOINIT;
  82.   }
  83.   return Stat;
  84. }

  85. /**
  86.   * 函数功能: 从SD卡读取数据到缓冲区
  87.   * 输入参数: lun : 不用
  88.   *           buff:存放读取到数据缓冲区指针
  89.   *           sector:扇区地址(LBA)
  90.   *           count:扇区数目
  91.   * 返 回 值: DSTATUS:操作结果
  92.   * 说    明: SD卡读操作使用DMA传输
  93.   */
  94. DRESULT SD_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)
  95. {
  96.   DRESULT res = RES_OK;
  97.   if((DWORD)buff&3)
  98.   {
  99.     DWORD scratch[BLOCK_SIZE/4];
  100.     while (count--)
  101.     {
  102.       res = SD_read(lun,(void *)scratch, sector++, 1);
  103.       if (res != RES_OK)
  104.       {
  105.         break;
  106.       }
  107.       memcpy(buff, scratch, BLOCK_SIZE);
  108.       buff += BLOCK_SIZE;
  109.     }
  110.     return res;
  111.   }
  112.   
  113.   if(HAL_SD_ReadBlocks_DMA(&hsdcard,(uint32_t*)buff,(uint64_t)(sector * BLOCK_SIZE),BLOCK_SIZE,count) != SD_OK)
  114.   {
  115.     res = RES_ERROR;
  116.   }
  117.   if(res==RES_OK)
  118.   {
  119.     if(HAL_SD_CheckReadOperation(&hsdcard, 0xFFFFFFFF) != SD_OK)
  120.     {
  121.       res = RES_ERROR;
  122.     }
  123.   }
  124.   return res;
  125. }

  126. /**
  127.   * 函数功能: 将缓冲区数据写入到SD卡内
  128.   * 输入参数: lun : 不用
  129.   *           buff:存放待写入数据的缓冲区指针
  130.   *           sector:扇区地址(LBA)
  131.   *           count:扇区数目
  132.   * 返 回 值: DSTATUS:操作结果
  133.   * 说    明: SD卡写操作没有使用DMA传输
  134.   */
  135. #if _USE_WRITE == 1
  136. DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
  137. {
  138.   DRESULT res = RES_OK;
  139.   if((DWORD)buff&3)
  140.   {
  141.     DRESULT res = RES_OK;
  142.     DWORD scratch[BLOCK_SIZE / 4];

  143.     while (count--)
  144.     {
  145.       memcpy( scratch,buff,BLOCK_SIZE);
  146.       res = SD_write(lun,(void *)scratch, sector++, 1);
  147.       if (res != RES_OK)
  148.       {
  149.         break;
  150.       }                                       
  151.       buff += BLOCK_SIZE;
  152.     }
  153.     return res;
  154.   }       
  155.       
  156.   if(HAL_SD_WriteBlocks(&hsdcard,(uint32_t*)buff,(uint64_t)(sector * BLOCK_SIZE),BLOCK_SIZE, count) != SD_OK)
  157.   {
  158.     res = RES_ERROR;
  159.   }  
  160.   return res;
  161. }
  162. #endif /* _USE_WRITE == 1 */

  163. /**
  164.   * 函数功能: 输入输出控制操作(I/O control operation)
  165.   * 输入参数: lun : 不用
  166.   *           cmd:控制命令
  167.   *           buff:存放待写入或者读取数据的缓冲区指针
  168.   * 返 回 值: DSTATUS:操作结果
  169.   * 说    明: 无
  170.   */
  171. #if _USE_IOCTL == 1
  172. DRESULT SD_ioctl(BYTE lun, BYTE cmd, void *buff)
  173. {
  174.   DRESULT res = RES_ERROR;
  175.   
  176.   if (Stat & STA_NOINIT) return RES_NOTRDY;
  177.   
  178.   switch (cmd)
  179.   {
  180.   /* Make sure that no pending write process */
  181.   case CTRL_SYNC :
  182.     res = RES_OK;
  183.     break;
  184.   
  185.   /* 获取SD卡总扇区数目(DWORD) */
  186.   case GET_SECTOR_COUNT :
  187.     HAL_SD_Get_CardInfo(&hsdcard,&SDCardInfo);
  188.     *(DWORD*)buff = SDCardInfo.CardCapacity / BLOCK_SIZE;
  189.     res = RES_OK;
  190.     break;
  191.   
  192.   /* 获取读写扇区大小(WORD) */
  193.   case GET_SECTOR_SIZE :
  194.     *(WORD*)buff = BLOCK_SIZE;
  195.     res = RES_OK;
  196.     break;
  197.   
  198.   /* 获取擦除块大小(DWORD) */
  199.   case GET_BLOCK_SIZE :
  200.     *(DWORD*)buff = BLOCK_SIZE;
  201.     break;
  202.   
  203.   default:
  204.     res = RES_PARERR;
  205.   }
  206.   
  207.   return res;
  208. }
  209. #endif /* _USE_IOCTL == 1 */
  210.   
  211. /******************* (C) COPYRIGHT 2015-2020 硬石嵌入式开发团队 *****END OF FILE****/
复制代码

串口调试助手截图.jpg


<
回复

使用道具 举报

0

主题

153

回帖

0

蝴蝶豆

中级会员

最后登录
2020-1-5
发表于 2016-7-2 06:00:23 | 显示全部楼层
多谢分享
回复 支持 反对

使用道具 举报

0

主题

153

回帖

0

蝴蝶豆

中级会员

最后登录
2020-1-5
发表于 2016-7-2 06:50:47 | 显示全部楼层
多谢分享!
回复 支持 反对

使用道具 举报

4

主题

379

回帖

0

蝴蝶豆

金牌会员

最后登录
2019-11-19
发表于 2016-7-7 23:32:27 | 显示全部楼层
先收藏            
回复 支持 反对

使用道具 举报

8

主题

28

回帖

2

蝴蝶豆

中级会员

最后登录
2018-7-10
发表于 2017-10-12 16:45:27 | 显示全部楼层
链接失效了
回复 支持 反对

使用道具 举报

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版