完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
SDIO(Secure Digital Input and Output)中文名称:安全数字输入输出,SDIO在SD标准上定义了一种外设接口。SDIO主要有两类应用——可移动和不可移动。可移动设备作为Palm和Windows Mobile的扩展设备,用来增加蓝牙、照相机、GPS和802.11b功能。不可移动设备遵循相同的电气标准,但不要求符合物理标准。某些手机内包含通过SDIO连接CPU的802.11芯片。此举将“珍贵”的I/ O管脚资源用于更重要的功能。 蓝牙、照相机、GPS和802.11b设备有专为它们定义的应用规范。这些应用规范与为PCI和USB设备定义的类规范很相像。它们允许任何宿主设备与任意外设“通话”,只要它们都支持应用规范。 SDIO和SD卡规范间的一个重要区别是增加了低速标准。SDIO卡只需要SPI和1位SD传输模式。低速卡的目标应用是以最小的硬件开支支持低速I/ O能力。低速卡支持类似调制解调器、条码扫描仪和GPS接受器等应用。对“组合”卡(存储器+ SDIO)而言,全速和4位操作对卡内存储器和SDIO部分都是强制要求的。 MM32F3270系列控制器支持SDIO接口,本文在接下来会对MM32F3270的SDIO进行介绍,并通过实验演示SDIO驱动SD卡。 01 SDIO 简介 SD/MMC/SDIO 控制器是 AMBA AHB 从外设,用于控制外部 SD/MMC/SDIO 卡,并支持 DSP/MCU的读/写访问。它作为主机与连接的 SD/MMC/SDIO 卡进行通信。所述控制器是基于 AMBA HCLK 域的完全同步设计。 1.1SDIO 功能框图 图1 SDIO功能框图 1) AHB 从模式接口:为 32 位 AHB 总线提供接口。2) FIFO 控制:产生握手信号到 DMA 硬件接口,并控制对外部数据 FIFO(128x32)的读/写访问。 3) 总线接口单元:包括控制寄存器和命令缓冲单元。 4) 多重块控制:控制多块数据的读写。 5) 时钟控制:通用时钟基于寄存器中定义的分频值。 6) 命令通路:从总线接口单元或 irq 响应中加载新的命令,然后发送命令,并接收响应 crc7 检查和 8 个空时钟。 7) 数据通路:发送和接收数据,用 crc16 检查。 8) 缓冲接口:控制对数据 FIFO 的读写控制信号。 1.2SDIO 功能描述 1) 完全兼容 SD 记忆卡规格 1.0 2) 完全兼容 SD 存储卡规格 1.1(高速) 3) 完全兼容 SD 记忆卡规格 2.0(SDHC) 4) 完全兼容 MMC 系统规格 2.0~4.2 5) 完全兼容 SDIO 存储卡规格 1.1.0 6) 标准的 MMC 模式接口支持 7) 可编程时钟速率 8) 自动命令/响应 CRC 生成/检查 9) 自动数据 CRC 生成/检查 10) 可编程超时检测 11) AMBA 2.0 32 位 AHB 接口 12) 用于 AHB 数据访问的总共外部 128*32 数据 FIFO 13) 32 位 DMA 硬件接口,用于更快的 DMA 访问 14) DMA 接口可以配置为启用/禁用 15) DMA 请求是可配置的 16) 组合中断输出 02 SD 存储卡 2.1Read-Write 属性 根据 Read-Write 属性不同可分为两种类型的 SD 存储卡: 1) 可读可写(RW)卡(FLASH, OTP, MTP)。这些卡通常作为空白媒介来售卖,用于海量终端用户的视频、音频或数字图像记录的存储。 2) 只读存储卡(ROM)。这些卡是用固定的数据内容生产出来的,它们通常用作软件、音频、视频等的传播媒介。 2.2电源电压 根据工作电源电压不同可分为两种类型的 SD 存储卡: 1) 高电压 SD 存储卡,可以在 2.7-3.6V 的电压范围内工作; 2) 双电压 SD 存储卡,可以在 1.6-3.6V 的电压范围内工作。 2.3卡容量 根据卡容量不同可分为两种类型的 SD 存储卡: 1) 标准容量的 SD 存储卡支持最大 2G 字节的容量。所有版本的物理规格都定义了标准容量 SD 存储卡; 2) 高容量 SD 存储卡支持超过 2G 字节的容量,此版本规范限制容量高达 32GB。高容量 SD 存储卡是物理层规范版本 2.00 中新定义的。 2.4传输速度 定义了四种速度等级,表示 SD 卡的最低性能: 1) Class0:这类卡不指定性能; 2) Class2:速度不低于 2MB/s; 3) Class4:速度不低于 4MB/s; 4) Class6:速度不低于 6MB/s; 大容量 SD 存储卡应支持速度等级规范,性能大于或等于 2 级。 2.5总线拓扑 SD 卡系统定义了两种通信协议:SD 和 SPI。主机系统可以选择任意一种。当收到 reset 命令的时候, SD 卡通过主机的信息来决定使用何种模式,并且之后的通讯都会使用相同模式。不推荐多卡槽用共同的总线信号。一个单独的 SD 总线应该连接一个单独的 SD 卡。SD 总线包含下面的信号: 1) CLK:时钟信号; 2) CMD:双向命令/响应信号; 3) DAT0-DAT3:双向数据信号; 4) Vdd, Vss1, Vss2:电源和地信号。 2.6总线协议 SD 总线通信: 1) Command:命令是一次操作开始的令牌,从主机发送到一个卡片(编址命令)或者连接到主机的所有卡片(广播命令)。命令在 CMD 线上连续传输。 2) Response:响应是从已寻址的卡或从所有连接上的卡发送到主机的令牌,作为对先前接收到指令的应答。响应在 CMD 线上连续传输。 3) Data:数据可以通过 DATA 线双向传输。 卡片寻址通过使用会话地址来实现,会话地址会在初始化阶段分配给卡。SD 总线上的基本交互是命令/响应交互。这种总线交互直接在命令或者响应的结构里面传输他们的信息。此外,某些操作还有数据令牌。SD 卡发送或接收的数据在块(block)中完成。数据块以 CRC 位来保证传输成功。目前有单块和多块操作。 注:多块操作模式在快速写操作时更好一点。多块传输在 CMD 线上产生 stop 命令时结束。主机端可以配置数据传输是单线还是多线。 SDIO“无响应”和“无数据”操作 SDIO(多)数据块读操作 SDIO(多)数据块写操作 SDIO连续读操作 03 卡的初始化以及识别过程 初始化进程以命令 ACMD41 作为开始,通过设置工作条件和 OCR 来进行。HCS(HighCapacitySupport)位为 1 表示主机支持高容量 SD 卡。卡通过 OCR 的 busy 位来通知主机 ACMD41 的初始化完成了。busy 位为 0表示卡仍然在初始化;为 1 表示已经完成初始化。主机会重复发送 ACMD41,直到 busy 位被置 1。卡片旨在第一个 ACMD41 的命令时,检查工作条件和 OCR 里面的 HCS 位。当重复 ACMD41 的时候,除了 CMD0,主机不再发其他命令。接着主机会发送命令 ALL_SEND_CID(CMD2),来获得卡的 CID 号。未识别的卡(处于Ready 状态的)发送自己的 CID 作为响应。当卡发送 CID 后,进入卡识别(Identification)状态。之后主机发送 SEND_RELATIVE_ADDR(CMD3)命令要求卡发布新的相对地址(RCA),一旦收到 RCA,卡就会变为等待(Stand-by)状态。主机会重复识别进程,为系统中每个卡循环发送 CMD2 和 CMD3。对于 SDI/O 卡而言,总线被激活后 SDIO 卡主机先发送 IO_SEND_OP_COND(CMD5)命令,得到的响应是卡的工作条件寄存器的内容,之后再同上发送 CMD3 命令,执行后续操作。 MM32的SDIO支持SD/MMC/SDIO卡,其中SDIO卡与SD存储卡是有区别的。SDIO卡实际上就是利用SDIO接口的一些模块,插入SD的插槽中,扩展设备的功能,如:SDIO wifi, SDIO CMOS相机等。SD存储卡就是平时常见的用于存储数据的卡。 本实验中使用的Micro SD卡属于SDSC(标准容量,最大2G)卡。介绍卡的种类是因为SD协议中的命令也支持这三种类型的卡,因此对MM32中的SDIO接口进行初始化后,上电后就要对接入的卡进行检测、分类,这个过程是通过向卡发送一系列不同的命令,根据卡不同的响应来进行分类。 本实验使用MM32F3270的SDIO对SD卡进行读写测试,首先填充一个块大小的存储器,通过写入操作把数据写入到 SD卡内,然后通过读取操作读取数据到另外的存储器,然后再对比存储器内容,判断读写操作是否正确。 实现的大概流程包括:初始化SDIO 外设以及GPIO,配置 SDIO 基本通信环境进入卡识别模式,通过命令处理后获取卡信息及状态。如果是SD卡正常则进行数据传输,接下来就可以进行读、写以及擦除操作,否则打印SD卡错误信息,不再进行后续操作。 硬件设计 实验使用MB-039开发板,主控芯片为MM32F3277G9P,如图是MB-039开发板的SDIO/TF卡接口部分,完整原理图可以通过官网下载。 根据 SD 卡识别过程和数据传输过程理解 SD 卡驱动函数代码。这部分代码内容也较多,在本文中只对部分核心函数介绍其功能,详细代码可到灵动官网下载参考。 SPIO配置初始化 void SDIO_ConfigInit(void) { SDIO_InitTypeDef SDIO_InitStruct; SDIO_PIN_GPIO_Config(); SDIO_Detect_Pin_Config(); RCC_AHBPeriphClockCmd(RCC_AHBENR_SDIO, ENABLE); SDIO_DeInit(); RCC_AHBPeriphClockCmd(RCC_AHBENR_SDIO, DISABLE); RCC_AHBPeriphClockCmd(RCC_AHBENR_SDIO, ENABLE); SDIO_ClockSet(0x2F); SDIO_StructInit(&SDIO_InitStruct); SDIO_InitStruct.SDIO_OPMSel = SDIO_MMC_CTRL_OPMSel; SDIO_InitStruct.SDIO_SelPTSM = SDIO_MMC_CTRL_SelSM; SDIO_InitStruct.SDIO_DATWT = SDIO_MMC_CTRL_DATWT; SDIO_Init(&SDIO_InitStruct); SDIO_CRCConfig(SDIO_MMC_CRCCTL_CMD_CRCEN | SDIO_MMC_CRCCTL_DAT_CRCEN, ENABLE); } void show_sdcard_info(void) { switch(SDCardInfo.CardType) { case SDIO_STD_CAPACITY_SD_CARD_V1_1: printf("Card Type:SDSC V1.1rn"); break; case SDIO_STD_CAPACITY_SD_CARD_V2_0: printf("Card Type:SDSC V2.0rn"); break; case SDIO_HIGH_CAPACITY_SD_CARD: printf("Card Type:SDHC V2.0rn"); break; case SDIO_MULTIMEDIA_CARD: printf("Card Type:MMC Cardrn"); break; } printf("Card ManufacturerID:%drn", SDCardInfo.SD_cid.ManufacturerID); //The manufacturer ID printf("Card RCA:%drn", SDCardInfo.RCA); //Card relative address printf("Card Capacity:%d MBrn", (u32)(SDCardInfo.CardCapacity >> 20)); printf("Card BlockSize:%drnrn", SDCardInfo.CardBlockSize); } SD卡的初始化主要进行卡识别和卡状态获取,定义SD_Init()如下:SD_Error SD_Init(void) { u32 clk; RCC_ClocksTypeDef bclk; u32 targetFreq; __IO SD_Error errorstatus = SD_OK; u8 clkdiv = 0; INTX_DISABLE(); errorstatus = SD_PowerON(); //SD Power On if (errorstatus != SD_OK) { return errorstatus; } errorstatus = SD_InitializeCards(); //Initialize SD Card if (errorstatus != SD_OK) { return errorstatus; } errorstatus = SD_GetCardInfo(&SDCardInfo); //Get card information if (errorstatus != SD_OK) { return errorstatus; } errorstatus = SD_SelectDeselect((u32)(SDCardInfo.RCA << 16)); //Select the SD card if (errorstatus != SD_OK) { return errorstatus; } errorstatus = SD_EnableWideBusOperation(1); //4 bit width, if it is an MMC card, you cannot use 4 bit mode if ((errorstatus != SD_OK)) { if( (SDIO_MULTIMEDIA_CARD == CardType)) { if (SDCardInfo.CardType == SDIO_STD_CAPACITY_SD_CARD_V1_1 || SDCardInfo.CardType == SDIO_STD_CAPACITY_SD_CARD_V2_0) { clkdiv = 0; //V1.1/V2.0 card with the maximum setting of 48/4=12Mhz } else { clkdiv = 1; //For other cards such as SDHC, the maximum setting is 48/2=24Mhz } if(clkdiv != 0) { targetFreq = 24000000; } else { targetFreq = 12000000; } RCC_GetClocksFreq(&bclk); clk = (bclk.HCLK_Frequency / 2 / 2 / targetFreq - 1); SDIO_ClockSet(clk); } else { __NOP(); } } else { if (SDCardInfo.CardType == SDIO_STD_CAPACITY_SD_CARD_V1_1 || SDCardInfo.CardType == SDIO_STD_CAPACITY_SD_CARD_V2_0) { clkdiv = 0; } else { clkdiv = 1; } if(clkdiv != 0) { targetFreq = 24000000; } else { targetFreq = 12000000; } RCC_GetClocksFreq(&bclk); clk = (bclk.HCLK_Frequency / 2 / 2 / targetFreq - 1); SDIO_ClockSet(clk); } INTX_ENABLE(); return errorstatus; } 1) SD_PowerON()函数用于查询卡的工作电压和时钟控制配置,并返回 SD_Error 类型错误,该函数是整个 SD 识别的关键函数。 2) SD_InitializeCards()函数初始化SD卡,并将其置入就绪状态; 3) SD_GetCardInfo()函数获取SD卡的信息; 4) SD_SelectDeselect()选择SD卡,发送CMD7命令,选择具有相对地址(RCA)的卡作为ADDR; 5) SD_EnableWideBusOperation()配置SDIO数据宽度; 6) SDIO_ClockSet()配置SDIO的时钟频率。 获取SD卡信息及数据的函数定义如下:void read_sd_card_info(void) { u16 i = 5; SD_Error result; u32 sd_size; SDIO_ConfigInit(); printf("SDCARD TESTrn"); while(1) { result = SD_Init(); if(result == SD_OK) { break; } printf("SD Card Error!rn"); DELAY_Ms(1); } show_sdcard_info(); i = 5; while(i--) { if(SD_ReadDisk(&vbuf[0], 0, 1) == 0) { printf("UART Sending Data...rn"); printf("SECTOR 0 DATA:rn"); for(sd_size = 0; sd_size < 512; sd_size++) { printf("%02x ", vbuf[sd_size]); } printf("rnDATA ENDEDrn"); printf("UART Send Data Over!rn"); } DELAY_Ms(50); } } 实验演示 在MB-039开发板的SDIO/TF卡槽插入SD卡,运行程序,串口调试助手显示如下: 如果SD卡可用,串口调试助手会打印SD卡的信息,包括卡类型、生产ID、RCA、容量和块大小,接着打印扇区0的数据,会连续打印5次该部分内容。 本次实验的例程可以通过MindMotion的官网下载MM32F3270 lib_Samples: https://www.mindmotion.com.cn/pr ... instream/mm32f3270/ 工程路径如下: ~MM32F327x_Samples LibSamplesSDIOSDIO_ReadSDCardInfo 可以看到详细的样例与功能操作。 |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
2247个成员聚集在这个小组
加入小组灵动微电子MM32全系列MCU产品应用手册,库函数和例程和选型表
11611 浏览 3 评论
【MM32 eMiniBoard试用连载】+基于OLED12864的GUI---U8G2
5913 浏览 1 评论
【MM32 eMiniBoard试用连载】移植RT-Thread至MM32L373PS
10894 浏览 0 评论
【MM32 eMiniBoard测评报告】+ 开箱 + 初探
4562 浏览 1 评论
灵动微课堂(第106讲) | MM32 USB功能学习笔记 —— WinUSB设备
4288 浏览 1 评论
[MM32软件] MM32F002使用内部flash存储数据怎么操作?
951浏览 1评论
774浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-15 02:21 , Processed in 0.745618 second(s), Total 66, Slave 50 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号