SD卡CMD6的用法

SD卡CMD6的用法

CMD6是SD卡用来扩展功能的一条重要命令。在SD协议1.00和2.00的版本是,该命令主要用于切换卡进入高速模式。而在3.00的协议中,该命令被赋予了更多的功能。

首先来说说功能模块的基本结构吧。SD卡协议中定义了6组功能,每组功能相当于是一组单框,我们可以根据自己不同的需要,来对每一组功能进行不同的选择。

这里以SD协议2.00版本为例,共定义了两种功能:Group1该组功能的名称叫AccessMode,主要就是用于速度上的选择了。默认选项为0x0,即25MHz的总线速度。我们可以将其选为0x1 High-Speed,即可进入到50MHz的总线速度模式了。Group2功能的名称叫Commandsystem,看样子是做一些命令上的扩展。怀疑可能会与加密卡有关,这里没有进行进一步的研究。

因此,简单的说,CMD6我们主要就是用于SD卡高速模式的切换了。下面说说该命令切换高速模式的用法。

CMD6命令共有查询模式和设置模式两种。查询模式主要用于查询是否支持该功能,而设置模式主要用于对该功能的设置。我们采取的流程是先查询,后设置。根据SPEC,因此,我们第一次发送的命令参数应该为:0x00, 0xff, 0xff, 0xf1。该命令的作用是查询AccessMode是否支持High-Speed。命令发送完毕,这里需要注意的是,CMD6并不是用命令总线,而是用数据总线来进行应答。在命令发送完毕时,我们会从数据总线上接收到64Byte的数据。根据SPEC,我们判断第17Byte的低4Bit(data_buf[16]&0x0f)是否等于1。是则继续,否则表示不支持高速模式。

确认SD卡支持高速模式后,我们第二次发送CMD6的参数为:0x80, 0xff, 0xff, 0xf1。该命令的作用是设置AccessMode为High-Speed。命令发送完毕,我们再一次查询接快收数据第17Byte的低4Bit (data_buf[16]&0x0f)是否等于1。如果是,则表明切换成功,接下来就可以调整SD主机模块的时钟和边沿控制了。

### SD CMD2 CID寄存器值解析 SD 的 `CMD2` 命令用于读取片的唯一识别号(CID,Card Identification Number)。该命令返回的数据是一个 16 字节长度的寄存器值,其中存储的信息在片生产过程中被固定写入,无法更改。以下是 CID 寄存器各字段的具体含义及其解析方法[^1]: #### CID 寄存器结构 | 字段名称 | 长度 (位数) | 描述 | |----------------|-------------|----------------------------------------------------------------------| | Manufacturer ID | 8 | 制造商 ID,表示制造厂商的独特标识符 | | OEM/Application ID | 10 | OEM 或应用 ID,由制造商分配给特定产品线 | | Product Name | 40 | 产品的名字,通常是由 ASCII 编码字符组成的字符串 | | Revision | 8 | 版本号,指示产品的版本 | | Serial Number | 32 | 序列号,每张唯一的序列编号 | | Manufacturing Date | 12 | 生产日期,包括年份和月份 | #### 解析方法 为了从 CID 数据中提取上述信息,可以按照以下方式处理数据流中的每一位。 - **Manufacturer ID**: 它位于 CID 的最高有效字节位置,占用了前 8 位。 - **OEM/Application ID**: 接下来的 10 位代表此字段,需通过二进制转换得到其十进制或十六进制形式。 - **Product Name**: 此部分占据连续的 5 字节空间,总共 40 位。这些字节通常是标准 ASCII 文本编码。 - **Revision**: 使用两个字节来定义修订版级别;高四位为大版本号,低四位则对应小版本号。 - **Serial Number**: 是一个无符号整型数值,占用四个完整的字节共 32 位。 - **Manufacturing Date**: 包含两部分内容——高六位指定年份偏移量(相对于 2000 年),剩余六位指明具体哪个月生产的。 下面提供一段 Python 示例代码展示如何解码原始 CID 数组到可理解的形式: ```python def parse_cid(cid_bytes): manufacturer_id = cid_bytes[0] oem_app_id = int.from_bytes(cid_bytes[1:3], byteorder='big') product_name_raw = cid_bytes[3:7].decode('ascii', errors='ignore').rstrip('\x00') revision_major = (cid_bytes[7] & 0xF0) >> 4 revision_minor = cid_bytes[7] & 0x0F serial_number = int.from_bytes(cid_bytes[8:12], byteorder='big') year = ((cid_bytes[12] & 0xFC) >> 2) + 2000 month = cid_bytes[12] & 0x0F parsed_info = { 'manufacturer_id': f"{manufacturer_id:#0{4}X}", 'oem_application_id': f"{oem_app_id:#0{6}X}", 'product_name': product_name_raw, 'revision': f"{revision_major}.{revision_minor}", 'serial_number': serial_number, 'manufacture_date': f"{year}-{month:02d}" } return parsed_info # Example usage with a hypothetical CID array example_cid = bytes([0x1B, 0x53, 0x4D, 0x30, 0x39, 0x4E, 0x45, 0x5A, 0x0C, 0xD1, 0xA4, 0xB2, 0xE0, 0x00, 0x00, 0x00]) parsed_data = parse_cid(example_cid) for key, value in parsed_data.items(): print(f"{key}: {value}") ``` 以上脚本会输出类似于这样的结果: ``` manufacturer_id: 0x1B oem_application_id: 0x534D product_name: SMD09NEZ revision: 0.10 serial_number: 216279250 manufacture_date: 2020-08 ``` 请注意实际实现可能因不同库函数而略有差异,但基本逻辑保持一致。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值