SD卡数据读取
2021/12/22 23:21:14
本文主要是介绍SD卡数据读取,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
绝望系列
- 一、安装Altium Designer 18
- 二、绘制电路原理图
- 1.建立工程
- 2.绘制原理图
- 基本操作
- 数据读取
- 原理
- sd卡协议
- 寄存器
- SD卡初始化(SPI模式)
- SD卡读取与写入(SPI模式)
- 实验准备
- 连线
- 配置HAL库
- 代码分析
- 结果
- 总结
一、安装Altium Designer 18
ADB
提取码:1108
百度网盘速度你懂的,劝你自己找,我只是给个形式。
后续:操作简单,截图太多,难得写了,给个博客
点我
二、绘制电路原理图
1.建立工程
2.绘制原理图
基本操作
这个软件的基本操作极其反人类(不出意外它绝对不会在我的电脑待超过寒假)
CTRL+鼠标滑轮:放大缩小界面
右键:滑动界面
左键:选中
这里要右键才能打开选项(我不理解)
如果没反应,没事它慢的很,习惯就好。(反正我很难受)
复制的时候记得不要按太久!他会无限复制(呵呵呵)
数据读取
掌握SD卡协议原理,用STM32F103完成对SD卡的数据读取(fat文件模式)。
原理
sd卡协议
SD存储卡是一种基于半导体快闪记忆器的新一代记忆设备,由于它体积小、数据传输速度快、可热插拔等优良的特性,被广泛地于便携式装置上使用,例如数码相机、平板电脑和多媒体播放器等。
结构:
SD 卡主要引脚和功能
CLK:时钟信号,每个时钟周期传输一个命令或数据位,频率可在0~25MHz之间变化,SD卡的总线管理器可以不受任何限制的自由产生0~25MHz 的频率;
CMD:双向命令和回复线,命令是一次主机到从卡操作的开始,命令可以是从主机到单卡寻址,也可以是到所有卡;回复是对之前命令的回答,回复可以来自单卡或所有卡;
DAT0~3:数据线,数据可以从卡传向主机也可以从主机传向卡。
SD卡以命令形式来控制SD卡的读写等操作。可根据命令对多块或单块进行读写操作。在SPI模式下其命令由6个字节构成,其中高位在前。SD卡命令的格式如后表所示,其中相关参数可以查阅SD卡规范。
SD卡接口除了保留MMC卡的7针外,还在两边加多了2针,作为数据线。 [3]
在SD卡3.0规范中,SD卡的理论最大容量可达2TB,理论最大读写速度可达104MB/s(在最新的4.10规范中,理论最大读写速度已提高到312MB/s)。 [3]
SD卡主要分为四部分组成:外部引脚、内部寄存器、接口控制器和内部存储介质。 [3]
引脚
SD卡主要引脚和功能描述如下: [3]
CLK:时钟信号,控制器或者SD卡在每个时钟周期传输一个命令位或数据位,在SD总线的默认速度模式下频率可在0~25MHz之间变化,SD卡的总线管理器可以不受任何限制的自由产生0~25MHz的频率,在UHS-I速度模式下,时钟频率最高可达208M。 [3]
CMD:命令和响应复用引脚,命令是由控制器发给SD卡,可以是从控制器到单个SD卡,也可以是到SD总线上所有卡;响应是存储卡对控制器发送的命令应答,应答可以来自单卡或所有卡。 [3]
DAT0~3:数据线,数据可以从卡传向控制器也可以从控制器传向卡。
寄存器
寄存器及功能描述如下: [3]
OCR(Operating Conditions Register)寄存器:32位的操作条件寄存器主要存储了VDD电压范围,SD卡操作电压范围为2~3.6V。 [3]
CID(Card IDentification Register)寄存器:卡识别码寄存器,长度为16个字节,存储SD卡唯一标识号,该号在卡生产厂家编程后无法修改。 [3]
CSD(Card-Specific Data Register)寄存器:卡特性数据寄存器,包含了访问该卡数据时的必要配置信息。
SCR(SD Card Configuration Register)寄存器:SD卡配置寄存器(SCR),提供了SD卡的一些特殊特性在这张卡内,长度为64位,这个寄存器内容由制造商在生产厂内设置。 [3]
RCA(Relative Card Address)寄存器:卡相对地址寄存器是一个16位可写的地址寄存器,控制器可通过地址选择对应地址的SD卡。 [3]
DSR(Driver Stage Register)寄存器:驱动级寄存器,属于可选寄存器,用于配置卡的驱
SD卡初始化(SPI模式)
SPI操作模式下:在SD卡收到复位命令时,CS为有效电平(低电平),则SPI模式被启用,在发送CMD之前要先发送74个时钟,64个为内部供电上升时间,10个用于SD卡同步;之后才能开始CMD操作,在初始化时CLK时钟不能超过400KHz。
1、初始化与SD卡连接的硬件条件(MCU的SPI配置,IO口配置);
2、上电延时(>74个CLK);
3、复位卡(CMD0),进入IDLE状态;
4、发送CMD8,检查是否支持2.0协议;
5、根据不同协议检查SD卡(命令包括:CMD55、CMD41、CMD58和CMD1等);
6、取消片选,发多8个CLK,结束初始化
这样我们就完成了对SD卡的初始化,注意末尾发送的8个CLK是提供SD卡额外的时钟,完成某些操作。通过SD卡初始化,我们可以知道SD卡的类型(V1、V2、V2HC或者MMC),在完成了初始化之后,就可以开始读写数据了。
SD卡读取与写入(SPI模式)
1、发送CMD17;
2、接收卡响应R1;
3、接收数据起始令牌0XFE;
4、接收数据;
5、接收2个字节的CRC,如果不使用CRC,这两个字节在读取后可以丢掉。
6、禁止片选之后,发多8个CLK;
以上就是一个典型的读取SD卡数据过程,SD卡的写于读数据差不多,写数据通过CMD24来实现,具体过程如下:
1、发送CMD24;
2、接收卡响应R1;
3、发送写数据起始令牌0XFE;
4、发送数据;
5、发送2字节的伪CRC;
6、禁止片选之后,
发多8个CLK;
实验准备
连线
stm32 | SD卡模块 |
---|---|
PA4 | SDCS |
PA5 | SCK |
PA7 | MOSI |
PA6 | MISO |
VCC | VCC |
GND | GND |
配置HAL库
我直接下的代码,我不配,好吧
代码分析
main
int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration---------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_SPI1_Init(); MX_FATFS_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ HAL_UART_Receive_IT(&huart1,&aRxBuffer1,1); //enable uart printf(" main \r\n"); Get_SDCard_Capacity(); //得到使用内存并选择格式化 /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { WritetoSD(WriteBuffer,sizeof(WriteBuffer)); HAL_Delay(500); WriteBuffer[0] = WriteBuffer[0] +10; WriteBuffer[1] = WriteBuffer[1] +10; write_cnt ++; while(write_cnt > 10) { printf(" while \r\n"); HAL_Delay(500); } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
writetoSD
void WritetoSD(BYTE write_buff[],uint8_t bufSize) { FATFS fs; FIL file; uint8_t res=0; UINT Bw; res = SD_init(); //SD卡初始化 if(res == 1) { printf("SD卡初始化失败! \r\n"); } else { printf("SD卡初始化成功! \r\n"); } res=f_mount(&fs,"0:",1); //挂载 // if(test_sd == 0) //用于测试格式化 if(res == FR_NO_FILESYSTEM) //没有文件系统,格式化 { // test_sd =1; //用于测试格式化 printf("没有文件系统! \r\n"); res = f_mkfs("", 0, 0); //格式化sd卡 if(res == FR_OK) { printf("格式化成功! \r\n"); res = f_mount(NULL,"0:",1); //格式化后先取消挂载 res = f_mount(&fs,"0:",1); //重新挂载 if(res == FR_OK) { printf("SD卡已经成功挂载,可以进进行文件写入测试!\r\n"); } } else { printf("格式化失败! \r\n"); } } else if(res == FR_OK) { printf("挂载成功! \r\n"); } else { printf("挂载失败! \r\n"); } res = f_open(&file,SD_FileName,FA_OPEN_ALWAYS |FA_WRITE); if((res & FR_DENIED) == FR_DENIED) { printf("卡存储已满,写入失败!\r\n"); } f_lseek(&file, f_size(&file));//确保写词写入不会覆盖之前的数据 if(res == FR_OK) { printf("打开成功/创建文件成功! \r\n"); res = f_write(&file,write_buff,bufSize,&Bw); //写数据到SD卡 if(res == FR_OK) { printf("文件写入成功! \r\n"); } else { printf("文件写入失败! \r\n"); } } else { printf("打开文件失败!\r\n"); } f_close(&file); //关闭文件 f_mount(NULL,"0:",1); //取消挂载 }
结果
总结
做的太难受了呀,我丢,堪称折磨,
这篇关于SD卡数据读取的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-26Mybatis官方生成器资料详解与应用教程
- 2024-11-26Mybatis一级缓存资料详解与实战教程
- 2024-11-26Mybatis一级缓存资料详解:新手快速入门
- 2024-11-26SpringBoot3+JDK17搭建后端资料详尽教程
- 2024-11-26Springboot单体架构搭建资料:新手入门教程
- 2024-11-26Springboot单体架构搭建资料详解与实战教程
- 2024-11-26Springboot框架资料:新手入门教程
- 2024-11-26Springboot企业级开发资料入门教程
- 2024-11-26SpringBoot企业级开发资料详解与实战教程
- 2024-11-26Springboot微服务资料:新手入门全攻略