简介

最近项目中可能需要使用到SD卡,所以需要对SD卡的配置和使用调研,在配置过程中遇到了一些问题,在此记录一下。

STM32Cube配置

  • Pinout





    只需要注意绿色部分的设定

  • Clock配置



    这里使用了最大的Clock,SDMMC1的时钟是48MHz

  • FATFS配置

  • Freertos配置



    这里增大了Heap size,使用了heap_4的内存管理方式。

  • SD卡配置





    在这里打开SD的全局中断,并使用DMA2的方式传输数据

  • NVIC配置



    SD的全局中断配置为5,DMA中断配置为6,5的优先级更高。

  • 工程配置



以上就是所有的配置内容了,配置完成后,直接使用Code generate功能就能自动生成keil工程。

代码修改

  • 初始化SD卡

    我生成的工程中需要手动添加BSP_SD_Init()函数,我是在MX_FATFS_Init()之前添加的。
/* StartDefaultTask function */
void StartDefaultTask(void const * argument)
{
BSP_SD_Init();
/* init code for FATFS */
MX_FATFS_Init(); /* USER CODE BEGIN StartDefaultTask */
/* Infinite loop */
for(;;)
{
MX_FATFS_Run();
vTaskDelay( 5000 );
}
/* USER CODE END StartDefaultTask */
}
  • 添加DMA中断处理函数

    stm32f7xx_it.c文件中,需要添加下面两个中断处理函数:
void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
{
BSP_SD_WriteCpltCallback();
} void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
{
BSP_SD_ReadCpltCallback();
}
  • 创建Queue

    在自动生成的Demo中,使用了SDQueueID这个Queue,但并没有自动创建它,所以需要手动创建一下。我是在SD_initialize()这个函数中创建的,具体创建的地方可能需要再仔细考虑清楚。
DSTATUS SD_initialize(BYTE lun)
{
osMessageQDef(myQueueSD, QUEUE_SIZE, uint8_t*);
SDQueueID = osMessageCreate(osMessageQ(myQueueSD), NULL);
return SD_CheckStatus(lun);
}
  • 将Pin的配置改为上拉

    在默认配置函数中HAL_SD_MspInit()对SDIO的Pin的默认配置是GPIO_NOPULL,但我在使用过程中发现,程序会卡死在SD_FindSCR()函数的以下这段代码中:
  /*卡在这个循环中出不去*/
while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND))
{
if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXDAVL))
{
*(tempscr + index) = SDMMC_ReadFIFO(hsd->Instance);
index++;
} if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT)
{
return HAL_SD_ERROR_TIMEOUT;
}
}

后面我将GPIO改为GPIO_PULLUP后解决了这个问题,具体原因暂时还不清楚。

    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;//GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;//GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

简单Fatfs应用

void StartDefaultTask(void const * argument)
{
BSP_SD_Init();
/* init code for FATFS */
MX_FATFS_Init(); /* USER CODE BEGIN StartDefaultTask */
/* Infinite loop */ for(;;)
{
/*自己实现一个Run方法,每隔5秒往SD卡中的文件写入数据*/
MX_FATFS_Run();
vTaskDelay( 5000 );
}
/* USER CODE END StartDefaultTask */
} void MX_FATFS_Init(void)
{
/*## FatFS: Link the SD driver ###########################*/
retSD = FATFS_LinkDriver(&SD_Driver, SDPath); /* USER CODE BEGIN Init */
/* 在Init的时候挂载文件系统 */
if(f_mount(&SDFatFS, SDPath,0) != FR_OK)
{
while(1);
}
/* USER CODE END Init */
} void MX_FATFS_Run(void)
{
UINT writeBytes;
/*文件系统基本操作:打开文件,定位到文件结尾,写入内容,关闭文件*/
if(f_open(&SDFile, "SDTest.txt", FA_READ|FA_WRITE|FA_OPEN_ALWAYS) != FR_OK)
{
while(1);
}
if(f_lseek(&SDFile, f_size(&SDFile)) != FR_OK)
{
while(1);
}
if(f_write(&SDFile, "sd Loop", sizeof("sd Loop"), &writeBytes) != FR_OK)
{
while(1);
}
if(f_close(&SDFile) != FR_OK)
{
while(1);
}
}
  • SD写入结果:

