HAL库记录-SDIO外设SD卡

news2024/11/25 20:46:52

正点原子--阿波罗开发板STM32F429IGT6

1.STM32CubeMX配置

 

 

 2.生成的代码

/**
  * Enable DMA controller clock
  */
void MX_DMA_Init(void)
{

  /* DMA controller clock enable */
  __HAL_RCC_DMA2_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA2_Stream3_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 5, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
  /* DMA2_Stream6_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 5, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);

}
SD_HandleTypeDef hsd;
DMA_HandleTypeDef hdma_sdio_rx;
DMA_HandleTypeDef hdma_sdio_tx;

/* SDIO init function */

void MX_SDIO_SD_Init(void)
{

  /* USER CODE BEGIN SDIO_Init 0 */

  /* USER CODE END SDIO_Init 0 */

  /* USER CODE BEGIN SDIO_Init 1 */

  /* USER CODE END SDIO_Init 1 */
  hsd.Instance = SDIO;
  hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
  hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
  hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
  hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
  hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
  hsd.Init.ClockDiv = 0;
  if (HAL_SD_Init(&hsd) != HAL_OK)
  {
	  COM_Printf("MX_SDIO_SD_Init Err1\r\n");
    //Error_Handler(); //注意,如果无内存,会进入这个错误函数
  }
  /* USER CODE BEGIN SDIO_Init 2 */
  if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)
  {
	  COM_Printf("MX_SDIO_SD_Init Err2\r\n");
    //Error_Handler(); //注意,如果无内存,会进入这个错误函数
  }
  /* USER CODE END SDIO_Init 2 */

}

void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(sdHandle->Instance==SDIO)
  {
  /* USER CODE BEGIN SDIO_MspInit 0 */

  /* USER CODE END SDIO_MspInit 0 */
    /* SDIO clock enable */
    __HAL_RCC_SDIO_CLK_ENABLE();

    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOD_CLK_ENABLE();
    /**SDIO GPIO Configuration
    PC8     ------> SDIO_D0
    PC12     ------> SDIO_CK
    PD2     ------> SDIO_CMD
    */
    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
    HAL_GPIO_Init(GPIOC, &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_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

    /* SDIO DMA Init */
    /* SDIO_RX Init */
    hdma_sdio_rx.Instance = DMA2_Stream3;
    hdma_sdio_rx.Init.Channel = DMA_CHANNEL_4;
    hdma_sdio_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_sdio_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_sdio_rx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_sdio_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_sdio_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
    hdma_sdio_rx.Init.Mode = DMA_PFCTRL;
    hdma_sdio_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
    hdma_sdio_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
    hdma_sdio_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
    hdma_sdio_rx.Init.MemBurst = DMA_MBURST_INC4;
    hdma_sdio_rx.Init.PeriphBurst = DMA_PBURST_INC4;
    if (HAL_DMA_Init(&hdma_sdio_rx) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(sdHandle,hdmarx,hdma_sdio_rx);

    /* SDIO_TX Init */
    hdma_sdio_tx.Instance = DMA2_Stream6;
    hdma_sdio_tx.Init.Channel = DMA_CHANNEL_4;
    hdma_sdio_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_sdio_tx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_sdio_tx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_sdio_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_sdio_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
    hdma_sdio_tx.Init.Mode = DMA_PFCTRL;
    hdma_sdio_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
    hdma_sdio_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
    hdma_sdio_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
    hdma_sdio_tx.Init.MemBurst = DMA_MBURST_INC4;
    hdma_sdio_tx.Init.PeriphBurst = DMA_PBURST_INC4;
    if (HAL_DMA_Init(&hdma_sdio_tx) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(sdHandle,hdmatx,hdma_sdio_tx);

    /* SDIO interrupt Init */
    HAL_NVIC_SetPriority(SDIO_IRQn, 3, 0);
    HAL_NVIC_EnableIRQ(SDIO_IRQn);
  /* USER CODE BEGIN SDIO_MspInit 1 */

  /* USER CODE END SDIO_MspInit 1 */
  }
}

void HAL_SD_MspDeInit(SD_HandleTypeDef* sdHandle)
{

  if(sdHandle->Instance==SDIO)
  {
  /* USER CODE BEGIN SDIO_MspDeInit 0 */

  /* USER CODE END SDIO_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_SDIO_CLK_DISABLE();

    /**SDIO GPIO Configuration
    PC8     ------> SDIO_D0
    PC12     ------> SDIO_CK
    PD2     ------> SDIO_CMD
    */
    HAL_GPIO_DeInit(GPIOC, GPIO_PIN_8|GPIO_PIN_12);

    HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2);

    /* SDIO DMA DeInit */
    HAL_DMA_DeInit(sdHandle->hdmarx);
    HAL_DMA_DeInit(sdHandle->hdmatx);

    /* SDIO interrupt Deinit */
    HAL_NVIC_DisableIRQ(SDIO_IRQn);
  /* USER CODE BEGIN SDIO_MspDeInit 1 */

  /* USER CODE END SDIO_MspDeInit 1 */
  }
}

注意:不要直接配置成4线模式,  要先配置成1位模式后,等初始化化完 HAL_SD_Init(&hsd) != HAL_OK

再手动配置为 4线模式, HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B)

