历史上的今天
今天是:2025年03月13日(星期四)
2020年03月13日 | 【stm32库应用】SD驱动移植(基于SDIO外设)
2020-03-13 来源:eefocus
来处理下SD卡这个东西(后期还将做fatfs文件系统移植)

图1 SD接口图
图1 的接口图不是完全正确的,每个PIN上都必须接一个50K的上拉电阻;
在ST官方提供的库里面有很多意见做好的外设,LCD,EEPROM,等等,当然我们比较幸运,也包括SD卡,这次移植基于3.5的库
我们要移植的文件在这个STM32F10x_StdPeriph_Lib_V3.5.0UtilitiesSTM32_EVAL下:

图2 移植需要的文件
因为我的板子是stm32f103vet6跟STM3210E_EVAL比较相近,所以选这个;

图3 common目录
把stm32_eval_spi_sd.c / stm32_eval_spi_sd.h 复制到你的工程里面,并添加;如果就这样编译的话有很多error和warning;
因为他里面确实一些函数,这些函数属于API层、或者说是驱动层的,跟处理器有关,所以我们就要到STM3210E_EVAL目录下看看了。
如果你把上面那个直接拿过去编译的话,会提示少下面一些函数:
void SD_LowLevel_DeInit(void);
void SD_LowLevel_Init(void);
void SD_LowLevel_DMA_TxConfig(uint32_t *BufferSRC, uint32_t BufferSize);
void SD_LowLevel_DMA_RxConfig(uint32_t *BufferDST, uint32_t BufferSize);
uint32_t SD_DMAEndOfTransferStatus(void);
和一些宏定义:
/**
* @brief SD FLASH SDIO Interface
*/
#define SD_DETECT_PIN GPIO_Pin_11 /* PF.11 */
#define SD_DETECT_GPIO_PORT GPIOF /* GPIOF */
#define SD_DETECT_GPIO_CLK RCC_APB2Periph_GPIOF
#define SDIO_FIFO_ADDRESS ((uint32_t)0x40018080)
/**
* @brief SDIO Intialization Frequency (400KHz max)
*/
#define SDIO_INIT_CLK_DIV ((uint8_t)0xB2)
/**
* @brief SDIO Data Transfer Frequency (25MHz max)
*/
#define SDIO_TRANSFER_CLK_DIV ((uint8_t)0x00)
这些声明和定义都在STM3210E_EVAL目录下的 "stm3210e_eval.h"里面,找到他们并复制到stm32_eval_spi_sd.h里面,如果你不想找的话,直接把我的这些复制走就好了!
对应的函数也都在"stm3210e_eval.c"里面;
/**
* @brief DeInitializes the SDIO interface.
* @param None
* @retval None
*/
void SD_LowLevel_DeInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*!< Disable SDIO Clock */
SDIO_ClockCmd(DISABLE);
/*!< Set Power State to OFF */
SDIO_SetPowerState(SDIO_PowerState_OFF);
/*!< DeInitializes the SDIO peripheral */
SDIO_DeInit();
/*!< Disable the SDIO AHB Clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_SDIO, DISABLE);
/*!< Configure PC.08, PC.09, PC.10, PC.11, PC.12 pin: D0, D1, D2, D3, CLK pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/*!< Configure PD.02 CMD line */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}
/**
* @brief Initializes the SD Card and put it into StandBy State (Ready for
* data transfer).
* @param None
* @retval None
*/
void SD_LowLevel_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*!< GPIOC and GPIOD Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | SD_DETECT_GPIO_CLK, ENABLE);
/*!< Configure PC.08, PC.09, PC.10, PC.11, PC.12 pin: D0, D1, D2, D3, CLK pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/*!< Configure PD.02 CMD line */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/*!< Configure SD_SPI_DETECT_PIN pin: SD Card detect pin */
GPIO_InitStructure.GPIO_Pin = SD_DETECT_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(SD_DETECT_GPIO_PORT, &GPIO_InitStructure);
/*!< Enable the SDIO AHB Clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_SDIO, ENABLE);
/*!< Enable the DMA2 Clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
}
/**
* @brief Configures the DMA2 Channel4 for SDIO Tx request.
* @param BufferSRC: pointer to the source buffer
* @param BufferSize: buffer size
* @retval None
*/
void SD_LowLevel_DMA_TxConfig(uint32_t *BufferSRC, uint32_t BufferSize)
{
DMA_InitTypeDef DMA_InitStructure;
DMA_ClearFlag(DMA2_FLAG_TC4 | DMA2_FLAG_TE4 | DMA2_FLAG_HT4 | DMA2_FLAG_GL4);
/*!< DMA2 Channel4 disable */
DMA_Cmd(DMA2_Channel4, DISABLE);
/*!< DMA2 Channel4 Config */
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SDIO_FIFO_ADDRESS;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)BufferSRC;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = BufferSize / 4;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA2_Channel4, &DMA_InitStructure);
/*!< DMA2 Channel4 enable */
DMA_Cmd(DMA2_Channel4, ENABLE);
}
/**
* @brief Configures the DMA2 Channel4 for SDIO Rx request.
* @param BufferDST: pointer to the destination buffer
* @param BufferSize: buffer size
* @retval None
*/
void SD_LowLevel_DMA_RxConfig(uint32_t *BufferDST, uint32_t BufferSize)
{
DMA_InitTypeDef DMA_InitStructure;
DMA_ClearFlag(DMA2_FLAG_TC4 | DMA2_FLAG_TE4 | DMA2_FLAG_HT4 | DMA2_FLAG_GL4);
/*!< DMA2 Channel4 disable */
DMA_Cmd(DMA2_Channel4, DISABLE);
/*!< DMA2 Channel4 Config */
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SDIO_FIFO_ADDRESS;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)BufferDST;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = BufferSize / 4;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA2_Channel4, &DMA_InitStructure);
/*!< DMA2 Channel4 enable */
DMA_Cmd(DMA2_Channel4, ENABLE);
}
/**
* @brief Returns the DMA End Of Transfer Status.
* @param None
* @retval DMA SDIO Channel Status.
*/
uint32_t SD_DMAEndOfTransferStatus(void)
{
return (uint32_t)DMA_GetFlagStatus(DMA2_FLAG_TC4);
}
同样,把这些复制到stm32_eval_spi_sd.c里面;你也可以从这里直接复制!
就这么多,如果你不是我这个平台的处理器,那么一定要注意找到适合你自己的再移植!
如何判别是否适合呢?
在STM321xxxE_EVAL目录下的stm32xxxe_eval.c里面看函数void SD_LowLevel_DeInit(void);看他初始化的管脚是否是你的外设管脚;
/*!< Configure PC.08, PC.09, PC.10, PC.11, PC.12 pin: D0, D1, D2, D3, CLK pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOC, &GPIO_InitStructure);
OK!这些移植好后,我们可以到STM32F10x_StdPeriph_Lib_V3.5.0ProjectSTM32F10x_StdPeriph_ExamplesSDIOuSDCard里面把例程移植一个看看效果怎么样;
我这里用了这个代码,看看他有SD卡有多大:
Status = SD_Init();
Status = SD_GetCardInfo(&SDCardInfo);
printf("%d,%dn",SDCardInfo.CardBlockSize,SDCardInfo.CardCapacity);
Status = SD_SelectDeselect((uint32_t) (SDCardInfo.RCA << 16));
Status = SD_EnableWideBusOperation(SDIO_BusWide_4b);
Status = SD_ReadBlock(buff, 0x00, 512);
if (Status == SD_OK)
printf("nRead%s",buff);
printf("Test SD OK!");

图4: 效果图
【1:block size 2:memory size 3:read message】
史海拾趣
|
寻SMD802 或者HV9910 PWM调光方案? 之前调试的此类IC都是用于日光灯驱动,很少用来PWM调光,以至于这管脚闲置,请问谁有材料让我看看这个原理图。解释下是怎么个调光的。… 查看全部问答> |
|
我是新手还没入门呢,大家别笑我啊,呵呵, 我安装BSP步骤: 1:复制SMDK2440 至 WINCE600/PLATFORM 下,去掉只读性 2:新建项目,在BSP 选项中看不到SMDK2440 这一项。 具体图片: 还有:SMDK2440 我去掉只读性时,明明去掉了,我再点击查看 ...… 查看全部问答> |
|
1、开发板和PC可以连接但无法调试?? 开发班和PC通过交叉网线连接的,可以把NK。BIN下进去,但是无论怎么设置WINCE或 EVC下的 TOOLS\\CONFIGURE 下的DEVICE 属性 都不能进行连接调试 !下载文件 2、另外问题就是在wince5.0 platform manager ...… 查看全部问答> |
|
STM32F051x 参考手册中文版 https://download.eeworld.com.cn/detail/ltbytyn/215961 STM32F407ZGT6红龙开发板原理图及例程集(超过20个模块应用例程,含原理图) https://download.eeworld.com.cn/detail/ltbytyn/215932 STM32F103ZET6红龙板基 ...… 查看全部问答> |