使用STM32Cube在STM32F7开发板上实现SD+Freertos+Fatfs的更多相关文章

  1. 在STM32F746G-DISCO开发板上使用Nabto + FreeRTOS的演示热泵应用

    当使用STM32 ARM Cortex-M微控制器时,ST的免费嵌入式软件STM32Cube提供了所有必要的驱动程序和中间件组件,以减少初始的开发工作.在上述提到的中间件组件中,其中一个是非常受欢迎的 ...

  2. easycwmp在开发板上的配置

    原创作品,转载请注明出处 copyright:weishusheng   2015.3.18 email:642613208@qq.com 平台: Linux version 2.6.32-279.e ...

  3. FS210开发板上Qt4.7.0移植过程

    作者:冯老师,华清远见嵌入式学院讲师. 1. 搭建Qt开发环境平台 1.开发环境:ubuntu 12.04 2.交叉编译链:arm-cortex_a8-linux-gnueabi 3.开发板:FS21 ...

  4. 开发板上使用core文件调试

    转载:http://www.nginx.cn/1521.html 如果开发板的操作系统也是linux,core调试方法依然适用.如果开发板上不支持gdb,可将开发板的环境(依赖库).可执行文件和cor ...

  5. [转载]在iTOP-4412开发板上调试helloworld应用

    本文转自迅为论坛:http://www.topeetboard.com 1.安装ADB驱动 在开发板上调试 Android 应用,首先要安装 ADB 驱动. 通过“SDK Manager.exe”来安 ...

  6. DE1-SOC开发板上搭建NIOS II处理器运行UCOS II

    DE1-SOC开发板上搭建NIOS II处理器运行UCOS II   今天在DE1-SOC的开发板上搭建NIOS II软核运行了UCOS II,整个开发过程比较繁琐,稍微有一步做的不对,就会导致整个过 ...

  7. 物联网操作系统HelloX已成功移植到MinnowBoard MAX开发板上

    在HelloX开发团队的努力下,以及Winzent Tech公司(总部在瑞典斯德哥尔摩)的支持下,HelloX最新版本V1.78已成功移植到MinnowBoard MAX开发板上.相关源代码已经发布到 ...

  8. ZTE AD3812 3G模块在linux 2.6.34 内核的开发板上的支持方法

    先说段废话,话说在linux 2.6.34 下,好多比较新的3G网卡及3G模块都没有很好的支持.如果想支持的这些3G网卡/3G模块呢,基本上有两种方式: 1.使用该3G模块的 linux 下的驱动,交 ...

  9. 运行在TQ2440开发板上以及X86平台上的linux内核编译

    一.运行在TQ2440开发板上的linux内核编译 1.获取源码并解压 直接使用天嵌移植好的“linux-2.6.30.4_20100531.tar.bz2”源码包. 解压(天嵌默认解压到/opt/E ...

随机推荐

  1. shell脚本调用python脚本的路径问题

    脚本的相互调用中,只有在同一级目录下才可以使用__file__参数去获取路径名,(在shell里使用pwd也同样),否则,使用的就是主文件(最开始运行的脚本程序)的所在位置,是错误路径:一定要注意当期 ...

  2. Linux内核中断和异常分析(上)

    中断,通常被定义为一个事件.打个比方,你烧热水,水沸腾了,这时候你要去关掉烧热水的电磁炉,然后再去办之前手中停不下来的事情.那么热水沸腾就是打断你正常工作的一个信号机制.当然,还有其它的情况,我们以后 ...

  3. C# 添加、读取Word脚注尾注

    脚注和尾注是对文本的补充说明.脚注一般位于页面的底部,可以作为文档某处内容的注释:尾注一般位于文档的末尾,列出引文 的出处等.在本示例中将介绍如何来添加或删除Word脚注. 工具使用:Free Spi ...

  4. Factor Pattern----工厂模式

    一. 概念 工厂模式就是负责生成其他对象的类或方法,就是把创建对象的过程封装起来,这样随时可以产生一个新的对象,减少代码之间耦合. 二. 使用场景(原因) 工厂模式可以将对象的生产从直接new 一个对 ...

  5. python 内置标准库socketserver模块的思考

    socketserver模块简化了编写网络服务器的任务, 在很大程度上封装了一些操作, 你可以看成是事件驱动型的设计, 这很不错.它定义了两个最基本的类--服务器类 BaseServer, 请求处理类 ...

  6. sql语句——根据身份证号判断男女

    根据身份证判断男女的规则:二代身份证为18位,判断倒数第二位,第二位若为奇数,性别为男:偶数则为女 一代身份证为15为,判断倒数第一位,规则同上. update 表名 set 表名.字段名= case ...

  7. Spring Cloud入门教程-Hystrix断路器实现容错和降级

    简介 Spring cloud提供了Hystrix容错库用以在服务不可用时,对配置了断路器的方法实行降级策略,临时调用备用方法.这篇文章将创建一个产品微服务,注册到eureka服务注册中心,然后我们使 ...

  8. Oracle数据库date类型与Java中Date的联系与转化

    以下是对Java中的日期对象与Oracle中的日期之间的区别与联系做点说明,以期对大家有所帮助.new Date():分配 Date 对象并初始化此对象,以表示分配它的时间(精确到毫秒),就是系统当前 ...

  9. 【CloverETL培训】题目

    具体要求: 导入: 1.在CRM中,创建相应物理表,存储Follow/Binding记录.openid作为逻辑主键 2.Follow/Binding导入相互不影响,一个失败另外一个继续执行 3.Fol ...

  10. AI 学习之路

    前言:本文章纯属自己学习路线纪录,不喜勿喷. 最近AI很火,几乎是个程序员 都要去学习AI,作为一个菜鸡小前端,我也踏上了学习AI的方向. 在学习之中,最开始遇到了很多的困难,比如你不知道如何切入进来 ...