STM32的SDIO(Secure Digital Input Output)接口是一种用于SD卡和MMC卡的高速数据传输接口,通过SDIO接口可以实现对SD卡和MMC卡的读写操作。在本文中,我们将详细介绍STM32 SDIO接口的配置和使用方法,并附上相关的代码示例。
✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进
❤欢迎关注我的知乎:对error视而不见
代码获取、问题探讨及文章转载可私信。
☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。
🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!👇
点击领取更多详细资料
1. STM32 SDIO接口简介
STM32的SDIO接口使用了全双工的模式,支持高速的SDIO 4.0标准。SDIO接口可以通过DMA传输来提高数据传输速度和减少CPU负担,同时还支持自动地处理多个数据块的传输。
2. STM32 SDIO接口配置方法
在使用STM32 SDIO接口之前,需要进行相应的配置以实现对SD卡的读写操作。以下是配置STM32 SDIO接口的步骤:
2.1 SDIO时钟配置
首先,需要配置SDIO的时钟,包括SDIO模块的和时钟源的配置。
2.2 GPIO配置
然后,我们需要配置相应的GPIO引脚为SDIO功能,并将引脚设置为推挽输出模式。
2.3 SDIO控制器配置
接下来,需要对SDIO控制器进行配置,包括时钟分频、数据线宽度、传输速度等。
2.4 DMA配置
为了提高数据传输效率,可以配置DMA传输来进行SDIO的数据读写操作。
2.5 SD卡初始化
最后,需要对SD卡进行初始化,包括发送卡初始化序列以使其进入正常工作状态。
以下是一个示例代码,演示了如何配置STM32的SDIO接口:
```c
#include "stm32f4xx.h"void SDIO_GPIO_Configuration(void)
{// 启用SDIO时钟RCC->AHB1ENR |= RCC_AHB1ENR_SDIOEN;// 配置SDIO引脚为复用功能GPIOB->MODER &= ~(GPIO_MODER_MODE7 | GPIO_MODER_MODE8 | GPIO_MODER_MODE9 | GPIO_MODER_MODE10);GPIOB->MODER |= (GPIO_MODER_MODE7_1 | GPIO_MODER_MODE8_1 | GPIO_MODER_MODE9_1 | GPIO_MODER_MODE10_1);// 配置IO引脚为AF12(SDIO功能)GPIOB->AFR[0] &= ~(GPIO_AFRL_AFSEL7_Msk | GPIO_AFRL_AFSEL8_Msk | GPIO_AFRL_AFSEL9_Msk | GPIO_AFRL_AFSEL10_Msk);GPIOB->AFR[0] |= (0xC << GPIO_AFRL_AFSEL7_Pos) | (0xC << GPIO_AFRL_AFSEL8_Pos) |(0xC << GPIO_AFRL_AFSEL9_Pos) | (0xC << GPIO_AFRL_AFSEL10_Pos);// 配置IO引脚为推挽输出GPIOB->OTYPER &= ~(GPIO_OTYPER_OT7 | GPIO_OTYPER_OT8 | GPIO_OTYPER_OT9 | GPIO_OTYPER_OT10);// 配置IO引脚速度GPIOB->OSPEEDR |= (GPIO_OSPEEDER_OSPEEDR7 | GPIO_OSPEEDER_OSPEEDR8 |GPIO_OSPEEDER_OSPEEDR9 | GPIO_OSPEEDER_OSPEEDR10);
}void SDIO_Init(void)
{// 启用SDIO时钟RCC->AHB2ENR |= RCC_AHB2ENR_SDIOEN;// 关闭SDIOSDIO->POWER &= ~SDIO_POWER_PWRCTRL_Msk;// 等待SDIO停止while (SDIO->POWER & SDIO_POWER_PWRCTRL_Msk);// SDIO时钟初始化和配置SDIO->CLKCR |= SDIO_CLKCR_HWFC_EN;SDIO->CLKCR |= (0x76 << SDIO_CLKCR_CLKDIV_Pos) |(0x2 << SDIO_CLKCR_CLKEN_Pos) |(0x1 << SDIO_CLKCR_PWRSAV_Pos);// 数据线宽度配置SDIO->CLKCR |= SDIO_CLKCR_WIDBUS_1;// DMA处理SDIO->DCTRL |= SDIO_DCTRL_DMAEN;// 使能SDIOSDIO->POWER |= SDIO_POWER_PWRCTRL_Msk;
}void SDIO_DMA_Init(void)
{// 启用DMA2时钟RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;// 配置DMA2的Stream3和Stream6DMA2_Stream3->CR &= ~DMA_SxCR_EN; // 关闭DMA2 Stream3DMA2_Stream3->CR |= (0x4 << DMA_SxCR_CHSEL_Pos); // 选择DMA2 Stream3通道4DMA2_Stream3->PAR = (uint32_t)&(SDIO->FIFO); // 设置外设地址为SDIO_FIFO寄存器地址DMA2_Stream3->M0AR = (uint32_t)buffer; // 设置内存地址,此处为内存buffer的地址DMA2_Stream3->NDTR = sizeof(buffer) / 4; // 设置传输数据大小(单位为32位)DMA2_Stream3->CR |= DMA_SxCR_MINC; // 使能内存地址自增模式DMA2_Stream6->CR &= ~DMA_SxCR_EN; // 关闭DMA2 Stream6DMA2_Stream6->CR |= (0x4 << DMA_SxCR_CHSEL_Pos); // 选择DMA2 Stream6通道4DMA2_Stream6->PAR = (uint32_t)&(SDIO->FIFO); // 设置外设地址为SDIO_FIFO寄存器地址DMA2_Stream6->M0AR = (uint32_t)buffer; // 设置内存地址,此处为内存buffer的地址DMA2_Stream6->NDTR = sizeof(buffer) / 4; // 设置传输数据大小(单位为32位)DMA2_Stream6->CR |= DMA_SxCR_MINC; // 使能内存地址自增模式
}void SDIO_StartTransfer(void)
{// 启动DMA传输DMA2_Stream3->CR |= DMA_SxCR_EN;DMA2_Stream6->CR |= DMA_SxCR_EN;// 启动SDIO数据传输SDIO->DCTRL |= SDIO_DCTRL_DTEN;
}int main(void)
{// 初始化库和系统时钟// 配置SDIO引脚SDIO_GPIO_Configuration();// 配置SDIOSDIO_Init();// 配置DMASDIO_DMA_Init();// 启动传输SDIO_Transfer_Start();while (1){// 主循环中其他任务}
}
```
在这个示例代码中,我们首先调用`SDIO_GPIO_Configuration`函数来进行SDIO引脚的配置操作。然后,我们调用`SDIO_Init`函数来初始化和配置SDIO接口,包括时钟分频、数据线宽度和DMA处理。接下来,我们调用`SDIO_DMA_Init`函数来初始化和配置DMA传输。最后,我们调用`SDIO_StartTransfer`函数来启动SDIO和DMA传输。
通过以上的配置,我们可以实现对SD卡的读写操作,利用SDIO接口和DMA传输,在数据传输中提供高效率和低CPU负载的特性。通过合理配置和使用,可以充分利用STM32 SDIO接口的性能,提供高速的SD卡读写功能。
✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进
❤欢迎关注我的知乎:对error视而不见
代码获取、问题探讨及文章转载可私信。
☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。
🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!👇
点击领取更多详细资料