3.代码改进(判断是否有TF卡)

无卡初始化是无效的,需要等待卡插入,再次初始化成功后,才可以继续操作SDIO外设

/**
 * @brief :函数作用 : 检测SDIO是否初始成功(也可以判断是否有卡插入)
 * @param :函数入口 : 无
 * @retval:函数返回 : 0:正常 1: HAL_SD_Init()初始化不过  2:HAL_SD_ConfigWideBusOperation()初始化不过
 */
uint8_t SDIO_Check(void)
{
  hsd.Instance                 = SDIO;
  hsd.Init.ClockEdge           = SDIO_CLOCK_EDGE_RISING;
  hsd.Init.ClockBypass         = SDIO_CLOCK_BYPASS_DISABLE;
  hsd.Init.ClockPowerSave      = SDIO_CLOCK_POWER_SAVE_DISABLE;
  hsd.Init.BusWide             = SDIO_BUS_WIDE_1B;
  hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
  hsd.Init.ClockDiv            = 0;
  if (HAL_SD_Init(&hsd) != HAL_OK)
  {
	COM_Printf("MX_SDIO_SD_Init Err1\r\n");
    return 1;
  }
  if (HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)
  {
	COM_Printf("MX_SDIO_SD_Init Err2\r\n");
    return 2;
  }
    return 0; //正常
}

4.测试代码

if(SDIO_Check()==0)
{
    COM_Printf("Micro SD Card Test...\r\n");
    /* 检测SD卡是否正常(处于数据传输模式的传输状态) */
    if(HAL_SD_GetCardState(&hsd) == HAL_SD_CARD_TRANSFER)
    {      
        COM_Printf("Initialize SD card successfully!\r\n");
        // 打印SD卡基本信息
        COM_Printf(" SD card information! \r\n");
        COM_Printf(" CardCapacity  : %lu\r\n", (hsd.SdCard.BlockSize*hsd.SdCard.BlockNbr));// 显示容量
        COM_Printf(" CardBlockSize : %d \r\n", hsd.SdCard.BlockSize);   // 块大小
        COM_Printf(" LogBlockNbr   : %d \r\n", hsd.SdCard.LogBlockNbr); // 逻辑块数量
        COM_Printf(" LogBlockSize  : %d \r\n", hsd.SdCard.LogBlockSize);// 逻辑块大小
        COM_Printf(" RCA           : %d \r\n", hsd.SdCard.RelCardAdd);  // 卡相对地址
        COM_Printf(" CardType      : %d \r\n", hsd.SdCard.CardType);    // 卡类型
        // 读取并打印SD卡的CID信息
        HAL_SD_CardCIDTypeDef sdcard_cid;
        HAL_SD_GetCardCID(&hsd,&sdcard_cid);
        COM_Printf(" ManufacturerID: %d \r\n",sdcard_cid.ManufacturerID);
    }
    else
    {
        COM_Printf("SD card init fail!\r\n" );
    }
}

5.测试结果

