首页 零死角玩转stm32-高级篇1、SDIO(4bit+++DMA、支持SDHC、带协议分析)

零死角玩转stm32-高级篇1、SDIO(4bit+++DMA、支持SDHC、带协议分析)

举报
开通vip

零死角玩转stm32-高级篇1、SDIO(4bit+++DMA、支持SDHC、带协议分析) ??????? www.9mcu.com -第 2 页- ...

零死角玩转stm32-高级篇1、SDIO(4bit+++DMA、支持SDHC、带协议分析)
??????? www.9mcu.com -第 2 页- 0、 友情提示 《零死角玩转 STM32》系列教程由初级篇、中级篇、高级篇、系统篇、 四个部分组成,根据野火 STM32 开发板旧版教程升级而来,且经过重新深入编 写,重新排版,更适合初学者,步步为营,从入门到精通,从裸奔到系统,让 您零死角玩转 STM32。M3 的世界,与野火同行,乐意惬无边。 另外,野火团队历时一年精心打造的《STM32 库开发实战指南》将于今 年 10 月份由机械工业出版社出版,该书的排版更适于纸质书本阅读以及更有利 于查阅资料。 内容 财务内部控制制度的内容财务内部控制制度的内容人员招聘与配置的内容项目成本控制的内容消防安全演练内容 上会给你带来更多的惊喜。是一本学习 STM32 必备的工具 书。敬请期待! ??????? www.9mcu.com -第 3 页- 1、SDIO(4bit + DMA、支持 SDHC) 1.1 实验描述及 工程 路基工程安全技术交底工程项目施工成本控制工程量增项单年度零星工程技术标正投影法基本原理 文件清单 实验描述 MicroSD 卡(SDIO 模式)测试实验,采用 4bit 数据线模式。没 有跑文件系统,只是单纯地读 block 并将测试信息通过串口 1 在电脑的超级终端上 打印出来。 硬件连接 PC12-SDIO-CLK:CLK PC10-SDIO-D2 :DATA2 PC11-SDIO-D3:CD/DATA3 PD2-SDIO-CMD :CMD PC8-SDIO-D0:DATA0 PC9-SDIO-D1:DATA1 用到的库文件 startup/start_stm32f10x_hd.c CMSIS/core_cm3.c CMSIS/system_stm32f10x.c FWlib/stm32f10x_gpio.c FWlib/stm32f10x_rcc.c FWlib/stm32f10x_usart.c FWlib/ stm32f10x_sdio.c FWlib/ stm32f10x_dma.c FWlib/ misc.c 用户编写的文件 USER/main.c USER/stm32f10x_it.c USER/usart1.c USER/ sdio_sdcard.c ??????? www.9mcu.com -第 4 页- 野火 STM32 开发板 MicroSD 卡硬件原理图: 1.2 SDIO 简介 野火 STM32 开发板的 CPU ( STM32F103VET6 )具有一个 SDIO 接口。 SD/SDIO/MMC 主机接口可以支持 MMC 卡系统规范 4.2 版中的 3 个不同的数据 总线模式:1 位(默认)、4 位和 8 位。在 8 位模式下,该接口可以使数据传输速 率达到 48MHz,该接口兼容 SD 存储卡规范 2.0 版。SDIO 存储卡规范 2.0 版支 持两种数据总线模式:1 位(默认)和 4 位。 目前的芯片版本只能一次支持一个 SD/SDIO/MMC 4.2 版的卡,但可以同 时支持多个 MMC 4.1 版或之前版本的卡。除了 SD/SDIO/MMC,这个接口完全 与 CE-ATA 数字协议版本 1.1 兼容。 1.3 SD 协议 大多数人原来没有了解过 SD 协议,又看到 SDIO 的驱动有 2000 多行, 感觉无从下手。所以野火重新写了这个文档进行详细的解释,帮助大家更快地 跨过这道槛。 附资料:《Simplified_Physical_Layer_Spec.pdf》,这个资料包含了 SDIO 协议中 SD 存储卡的部分。 ??????? www.9mcu.com -第 5 页- 下面野火结合 STM32 的 SDIO,分析 SD 协议,让大家对它先有个大概了 解,更具体的说明在代码中展开。 SDIO 接口图 一.从 SDIO 的时钟说起。 SDIO_CK 时钟是通过 PC12 引脚连接到 SD 卡的,是 SDIO 接口与 SD 卡用 于同步的时钟。 SDIO 选配器挂载到 AHB 总线上,通过 HCLK 二分频输入到适配器得到 SDIO_CK 的时钟,这时 SDIO_CK = HCLK/(2+CLKDIV)。其中 CLKDIV 是 SDIO_CLK(寄存器)中的 CLKDIV 位。 另外,SDIO_CK 也可以由 SDIOCLK 通过设置 bypass 模式直接得到,这时 SDIO_CK = SDIOCLK=HCLK。 通过下面的库函数来配置时钟: 1. SDIO_Init(&SDIO_InitStructure); 对 SD 卡的操作一般是大吞吐量的数据传输,所以采用 DMA 来提高效率, SDIO 采用的是 DMA2 中的通道 4。在数据传输的时候 SDIO 可向 DMA 发出请 求。 二.讲解 SDIO 的命令、数据传输方式。 SDIO 的所有命令及命令响应,都是通过 SDIO-CMD 引脚来传输的。 ??????? www.9mcu.com -第 6 页- 命令只能由 host 即 STM32 的 SDIO 控制器发出。SDIO 协议把命令分成了 11 种,包括基本命令,读写命令还有 ACMD 系列命令等。其中,在发送 ACMD 命令前,要先向卡发送编号为 CMD55 的命令。 参照下面的命令格式图,其中的 start bit,transmission bit ,crc7, endbit,都是由 STM32 中的 SDIO 硬件完成,我们在软件上配置的时候只需要 设置 command index 和命令参数 argument。Command index 就是命令索引 (编号),如 CMD0,CMD1…被编号成 0,1...。有的命令会包含参数,读命令 的地址参数等,这个参数被存放在 argument 段。 SD 卡命令格式 可以通过下面的函数来配置、发送命令: 1. SDIO_SendCommand(&SDIO_CmdInitStructure); //发送命令 SD 卡对 host 的各种命令的回复称为响应,除了 CMD0 命令外,SD 卡在接 收到命令都会返回一个响应。对于不同的命令,会有不同的响应格式,共 7 种,分为长响应型(136bit)和短响应型(48bit)。以下图,响应 6(R6)为 例: SD 卡命令响应格式(R6) ??????? www.9mcu.com -第 7 页- SDIO 通过 CMD 接收到响应后,硬件去除头尾的信息,把 command index 保存到 SDIO_RESPCMD 寄存器,把 argument field 内容保存存储到 SDIO_RESPx 寄存器中。这两个值可以分别通过下面的库函数得到。 1. SDIO_GetCommandResponse(); //卡返回接收到的命令 2. SDIO_GetResponse(SDIO_RESP1); //卡返回的 argument field 内容 数据写入,读取。请看下面的写数据时序图,在软件上,我们要处理的 只是读忙。另外,我们的实验中用的是 Micro SD 卡,有 4 条数据线,默认的时 候 SDIO 采用 1 条数据线的传输方式,更改为 4 条数据线模式要通过向卡发送 命令来更改。 SD 卡的多块写入时序图 三.卡的种类。 STM32 的 SDIO 支持 SD 存储卡,SD I/O 卡 ,MMC 卡。 其中 SDI/O 卡与 SD 存储卡是有区别的,SDI/O 卡实际上就是利用 SDIO 接口 的一些模块,插入 SD 的插槽中,扩展设备的功能,如:SDI/O wifi, SDI/O cmos 相机等。而 SD 存储卡就是我们平时常见的单纯用于存储数据的卡。 ??????? www.9mcu.com -第 8 页- 可使用 SDIO 接口类型的卡 本实验中使用的 Micro SD 卡属于 SDSC( 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 容量,最大两 G)卡。介绍卡的 种类是因为 SD 协议中的命令也支持这三种类型的卡,因此对 STM32 中的 SDIO 接口进行初始化后,上电后就要对接入的卡进行 检测 工程第三方检测合同工程防雷检测合同植筋拉拔检测方案传感器技术课后答案检测机构通用要求培训 、分类,这个过程是 通过向卡发送一系列不同的命令,根据卡不同的响应来进行分类。 下面进入代码展开具体讲解。 1.4 代码分析 首先要添加用的库文件,在工程文件夹下 Fwlib 下我们需添加以下库文 件: FWlib/stm32f10x_gpio.c FWlib/stm32f10x_rcc.c FWlib/stm32f10x_usart.c FWlib/stm32f10x_sdio.c FWlib/stm32f10x_dma.c FWlib/misc.c 还要在 stm32f10x_conf.h 中把相应的头文件添加进来: ??????? www.9mcu.com -第 9 页- 1. #include "stm32f10x_dma.h" 2. #include "stm32f10x_gpio.h" 3. #include "stm32f10x_rcc.h" 4. #include "stm32f10x_sdio.h" 5. #include "stm32f10x_usart.h" 6. #include "misc.h" 保持良好的习惯,从 main 函数开始分析: 1. int main(void) 2. { 3. 4. /*进入到 main 函数前,启动文件 startup(startup_stm32f10x_xx.s)已经调用 了在 5. system_stm32f10x.c 中的 SystemInit(),配置好了系统时钟,在外部晶振 8M 的条件下, 6. 设置 HCLK = 72M */ 7. 8. /* Interrupt Config */ 9. NVIC_Configuration(); 10. 11. /* USART1 config */ 12. USART1_Config(); 13. 14. /*------------------------------ SD Init ------------------------- --------- */ 15. Status = SD_Init(); 16. 17. printf( "\r\n 这是一个 MicroSD 卡实验(没有跑文件系 统).........\r\n " ); 18. 19. 20. if(Status == SD_OK) //检测初始化是否成功 21. { 22. printf( " \r\n SD_Init 初始化成功 \r\n " ); 23. } 24. else 25. { 26. printf("\r\n SD_Init 初始化失败 \r\n" ); 27. printf("\r\n 返回的 Status 的值为: %d \r\n",Status ); 28. } 29. 30. printf( " \r\n CardType is :%d ", SDCardInfo.CardType ); 31. printf( " \r\n CardCapacity is :%d ", SDCardInfo.CardCapacity ); 32. printf( " \r\n CardBlockSize is :%d ", SDCardInfo.CardBlockSize ) ; 33. printf( " \r\n RCA is :%d ", SDCardInfo.RCA); 34. printf( " \r\n ManufacturerID is :%d \r\n", SDCardInfo.SD_cid.Man ufacturerID ); 35. 36. SD_EraseTest(); //擦除测试 37. 38. SD_SingleBlockTest(); //单块读写测试 39. 40. SD_MultiBlockTest(); //多块读写测试 41. 42. while (1) 43. {} 44. } ??????? www.9mcu.com -第 10 页- main 函数的流程简单明了: 1. 用 NVIC_Configuration()初始化好 SDIO 的中断; 2. 用 USART1_Config()配置好用于返回调试信息的串口,SD_Init()开始 进行 SDIO 的初始化; 3. 最后分别用 SD_EraseTest()、SD_SingleBlockTest()、SD_MultiBlockTest() 进行擦除,单数据块读写,多数据块读写测试。 下面我们先进入 SDIO 驱动函数的大头——SD_Init()进行分析: 1. /* 2. * 函数名:SD_Init 3. * 描述 :初始化 SD 卡,使卡处于就绪状态(准备传输数据) 4. * 输入 :无 5. * 输出 :-SD_Error SD 卡错误代码 6. * 成功时则为 SD_OK 7. * 调用 :外部调用 8. */ 9. SD_Error SD_Init(void) 10. { 11. /*重置 SD_Error 状态*/ 12. SD_Error errorstatus = SD_OK; 13. 14. /* SDIO 外设底层引脚初始化 */ 15. GPIO_Configuration(); 16. 17. /*对 SDIO 的所有寄存器进行复位*/ 18. SDIO_DeInit(); 19. 20. /*上电并进行卡识别流程,确认卡的操作电压 */ 21. errorstatus = SD_PowerON(); 22. 23. /*如果上电,识别不成功,返回“响应超时”错误 */ 24. if (errorstatus != SD_OK) 25. { 26. /*!< CMD Response TimeOut (wait for CMDSENT flag) */ 27. return(errorstatus); 28. } 29. 30. /*卡识别成功,进行卡初始化 */ 31. errorstatus = SD_InitializeCards(); 32. 33. if (errorstatus != SD_OK) //失败返回 34. { 35. /*!< CMD Response TimeOut (wait for CMDSENT flag) */ 36. return(errorstatus); 37. } 38. 39. /*!< Configure the SDIO peripheral 40. 上电识别,卡初始化都完成后,进入数据传输模式,提高读写速度 41. 速度若超过 24M 要进入 bypass 模式 42. !< on STM32F2xx devices, SDIOCLK is fixed to 48MHz 43. !< SDIOCLK = HCLK, SDIO_CK = HCLK/(2 + SDIO_TRANSFER_CLK_DIV) */ 44. SDIO_InitStructure.SDIO_ClockDiv = SDIO_TRANSFER_CLK_DIV; 45. SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising; //上 升沿采集数据 ??????? www.9mcu.com -第 11 页- 46. SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable; //时钟 频率若超过 24M,要开启此模式 47. SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable; //若开启此功能,在总线空闲时关闭 sd_clk 时钟 48. SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b; //1 位模式 49. SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_ Disable; //硬件流,若开启,在 FIFO 不能进行发送和接收数据时,数据传输暂停 50. SDIO_Init(&SDIO_InitStructure); 51. 52. if (errorstatus == SD_OK) 53. { 54. /*----------------- Read CSD/CID MSD registers ------------------ */ 55. errorstatus = SD_GetCardInfo(&SDCardInfo); //用来读取 csd/cid 寄存 器 56. } 57. 58. if (errorstatus == SD_OK) 59. { 60. /*----------------- Select Card -------------------------------- */ 61. errorstatus = SD_SelectDeselect((uint32_t) (SDCardInfo.RCA << 16)); //通过 cmd7 ,rca 选择要操作的卡 62. } 63. 64. if (errorstatus == SD_OK) 65. { 66. errorstatus = SD_EnableWideBusOperation(SDIO_BusWide_4b); //开启 4bits 模式 67. } 68. 69. return(errorstatus); 70. } 先从整体上了解这个 SD_Init()函数: 1.用 GPIO_Configuration()进行 SDIO 的端口底层配置 2.分别调用了 SD_PowerON()和 SD_InitializeCards()函数,这两个函数共同实 现了上面提到的卡检测、识别流程。 3.调用 SDIO_Init(&SDIO_InitStructure)库函数配置 SDIO 的时钟,数据线宽 度,硬件流(在读写数据的时候,开启硬件流是和很必要的,可以减少出错) 4. 调用 SD_GetCardInfo(&SDCardInfo)获取 sd 卡的 CSD 寄存器中的内容,在 main 函数里输出到串口的数据就是这个时候从卡读取得到的。 5. 调用 SD_SelectDeselect()选定后面即将要操作的卡。 6.调用 SD_EnableWideBusOperation(SDIO_BusWide_4b)开启 4bit 数据线模式 如果 SD_Init()函数能够执行完整个流程,并且返回值是 SD_OK 的话则说明初始 化成功,就可以开始进行擦除、读写的操作了。 下面进入 SD_PowerON()函数,分析完这个函数大家就能了解 SDIO 如何接收、 发送命令了。 ??????? www.9mcu.com -第 12 页- 1. /* 2. * 函数名:SD_PowerON 3. * 描述 :确保 SD 卡的工作电压和配置控制时钟 4. * 输入 :无 5. * 输出 :-SD_Error SD 卡错误代码 6. * 成功时则为 SD_OK 7. * 调用 :在 SD_Init() 调用 8. */ 9. SD_Error SD_PowerON(void) 10. { 11. SD_Error errorstatus = SD_OK; 12. uint32_t response = 0, count = 0, validvoltage = 0; 13. uint32_t SDType = SD_STD_CAPACITY; 14. 15. /*!< Power ON Sequence ------------------------------------------------ -----*/ 16. /*!< Configure the SDIO peripheral */ 17. /*!< SDIOCLK = HCLK, SDIO_CK = HCLK/(2 + SDIO_INIT_CLK_DIV) */ 18. /*!< on STM32F2xx devices, SDIOCLK is fixed to 48MHz */ 19. /*!< SDIO_CK for initialization should not exceed 400 KHz */ 20. /*初始化时的时钟不能大于 400KHz*/ 21. SDIO_InitStructure.SDIO_ClockDiv = SDIO_INIT_CLK_DIV; /* HCLK = 72MHz, SDIOCLK = 72MHz, SDIO_CK = HCLK/(178 + 2) = 400 KHz */ 22. SDIO_InitStructure.SDIO_ClockEdge = SDIO_ClockEdge_Rising; 23. SDIO_InitStructure.SDIO_ClockBypass = SDIO_ClockBypass_Disable; //不使 用 bypass 模式,直接用 HCLK 进行分频得到 SDIO_CK 24. SDIO_InitStructure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable; / / 空闲时不关闭时钟电源 25. SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b; / /1 位数据线 26. SDIO_InitStructure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_ Disable;//硬件流 27. SDIO_Init(&SDIO_InitStructure); 28. 29. /*!< Set Power State to ON */ 30. SDIO_SetPowerState(SDIO_PowerState_ON); 31. 32. /*!< Enable SDIO Clock */ 33. SDIO_ClockCmd(ENABLE); 34. 35. /*下面发送一系列命令,开始卡识别流程*/ 36. /*!< CMD0: GO_IDLE_STATE ---------------------------------------------- -----*/ 37. /*!< No CMD response required */ 38. SDIO_CmdInitStructure.SDIO_Argument = 0x0; 39. SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_GO_IDLE_STATE; //cmd0 40. SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_No; //无响应 41. SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; 42. SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; //则 CPSM 在开始发送 命令之前等待数据传输结束。 43. SDIO_SendCommand(&SDIO_CmdInitStructure); //写命令进命令寄存器 44. 45. errorstatus = CmdError();//检测是否正确接收到 cmd0 46. 47. if (errorstatus != SD_OK) //命令发送出错,返回 48. { 49. /*!< CMD Response TimeOut (wait for CMDSENT flag) */ 50. return(errorstatus); 51. } 52. 53. /*!< CMD8: SEND_IF_COND ----------------------------------------------- -----*/ 54. /*!< Send CMD8 to verify SD card interface operating condition */ 55. /*!< Argument: - [31:12]: Reserved (shall be set to '0') 56. - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V) ??????? www.9mcu.com -第 13 页- 57. - [7:0]: Check Pattern (recommended 0xAA) */ 58. /*!< CMD Response: R7 */ 59. SDIO_CmdInitStructure.SDIO_Argument = SD_CHECK_PATTERN; //接收到命令 sd 会返回这个参数 60. SDIO_CmdInitStructure.SDIO_CmdIndex = SDIO_SEND_IF_COND; //cmd8 61. SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; //r7 62. SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; //关闭等待中 断 63. SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; 64. SDIO_SendCommand(&SDIO_CmdInitStructure); 65. 66. /*检查是否接收到命令*/ 67. errorstatus = CmdResp7Error(); 68. 69. if (errorstatus == SD_OK) //有响应则 card 遵循 sd 协议 2.0 版本 70. { 71. CardType = SDIO_STD_CAPACITY_SD_CARD_V2_0; /*!< SD Card 2.0 ,先把它定 义会 sdsc 类型的卡*/ 72. SDType = SD_HIGH_CAPACITY; //这个变量用作 acmd41 的参数,用来询问是 sdsc 卡 还是 sdhc 卡 73. } 74. else //无响应,说明是 1.x 的或 mmc 的卡 75. { 76. /*!< CMD55 */ 77. SDIO_CmdInitStructure.SDIO_Argument = 0x00; 78. SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_CMD; 79. SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; 80. SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; 81. SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; 82. SDIO_SendCommand(&SDIO_CmdInitStructure); 83. errorstatus = CmdResp1Error(SD_CMD_APP_CMD); 84. } 85. /*!< CMD55 */ //为什么在 else 里和 else 外面都要发送 CMD55? 86. //发送 cmd55,用于检测是 sd 卡还是 mmc 卡,或是不支持的卡 87. SDIO_CmdInitStructure.SDIO_Argument = 0x00; 88. SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_CMD; 89. SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; //r1 90. SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; 91. SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; 92. SDIO_SendCommand(&SDIO_CmdInitStructure); 93. errorstatus = CmdResp1Error(SD_CMD_APP_CMD); //是否响应,没响应的是 mmc 或 不支持的卡 94. 95. /*!< If errorstatus is Command TimeOut, it is a MMC card */ 96. /*!< If errorstatus is SD_OK it is a SD card: SD card 2.0 (voltage rang e mismatch) 97. or SD card 1.x */ 98. if (errorstatus == SD_OK) //响应了 cmd55,是 sd 卡,可能为 1.x,可能为 2.0 99. { 100. /*下面开始循环地发送 sdio 支持的电压范围,循环一定次数*/ 101. 102. /*!< SD CARD */ 103. /*!< Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */ 104. while ((!validvoltage) && (count < SD_MAX_VOLT_TRIAL)) 105. { 106. //因为下面要用到 ACMD41,是 ACMD 命令,在发送 ACMD 命令前都要先向卡发送 CMD55 107. /*!< SEND CMD55 APP_CMD with RCA as 0 */ 108. SDIO_CmdInitStructure.SDIO_Argument = 0x00; 109. SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_APP_CMD; //CMD55 110. SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; 111. SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; 112. SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; 113. SDIO_SendCommand(&SDIO_CmdInitStructure); ??????? www.9mcu.com -第 14 页- 114. 115. errorstatus = CmdResp1Error(SD_CMD_APP_CMD); //检测响应 116. 117. if (errorstatus != SD_OK) 118. { 119. return(errorstatus);//没响应 CMD55,返回 120. } 121. //acmd41,命令参数由支持的电压范围及 HCS 位组成,HCS 位置一来区分卡是 SDSc 还是 sdhc 122. SDIO_CmdInitStructure.SDIO_Argument = SD_VOLTAGE_WINDOW_SD | SDT ype; //参数为主机可供电压范围及 hcs 位 123. SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SD_APP_OP_COND; 124. SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short; //r3 125. SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No; 126. SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable; 127. SDIO_SendCommand(&SDIO_CmdInitStructure); 128. 129. errorstatus = CmdResp3Error(); //检测是否正确接收到数据 130. if (errorstatus != SD_OK) 131. { 132. return(errorstatus); //没正确接收到 acmd41,出错,返回 133. } 134. /*若卡需求电压在 SDIO 的供电电压范围内,会自动上电并标志 pwr_up 位*/ 135. response = SDIO_GetResponse(SDIO_RESP1); //读取卡寄存器,卡状 态 136. validvoltage = (((response >> 31) == 1) ? 1 : 0); //读取卡的 ocr 寄存器的 pwr_up 位,看是否已工作在正常电压 137. count++; //计算循环次数 138. } 139. if (count >= SD_MAX_VOLT_TRIAL) //循环检测超过一定次数还没上电 140. { 141. errorstatus = SD_INVALID_VOLTRANGE; //SDIO 不支持 card 的供电电 压 142. return(errorstatus); 143. } 144. /*检查卡返回信息中的 HCS 位*/ 145. if (response &= SD_HIGH_CAPACITY) //判断 ocr 中的 ccs 位 ,如果是 sdsc 卡则不执行下面的语句 146. { 147. CardType = SDIO_HIGH_CAPACITY_SD_CARD; //把卡类型从初始化的 sdsc 型 改为 sdhc 型 148. } 149. 150. }/*!< else MMC Card */ 151. 152. return(errorstatus); 153. } 这个函数的流程就是卡的上电、识别操作,如下图: 卡的上电,识别流程: 截图来自《Simplified_Physical_Layer_Spec.pdf》 page27 ??????? www.9mcu.com -第 15 页- 代码中所有的判断语句都是根据这个图的各个识别走向展开的,最终把卡 分为 1.0
本文档为【零死角玩转stm32-高级篇1、SDIO(4bit+++DMA、支持SDHC、带协议分析)】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_324651
暂无简介~
格式:pdf
大小:1MB
软件:PDF阅读器
页数:25
分类:互联网
上传时间:2012-11-07
浏览量:27