2025年inand总结

inand总结1 inand 的介绍 1 1 inand 由接口电路和系统储存组成 1 2 inand 有 8 根 IO 线 一根命令线 一根时钟线 SD 卡有四根 IO 线 一根命令线 一根时钟线 1 3 inand 接口电路的功能 1 3 1 提供 eMMC 接口协议和 SOC 对接 1 3 2 提供 eMMC 校验的相关逻辑 简化了 SOC 的编程 1 3 3 内部使用了 MLC 的储存颗粒 价格便宜 性价比高 1 3 4

大家好,我是讯享网,很高兴认识大家。

1 inand的介绍

1.3 inand接口电路的功能
1.3.1提供eMMC接口协议和SOC对接。
1.3.2提供eMMC校验的相关逻辑,简化了SOC的编程。
1.3.3 内部使用了MLC的储存颗粒,价格便宜,性价比高。
1.3.4 提供cache机制,所以inand的读取速度快。

2 inand的操作

2.1 支持1,4,8线并行传输
2.2 通过CMD线来传输命令,通过CLK线来传输时钟。
2.3 soc可以通过寻址或者广播向一个或者多个SD卡发送命令,SD卡接收到命令之后会返回一个响应。
在这里插入图片描述
讯享网
2.4 soc也可以进行多块读写,soc先发送一个多块读写的命令,之后SD卡回应一个响应,当停止读写的时候,SOC会发送一个停止命令,之后SD卡发送一个响应,多块读写结束。如图

在这里插入图片描述
2.5 命令牌图

在这里插入图片描述
2.6 SD卡结构图
在这里插入图片描述

3 代码分析

3.1初始化流程图
在这里插入图片描述
3.2 传输图
在这里插入图片描述
3.3 Hsmmc.h文件

#ifndef __HSMMC_H__ #define __HSMMC_H__ #ifdef __cplusplus extern "C" { #endif #include "stdint.h" // SD协议规定的命令码 #define CMD0 0 #define CMD1 1 #define CMD2 2 #define CMD3 3 #define CMD6 6 #define CMD7 7 #define CMD8 8 #define CMD9 9 #define CMD13 13 #define CMD16 16 #define CMD17 17 #define CMD18 18 #define CMD23 23 #define CMD24 24 #define CMD25 25 #define CMD32 32 #define CMD33 33 #define CMD38 38 #define CMD41 41 #define CMD51 51 #define CMD55 55 // 卡类型 #define UNUSABLE 0 #define SD_V1 1 #define SD_V2 2 #define SD_HC 3 #define MMC 4 // 卡状态 #define CARD_IDLE 0 // 空闲态 #define CARD_READY 1 // 准备好 #define CARD_IDENT 2 #define CARD_STBY 3 #define CARD_TRAN 4 #define CARD_DATA 5 #define CARD_RCV 6 #define CARD_PRG 7 // 卡编程状态 #define CARD_DIS 8 // 断开连接 // 卡回复类型 #define CMD_RESP_NONE 0 // 无回复 #define CMD_RESP_R1 1 #define CMD_RESP_R2 2 #define CMD_RESP_R3 3 #define CMD_RESP_R4 4 #define CMD_RESP_R5 5 #define CMD_RESP_R6 6 #define CMD_RESP_R7 7 #define CMD_RESP_R1B 8 typedef struct { uint32_t RESERVED1; uint32_t RESERVED2 : 16; uint32_t SD_BUS_WIDTHS : 4; uint32_t SD_SECURITY : 3; uint32_t DATA_STAT_AFTER_ERASE : 1; uint32_t SD_SPEC : 4; uint32_t SCR_STRUCTURE : 4; } SD_SCR; int32_t Hsmmc_Init(void); int32_t Hsmmc_GetCardState(void); int32_t Hsmmc_GetSdState(uint8_t *pStatus); int32_t Hsmmc_Get_SCR(SD_SCR *pSCR); int32_t Hsmmc_Get_CSD(uint8_t *pCSD); int32_t Hsmmc_EraseBlock(uint32_t StartBlock, uint32_t EndBlock); int32_t Hsmmc_WriteBlock(uint8_t *pBuffer, uint32_t BlockAddr, uint32_t BlockNumber); int32_t Hsmmc_ReadBlock(uint8_t *pBuffer, uint32_t BlockAddr, uint32_t BlockNumber); #ifdef __cplusplus } #endif #endif /*__HSMMC_H__*/ 

