Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
SD卡_TF卡
SPI
STM32H743基于SPI的SD卡驱动开发
发布于 2023-08-15 09:52:58 浏览:777
订阅该版
[tocm] STM32H743以太网驱动调试 ### 硬件环境: 基于STM32H743IIT6自研单板 (1)外部时钟:25MHz (2)调试串口: PC12 ———> UART5_TX PD2 ———> UART5_RX (3)SPI6 PG12 ------> SPI6_MISO PG13 ------> SPI6_SCK PG14 ------> SPI6_MOSI PG8 ------> SPI6_NSS ### 软件开发环境 RT-Thread Studio 版本: 2.2.6 构建ID: 202211231640 OS: Windows 10, v.10.0, x86_64 / win32 ### 调试串口+以太网 https://club.rt-thread.org/ask/article/f2a4eb16251dc7ac.html ### RT-Thread配置   ### SPI配置 在board.h文件中,参考SPI配置说明依次配置SPI参数 ```c /*-------------------------- SPI CONFIG BEGIN --------------------------*/ /** if you want to use spi bus you can use the following instructions. * * STEP 1, open spi driver framework support in the RT-Thread Settings file * * STEP 2, define macro related to the spi bus * such as #define BSP_USING_SPI1 * * STEP 3, copy your spi init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file * such as void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi) * * STEP 4, modify your stm32xxxx_hal_config.h file to support spi peripherals. define macro related to the peripherals * such as #define HAL_SPI_MODULE_ENABLED */ #define BSP_USING_SPI /*#define BSP_USING_SPI1*/ /*#define BSP_USING_SPI2*/ /*#define BSP_USING_SPI3*/ /*#define BSP_USING_SPI4*/ /*#define BSP_USING_SPI5*/ #define BSP_USING_SPI6 /*-------------------------- SPI CONFIG END --------------------------*/ ``` 在board.c文件中添加HAL_SPI_MspInit函数 ```c void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; if(spiHandle->Instance==SPI1) { /* USER CODE BEGIN SPI1_MspInit 0 */ /* USER CODE END SPI1_MspInit 0 */ /** Initializes the peripherals clock */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI1; PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); } /* SPI1 clock enable */ __HAL_RCC_SPI1_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /**SPI1 GPIO Configuration PG9 ------> SPI1_MISO PG11 ------> SPI1_SCK PB5 ------> SPI1_MOSI */ GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* SPI1 interrupt Init */ HAL_NVIC_SetPriority(SPI1_IRQn, 5, 0); HAL_NVIC_EnableIRQ(SPI1_IRQn); /* USER CODE BEGIN SPI1_MspInit 1 */ /* USER CODE END SPI1_MspInit 1 */ } else if(spiHandle->Instance==SPI2) { /* USER CODE BEGIN SPI2_MspInit 0 */ /* USER CODE END SPI2_MspInit 0 */ /** Initializes the peripherals clock */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI2; PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); } /* SPI2 clock enable */ __HAL_RCC_SPI2_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOI_CLK_ENABLE(); /**SPI2 GPIO Configuration PB10 ------> SPI2_SCK PB15 ------> SPI2_MOSI PI2 ------> SPI2_MISO */ GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_15; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; HAL_GPIO_Init(GPIOI, &GPIO_InitStruct); /* SPI2 interrupt Init */ HAL_NVIC_SetPriority(SPI2_IRQn, 5, 0); HAL_NVIC_EnableIRQ(SPI2_IRQn); /* USER CODE BEGIN SPI2_MspInit 1 */ /* USER CODE END SPI2_MspInit 1 */ } else if(spiHandle->Instance==SPI3) { /* USER CODE BEGIN SPI3_MspInit 0 */ /* USER CODE END SPI3_MspInit 0 */ /** Initializes the peripherals clock */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI3; PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); } /* SPI3 clock enable */ __HAL_RCC_SPI3_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE(); /**SPI3 GPIO Configuration PB2 ------> SPI3_MOSI PC10 ------> SPI3_SCK PC11 ------> SPI3_MISO */ GPIO_InitStruct.Pin = GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF7_SPI3; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF6_SPI3; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /* SPI3 interrupt Init */ HAL_NVIC_SetPriority(SPI3_IRQn, 5, 0); HAL_NVIC_EnableIRQ(SPI3_IRQn); /* USER CODE BEGIN SPI3_MspInit 1 */ /* USER CODE END SPI3_MspInit 1 */ } else if(spiHandle->Instance==SPI4) { /* USER CODE BEGIN SPI4_MspInit 0 */ /* USER CODE END SPI4_MspInit 0 */ /** Initializes the peripherals clock */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI4; PeriphClkInitStruct.Spi45ClockSelection = RCC_SPI45CLKSOURCE_D2PCLK1; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); } /* SPI4 clock enable */ __HAL_RCC_SPI4_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); /**SPI4 GPIO Configuration PE2 ------> SPI4_SCK PE5 ------> SPI4_MISO PE6 ------> SPI4_MOSI */ GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_5|GPIO_PIN_6; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;//GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF5_SPI4; HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); /* SPI4 interrupt Init */ HAL_NVIC_SetPriority(SPI4_IRQn, 5, 0); HAL_NVIC_EnableIRQ(SPI4_IRQn); /* USER CODE BEGIN SPI4_MspInit 1 */ /* USER CODE END SPI4_MspInit 1 */ } else if(spiHandle->Instance==SPI5) { /* USER CODE BEGIN SPI5_MspInit 0 */ /* USER CODE END SPI5_MspInit 0 */ /** Initializes the peripherals clock */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI5; PeriphClkInitStruct.Spi45ClockSelection = RCC_SPI45CLKSOURCE_D2PCLK1; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); } /* SPI5 clock enable */ __HAL_RCC_SPI5_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE(); /**SPI5 GPIO Configuration PF7 ------> SPI5_SCK PF8 ------> SPI5_MISO PF9 ------> SPI5_MOSI */ GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF5_SPI5; HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); /* SPI5 interrupt Init */ HAL_NVIC_SetPriority(SPI5_IRQn, 5, 0); HAL_NVIC_EnableIRQ(SPI5_IRQn); /* USER CODE BEGIN SPI5_MspInit 1 */ /* USER CODE END SPI5_MspInit 1 */ } else if(spiHandle->Instance==SPI6) { /* USER CODE BEGIN SPI6_MspInit 0 */ /* USER CODE END SPI6_MspInit 0 */ /** Initializes the peripherals clock */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SPI6; PeriphClkInitStruct.Spi6ClockSelection = RCC_SPI6CLKSOURCE_D3PCLK1; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); } /* SPI6 clock enable */ __HAL_RCC_SPI6_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); /**SPI6 GPIO Configuration PG12 ------> SPI6_MISO PG13 ------> SPI6_SCK PG14 ------> SPI6_MOSI */ GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF5_SPI6; HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); /* SPI6 interrupt Init */ HAL_NVIC_SetPriority(SPI6_IRQn, 5, 0); HAL_NVIC_EnableIRQ(SPI6_IRQn); /* USER CODE BEGIN SPI6_MspInit 1 */ /* USER CODE END SPI6_MspInit 1 */ } } ``` 在stm32h7xx_hal_conf.h文件中,打开宏定义: ```c #define HAL_SPI_MODULE_ENABLED ``` 在drv_spi.c文件的spi_config数组中用到了SPI6_BUS_CONFIG,默认工程是没有的,需要自己添加,可以参考已有的SPI配置  在spi_config.h文件尾部添加SPI6_BUS_CONFIG ```c #ifdef BSP_USING_SPI6 #ifndef SPI6_BUS_CONFIG #define SPI6_BUS_CONFIG \ { \ .Instance = SPI6, \ .bus_name = "spi6", \ } #endif /* SPI6_BUS_CONFIG */ #endif /* BSP_USING_SPI6 */ //#ifdef BSP_SPI6_TX_USING_DMA //#ifndef SPI6_TX_DMA_CONFIG //#define SPI6_TX_DMA_CONFIG \ // { \ // .dma_rcc = SPI6_TX_DMA_RCC, \ // .Instance = SPI6_TX_DMA_INSTANCE, \ // .channel = SPI6_TX_DMA_CHANNEL, \ // .dma_irq = SPI6_TX_DMA_IRQ, \ // } //#endif /* SPI6_TX_DMA_CONFIG */ //#endif /* BSP_SPI6_TX_USING_DMA */ // //#ifdef BSP_SPI6_RX_USING_DMA //#ifndef SPI6_RX_DMA_CONFIG //#define SPI6_RX_DMA_CONFIG \ // { \ // .dma_rcc = SPI6_RX_DMA_RCC, \ // .Instance = SPI6_RX_DMA_INSTANCE, \ // .channel = SPI6_RX_DMA_CHANNEL, \ // .dma_irq = SPI6_RX_DMA_IRQ, \ // } //#endif /* SPI6_RX_DMA_CONFIG */ //#endif /* BSP_SPI6_RX_USING_DMA */ ``` 在dfs_fs.c文件中,添加文件系统默认装载表: ```c const struct dfs_mount_tbl mount_table[] = { {"sd0", "/", "elm", 0, 0}, {0} }; ``` 在driver目录下添加drv_spi_tfcard.c文件 [drv_spi_tfcard.c](https://club.rt-thread.org/file_download/391b3d2c9234142a) ### 测试  至此完成基于SPI的SD驱动框架。 ### 遗留问题 添加SD后,MPU配置会影响以太网ping的效果,使用下面配置SD卡、以太网均正常 ```c { MPU_Region_InitTypeDef MPU_InitStruct = {0}; /* Disables the MPU */ HAL_MPU_Disable(); /** Initializes and configures the Region and the memory to be protected */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER0; MPU_InitStruct.BaseAddress = 0x30040000; MPU_InitStruct.Size = MPU_REGION_SIZE_256B; MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /** Initializes and configures the Region and the memory to be protected */ MPU_InitStruct.Number = MPU_REGION_NUMBER1; MPU_InitStruct.BaseAddress = 0x30044000; MPU_InitStruct.Size = MPU_REGION_SIZE_16KB; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); /* Enables the MPU */ HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); } ``` 使用下面的配置,以太网ping不通 ```c { MPU_Region_InitTypeDef MPU_InitStruct; /* Disable the MPU */ HAL_MPU_Disable(); /* Configure the MPU attributes as WT for AXI SRAM */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x24000000; MPU_InitStruct.Size = MPU_REGION_SIZE_512KB; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER0; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0X00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); #ifdef BSP_USING_SDRAM /* Configure the MPU attributes as WT for SDRAM */ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0xC0000000; MPU_InitStruct.Size = MPU_REGION_SIZE_32MB; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER1; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); #endif #ifdef BSP_USING_ETH /* Configure the MPU attributes as Device not cacheable for ETH DMA descriptors and RX Buffers*/ MPU_InitStruct.Enable = MPU_REGION_ENABLE; MPU_InitStruct.BaseAddress = 0x30040000; MPU_InitStruct.Size = MPU_REGION_SIZE_32KB; MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE; MPU_InitStruct.Number = MPU_REGION_NUMBER2; MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1; MPU_InitStruct.SubRegionDisable = 0x00; MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; HAL_MPU_ConfigRegion(&MPU_InitStruct); #endif /* Configure the MPU attributes as WT for QSPI */ // MPU_InitStruct.Enable = MPU_REGION_ENABLE; // MPU_InitStruct.BaseAddress = 0x90000000; // MPU_InitStruct.Size = MPU_REGION_SIZE_8MB; // MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; // MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; // MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; // MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; // MPU_InitStruct.Number = MPU_REGION_NUMBER3; // MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; // MPU_InitStruct.SubRegionDisable = 0X00; // MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; // // HAL_MPU_ConfigRegion(&MPU_InitStruct); /* Enable the MPU */ HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); /* Enable CACHE */ SCB_EnableICache(); SCB_EnableDCache(); return RT_EOK; } ``` 如果了解该问题的大佬看到这篇文章,还请答疑解惑!
0
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
xinyz4104
这家伙很懒,什么也没写!
文章
3
回答
2
被采纳
0
关注TA
发私信
相关文章
1
BBB的SPI驱动
2
求个SPI上挂两个或多个设备的使用例子
3
SPI设备有个bug
4
spi flash 的fatfs使用一段时间后读写文件出现故障
5
SPI驱动
6
请教rt_spi_configure函数理解
7
SPI FLASH挂载的问题
8
SPI-FLASH 文件系统 SPIFFS
9
求助一个完整的 spi flash 驱动
10
关于同时使用文件系统与SPI FLASH的问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
DMA
USB
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
rt-smart
FAL
I2C_IIC
UART
ESP8266
cubemx
WIZnet_W5500
ota在线升级
PWM
BSP
flash
freemodbus
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
编译报错
socket
中断
Debug
rt_mq_消息队列_msg_queue
keil_MDK
ulog
SFUD
msh
C++_cpp
MicroPython
本月问答贡献
RTT_逍遥
10
个答案
3
次被采纳
xiaorui
3
个答案
3
次被采纳
winfeng
2
个答案
2
次被采纳
三世执戟
8
个答案
1
次被采纳
KunYi
8
个答案
1
次被采纳
本月文章贡献
catcatbing
3
篇文章
5
次点赞
lizimu
2
篇文章
9
次点赞
swet123
1
篇文章
4
次点赞
Days
1
篇文章
4
次点赞
YZRD
1
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部