Micro SD Card Test...
Initialize SD card successfully!
 SD card information! 
 CardCapacity  : 3046637568
 CardBlockSize : 512 
 LogBlockNbr   : 31116288 
 LogBlockSize  : 512 
 RCA           : 43690 
 CardType      : 1 
 ManufacturerID: 3 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/702579.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS差缺补漏之《高频面试题----如何使元素水平垂直居中?》

面试中经常会被问到如何使元素水平垂直居中,有哪些方法可以做到? 针对此问题,特意总结如下~ 方法一: 定位(主要是值子绝父相)与margin负值配合----依赖于子元素宽/高 (使用绝对定位或固定定位后&#xff0c…

GitLab无法提交大文件的问题

GitLab无法提交大文件的问题 问题描述 GitLab 当提交大文件时遇到如下报错 MYOPS001MYOPS001 MINGW64 /e/work/GitLab/system-deploy (main) $ git push Enumerating objects: 91, done. Counting objects: 100% (91/91), done. Delta compression using up to 16 threads C…

ARM-异常中断处理概述(五)

文章目录 控制程序执行流程ARM 体系中异常中断种类 控制程序执行流程 在 ARM 体系中通常有以下 3 种方式控制程序的执行流程: 在正常程序中执行过程中,每执行一条 ARM 指令,程序计数寄存器 PC 的值加 4 个字节;每执行一条 Thumb…

Python车道线识别

最近找了一款车道线识别的代码,可以准确识别出车道线,里面的视频路径可以切换为自己的视频,现在我以自带的视频数据展示效果 图片中可以准确识别车的车道线: 下面给出一部分源代码: import cv2 import numpy as np i…

汽车统一bootloaderv2.0版本 翻译

统一bootloader系统 统一bootloader范围 下图展示了PC通过适配器与ECU连接。高亮公布部分是ECU和PC共同的。所有平台都是一样的。 统一bootloader关键特征 UDS(ISO14229)TP(ISO1765-2/CAN,ISO17987-2/LIN)Flash驱动包括共同的要求从主机下载Flash驱动bootloader检测APP完整…

元宇宙赋能数字文创 | 蓝海创意云受邀发表瑶海区文化创意产业数字化高峰论坛主题演讲

2023年6月29日,在合肥市文化旅游局的指导下,由中共合肥市瑶海区委员会和合肥市瑶海区人民政府主办的“2023瑶海文化创意产业数字化高峰论坛”于合肥市长江180艺术街区召开,本次论坛以“传承创新,数字引领”为主题,探索…

uniapp项目 完成一个点击 展开 收起的效果

需求是: 即将解锁勋章模块 默认只展示三条数据,当数据大于3条时显示展开,点击展开显示全部数据,展开按钮变为收起,点击收起就只展示三条数据,且收起按钮变为展开. 小于或等于3条时显示所有数据,且不显示展开收起, <view class"unlock"><view style&quo…

Modbus协议学习方法

在刚开始接触modbus协议的时候&#xff0c;很容易被里面的各种功能码搞晕&#xff0c;同时在编写程序的时候也容易搞不清楚每一位数据代表的含义。如果在学习的过程中有实际的发送和接收数据的例子话&#xff0c;那么理解modbus协议就会更容易一些。   下面我将自己借助软件学…

3.0C++虚函数

C 虚函数 C的虚函数是一种特殊的成员函数&#xff0c;可以在派生类中被重写。 虚函数的作用是实现多态性&#xff0c;当我们使用基类指针或引用来调用虚函数时&#xff0c;程序会根据实际的对象类型来调用相应的派生类函数。 我们可以将一个成员函数声明为虚函数&#xff0c…

C++primer(第五版)第六章(函数)

6.1函数基础 函数可以理解成是可以循环使用的代码块.函数的定义通常包含以下部分:返回类型,函数名称,参数列表,函数体. //以下是一个返回值为int类型,有两个参数的函数的定义 int add(int a,int b){return ab; }我们用调用运算符( )来执行函数,在运算符内传入参数.调用时会打…

如何确保大模型追求“正确”的目标?丨AI安全与对齐圆桌回顾

导读 在智源大会「AI 安全与对齐」论坛上&#xff0c;与会嘉宾针对目前人们关心的 AI 安全控制标准、多智能体强化学习环境下的安全、开源对 AI 安全的影响、对智能涌现安全的思考等问题展开了讨论。 能力越大&#xff0c;责任越大。 嘉宾名单 谢旻希丨主持人&#xff0c;安远A…

高压线路距离保护程序逻辑原理(一)

为了保证高压线路输电的稳定性和可靠性&#xff0c;通常要求高压电网构成多侧电源的环形电网。在这种电网中简单的电压电流保护往往不能满足保护的基本要求&#xff0c;例如方向电流保护往往不能保证有选择性地切除故障。为此&#xff0c;在多侧电源的环形电网的线路上配置了选…

使用Nexus搭建Maven私有库实战

本篇快速演示如何搭建和使用Nexus本地库&#xff0c; 关于Nexus 的基本使用参考&#xff1a; Nexus搭建Maven私有库介绍 实战场景 本篇的实际场景是&#xff1a; 本地开发机器可以连接外部网络测试或正式部署环境只能连接内网项目使用了内部开发的组件库 在搭建搭建Maven私…

如何一次解决两大难题,不用写注释,也不会被他人吐槽没有注释呢?

如何一次解决两大难题&#xff0c;不用写注释&#xff0c;也不会被他人吐槽没有注释呢&#xff1f;&#xfeff; 导读为什么要减少代码中的注释量呢&#xff1f;一、无用型的注释二、絮絮叨叨的注释三、代替代码分层的注释四、不知所云的注释 参考&#xff1a;阿里云开发者社区…

【vs2022】解决 “对程序集签名是出错 - 拒绝访问 ”

背景 拿到一个工程&#xff0c;编译时报错&#xff1a;“对程序集签名是出错 - 拒绝访问” 解决方法 ”C:\ProgramData\Microsoft\Crypto\RSA”目录下面&#xff0c;找到【MachineKeys】文件夹。 右键【MachineKeys】文件夹&#xff0c;在安全属性里面&#xff0c;将当前win…

DETR系列:RT-DETR(一) 论文解析

论文&#xff1a;《DETRs Beat YOLOs on Real-time Object Detection》 2023.4 DETRs Beat YOLOs on Real-time Object Detection&#xff1a;https://arxiv.org/pdf/2304.08069.pdf 源码地址&#xff1a;https://github.com/PaddlePaddle/PaddleDetection/tree/develop/conf…

江西五十铃汽车PMO经理苏建受邀为第十二届PMO大会演讲嘉宾

江西五十铃汽车有限公司PMO经理苏建先生受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾&#xff0c;演讲议题&#xff1a;PMO全链路建设促进组织变革——传统汽车行业0-1PMO最佳实践探索。大会将于8月12-13日在北京举办&#xff0c;敬请关注&#xff01; 议题简要&…

LangChain:LLM应用程序开发(上)——Models、Prompt、Parsers、Memory、Chains

文章目录 一、Models、Prompt、Parsers1.1 环境配置&#xff08;导入openai&#xff09;1.2 辅助函数&#xff08;Chat API : OpenAI&#xff09;1.3 使用OpenAI API进行文本翻译1.4使用LangChain进行文本翻译1.5 使用LangChain解析LLM的JSON输出1.5.1 LangChain输出为string格…

基于人体姿势估计的舞蹈检测(AI Dance based on Human Pose Estimation)

人体姿势骨架以图形格式表示人的方向。本质上&#xff0c;它是一组坐标&#xff0c;可以连接起来描述人的姿势。骨架中的每个坐标都被称为一个部分(或一个关节&#xff0c;或一个关键点)。两个部分之间的有效连接称为一对(或分支)。下面是一个人体姿势骨架样本。 因此&#xff…

mysql基础3——数据备份与恢复、破解数据库密码

文章目录 一、备份方案二、备份工具mysqldump2.1 备份整张表数据2.2 备份整个库数据 三、全量备份四、差异备份五、数据库密码破解 一、备份方案 备份方案概念特点全量备份对某一个时间点上的所有数据或应用进行完全拷贝。数据恢复快&#xff0c;备份时间长。增量备份在一次全…