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

【stm32库应用】SD驱动移植(基于SDIO外设)

[复制链接]
aimejia 发布时间:2018-5-25 15:43
上星期六刚刚买的新板子,来处理下SD卡这个东西(后期还将做fatfs文件系统移植)

1.jpg

图1 SD接口图

图1 的接口图不是完全正确的,每个PIN上都必须接一个50K的上拉电阻;

在ST官方提供的库里面有很多意见做好的外设,LCD,EEPROM,等等,当然我们比较幸运,也包括SD卡,这次移植基于3.5的库

我们要移植的文件在这个STM32F10x_StdPeriph_Lib_V3.5.0\Utilities\STM32_EVAL下:

2.jpg

图2 移植需要的文件

因为我的板子是stm32f103vet6跟STM3210E_EVAL比较相近,所以选这个;

3.jpg

图3 common目录

把stm32_eval_spi_sd.c / stm32_eval_spi_sd.h 复制到你的工程里面,并添加;如果就这样编译的话有很多error和warning;

因为他里面确实一些函数,这些函数属于API层、或者说是驱动层的,跟处理器有关,所以我们就要到STM3210E_EVAL目录下看看了。

如果你把上面那个直接拿过去编译的话,会提示少下面一些函数:
  1. [cpp] view plain copy
  2. void SD_LowLevel_DeInit(void);  
  3. void SD_LowLevel_Init(void);   
  4. void SD_LowLevel_DMA_TxConfig(uint32_t *BufferSRC, uint32_t BufferSize);  
  5. void SD_LowLevel_DMA_RxConfig(uint32_t *BufferDST, uint32_t BufferSize);  
  6. uint32_t SD_DMAEndOfTransferStatus(void);  
复制代码
和一些宏定义:
  1. [cpp] view plain copy
  2. /**
  3.   * @brief  SD FLASH SDIO Interface
  4.   */   
  5.   
  6. #define SD_DETECT_PIN                    GPIO_Pin_11                 /* PF.11 */  
  7. #define SD_DETECT_GPIO_PORT              GPIOF                       /* GPIOF */  
  8. #define SD_DETECT_GPIO_CLK               RCC_APB2Periph_GPIOF  
  9.   
  10. #define SDIO_FIFO_ADDRESS                ((uint32_t)0x40018080)  
  11. /**  
  12.   * @brief  SDIO Intialization Frequency (400KHz max)
  13.   */  
  14. #define SDIO_INIT_CLK_DIV                ((uint8_t)0xB2)  
  15. /**  
  16.   * @brief  SDIO Data Transfer Frequency (25MHz max)  
  17.   */  
  18. #define SDIO_TRANSFER_CLK_DIV            ((uint8_t)0x00)   