讯享网

3.4 Hsmmc.c文件

讯享网#include "ProjectConfig.h" #include "Hsmmc.h" #define HSMMC_NUM 2 #if (HSMMC_NUM == 0) #define HSMMC_BASE (0xEB000000) #elif (HSMMC_NUM == 1) #define HSMMC_BASE (0xEB) #elif (HSMMC_NUM == 2) #define HSMMC_BASE (0xEB) #elif (HSMMC_NUM == 3) #define HSMMC_BASE (0xEB) #else #error "Configure HSMMC: HSMMC0 ~ HSMM3(0 ~ 3)" #endif #define MAX_BLOCK 65535 #define SWRST_OFFSET 0x2F static uint8_t CardType; // 卡类型 static uint32_t RCA; // 卡相对地址 static void Hsmmc_ClockOn(uint8_t On) { uint32_t Timeout; if (On) { __REGw(HSMMC_BASE+CLKCON_OFFSET) |= (1<<2); // sd时钟使能 Timeout = 1000; // Wait max 10 ms while (!(__REGw(HSMMC_BASE+CLKCON_OFFSET) & (1<<3))) { // 等待SD输出时钟稳定 if (Timeout == 0) { return; } Timeout--; Delay_us(10); } } else { __REGw(HSMMC_BASE+CLKCON_OFFSET) &= ~(1<<2); // sd时钟禁止 } } static void Hsmmc_SetClock(uint32_t Clock) { uint32_t Temp; uint32_t Timeout; uint32_t i; Hsmmc_ClockOn(0); // 关闭时钟 Temp = __REG(HSMMC_BASE+CONTROL2_OFFSET); // Set SCLK_MMC(48M) from SYSCON as a clock source Temp = (Temp & (~(3<<4))) | (2<<4); Temp |= (1u<<31) | (1u<<30) | (1<<8); if (Clock <= ) { Temp &= ~((1<<14) | (1<<15)); __REG(HSMMC_BASE+CONTROL3_OFFSET) = 0; } else { Temp |= ((1<<14) | (1<<15)); __REG(HSMMC_BASE+CONTROL3_OFFSET) = (1u<<31) | (1<<23); } __REG(HSMMC_BASE+CONTROL2_OFFSET) = Temp; for (i=0; i<=8; i++) { if (Clock >= (/(1<<i))) { break; } } Temp = ((1<<i) / 2) << 8; // clock div Temp |= (1<<0); // Internal Clock Enable __REGw(HSMMC_BASE+CLKCON_OFFSET) = Temp; Timeout = 1000; // Wait max 10 ms while (!(__REGw(HSMMC_BASE+CLKCON_OFFSET) & (1<<1))) { // 等待内部时钟振荡稳定 if (Timeout == 0) { return; } Timeout--; Delay_us(10); } Hsmmc_ClockOn(1); // 使能时钟 } static int32_t Hsmmc_WaitForBufferReadReady(void) { int32_t ErrorState; while (1) { if (__REGw(HSMMC_BASE+NORINTSTS_OFFSET) & (1<<15)) { // 出现错误 break; } if (__REGw(HSMMC_BASE+NORINTSTS_OFFSET) & (1<<5)) { // 读缓存准备好 __REGw(HSMMC_BASE+NORINTSTS_OFFSET) |&
小讯
上一篇 2025-01-09 16:23
下一篇 2025-04-03 20:54

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/28828.html