复制代码
这些声明和定义都在STM3210E_EVAL目录下的 "stm3210e_eval.h"里面,找到他们并复制到stm32_eval_spi_sd.h里面,如果你不想找的话,直接把我的这些复制走就好了!
对应的函数也都在"stm3210e_eval.c"里面;
  1. [cpp] view plain copy
  2. /**
  3.   * @brief  DeInitializes the SDIO interface.
  4.   * @param  None
  5.   * @retval None
  6.   */  
  7. void SD_LowLevel_DeInit(void)  
  8. {  
  9.   GPIO_InitTypeDef  GPIO_InitStructure;  
  10.    
  11.   /*!< Disable SDIO Clock */  
  12.   SDIO_ClockCmd(DISABLE);  
  13.    
  14.   /*!< Set Power State to OFF */  
  15.   SDIO_SetPowerState(SDIO_PowerState_OFF);  
  16.   
  17.   /*!< DeInitializes the SDIO peripheral */  
  18.   SDIO_DeInit();  
  19.    
  20.   /*!< Disable the SDIO AHB Clock */  
  21.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_SDIO, DISABLE);  
  22.   
  23.   /*!< Configure PC.08, PC.09, PC.10, PC.11, PC.12 pin: D0, D1, D2, D3, CLK pin */  
  24.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;  
  25.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
  26.   GPIO_Init(GPIOC, &GPIO_InitStructure);  
  27.   
  28.   /*!< Configure PD.02 CMD line */  
  29.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;  
  30.   GPIO_Init(GPIOD, &GPIO_InitStructure);  
  31. }  
  32.   
  33. /**
  34.   * @brief  Initializes the SD Card and put it into StandBy State (Ready for  
  35.   *         data transfer).
  36.   * @param  None
  37.   * @retval None
  38.   */  
  39. void SD_LowLevel_Init(void)  
  40. {  
  41.   GPIO_InitTypeDef  GPIO_InitStructure;  
  42.   
  43.   /*!< GPIOC and GPIOD Periph clock enable */  
  44.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | SD_DETECT_GPIO_CLK, ENABLE);  
  45.   
  46.   /*!< Configure PC.08, PC.09, PC.10, PC.11, PC.12 pin: D0, D1, D2, D3, CLK pin */  
  47.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;  
  48.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
  49.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
  50.   GPIO_Init(GPIOC, &GPIO_InitStructure);  
  51.   
  52.   /*!< Configure PD.02 CMD line */  
  53.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;  
  54.   GPIO_Init(GPIOD, &GPIO_InitStructure);  
  55.   
  56.   /*!< Configure SD_SPI_DETECT_PIN pin: SD Card detect pin */  
  57.   GPIO_InitStructure.GPIO_Pin = SD_DETECT_PIN;  
  58.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  
  59.   GPIO_Init(SD_DETECT_GPIO_PORT, &GPIO_InitStructure);  
  60.    
  61.   /*!< Enable the SDIO AHB Clock */  
  62.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_SDIO, ENABLE);  
  63.   
  64.   /*!< Enable the DMA2 Clock */  
  65.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);  
  66. }  
  67.   
  68. /**
  69.   * @brief  Configures the DMA2 Channel4 for SDIO Tx request.
  70.   * @param  BufferSRC: pointer to the source buffer
  71.   * @param  BufferSize: buffer size
  72.   * @retval None
  73.   */  
  74. void SD_LowLevel_DMA_TxConfig(uint32_t *BufferSRC, uint32_t BufferSize)  
  75. {  
  76.   
  77.   DMA_InitTypeDef DMA_InitStructure;  
  78.   
  79.   DMA_ClearFlag(DMA2_FLAG_TC4 | DMA2_FLAG_TE4 | DMA2_FLAG_HT4 | DMA2_FLAG_GL4);  
  80.   
  81.   /*!< DMA2 Channel4 disable */  
  82.   DMA_Cmd(DMA2_Channel4, DISABLE);  
  83.   
  84.   /*!< DMA2 Channel4 Config */  
  85.   DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SDIO_FIFO_ADDRESS;  
  86.   DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)BufferSRC;  
  87.   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  
  88.   DMA_InitStructure.DMA_BufferSize = BufferSize / 4;  
  89.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  
  90.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  
  91.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;  
  92.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;  
  93.   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  
  94.   DMA_InitStructure.DMA_Priority = DMA_Priority_High;  
  95.   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  
  96.   DMA_Init(DMA2_Channel4, &DMA_InitStructure);  
  97.   
  98.   /*!< DMA2 Channel4 enable */  
  99.   DMA_Cmd(DMA2_Channel4, ENABLE);   
  100. }  
  101.   
  102. /**
  103.   * @brief  Configures the DMA2 Channel4 for SDIO Rx request.
  104.   * @param  BufferDST: pointer to the destination buffer
  105.   * @param  BufferSize: buffer size
  106.   * @retval None
  107.   */  
  108. void SD_LowLevel_DMA_RxConfig(uint32_t *BufferDST, uint32_t BufferSize)  
  109. {  
  110.   DMA_InitTypeDef DMA_InitStructure;  
  111.   
  112.   DMA_ClearFlag(DMA2_FLAG_TC4 | DMA2_FLAG_TE4 | DMA2_FLAG_HT4 | DMA2_FLAG_GL4);  
  113.   
  114.   /*!< DMA2 Channel4 disable */  
  115.   DMA_Cmd(DMA2_Channel4, DISABLE);  
  116.   
  117.   /*!< DMA2 Channel4 Config */  
  118.   DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SDIO_FIFO_ADDRESS;  
  119.   DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)BufferDST;  
  120.   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  
  121.   DMA_InitStructure.DMA_BufferSize = BufferSize / 4;  
  122.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  
  123.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  
  124.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;  
  125.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;  
  126.   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  
  127.   DMA_InitStructure.DMA_Priority = DMA_Priority_High;  
  128.   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  
  129.   DMA_Init(DMA2_Channel4, &DMA_InitStructure);  
  130.   
  131.   /*!< DMA2 Channel4 enable */  
  132.   DMA_Cmd(DMA2_Channel4, ENABLE);   
  133. }  
  134.   
  135. /**
  136.   * @brief  Returns the DMA End Of Transfer Status.
  137.   * @param  None
  138.   * @retval DMA SDIO Channel Status.
  139.   */  
  140. uint32_t SD_DMAEndOfTransferStatus(void)  
  141. {  
  142.   return (uint32_t)DMA_GetFlagStatus(DMA2_FLAG_TC4);  
  143. }  
复制代码
同样,把这些复制到stm32_eval_spi_sd.c里面;你也可以从这里直接复制!
就这么多,如果你不是我这个平台的处理器,那么一定要注意找到适合你自己的再移植!

如何判别是否适合呢?

在STM321xxxE_EVAL目录下的stm32xxxe_eval.c里面看函数void SD_LowLevel_DeInit(void);看他初始化的管脚是否是你的外设管脚;
  1. [cpp] view plain copy
  2. /*!< Configure PC.08, PC.09, PC.10, PC.11, PC.12 pin: D0, D1, D2, D3, CLK pin */  
  3. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;  
  4. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  
  5. GPIO_Init(GPIOC, &GPIO_InitStructure);  
复制代码
OK!这些移植好后,我们可以到STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\SDIO\uSDCard里面把例程移植一个看看效果怎么样;
我这里用了这个代码,看看他有SD卡有多大:

  1. [cpp] view plain copy
  2. Status = SD_Init();  
  3.   Status = SD_GetCardInfo(&SDCardInfo);  
  4. printf("%d,%d\n",SDCardInfo.CardBlockSize,SDCardInfo.CardCapacity);  
  5.   Status = SD_SelectDeselect((uint32_t) (SDCardInfo.RCA << 16));  
  6.   Status = SD_EnableWideBusOperation(SDIO_BusWide_4b);   
  7.   Status = SD_ReadBlock(buff, 0x00,  512);   
  8. if (Status == SD_OK)  
  9.         printf("\nRead%s",buff);  
  10. printf("Test SD OK!");  
复制代码

4.jpg


图4: 效果图

【1:block size   2:memory size   3:read message】



转载自ieczw

收藏 评论0 发布时间:2018-5-25 15:43

举报

0个回答

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似分享

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