学习STM32之SD卡总结

合集下载

STM32F103调试读SD卡经验总结

STM32F103调试读SD卡经验总结

WL板子EK-STM32F103调试读S D卡经验总结一开始碰到的问题:发送CMD0能执行返回01,CMD1超时没响应。

查到原因:模板程序控制SD供电逻辑反了。

#if 0#define MSD_POWER_ON() GPIO_ResetBits(GPIOD, GPIO_Pi n_10)#define MSD_POWER_OFF() GPIO_SetBits(GPIOD, GPIO_Pin_10)#else#define MSD_POWER_ON() GPIO_SetBits(GPIOD, GPIO_Pin_10)#define MSD_POWER_OFF() GPIO_ResetBits(GPIOD, GPIO_Pin_10)#endif第二个问题:单步执行CMD0,CMD1,有响应,直接运行没响应。

查到原因,上电时间少于1ms,SD卡内部复位没准备好,初始化前加廷时1ms./* delay 1ms*/delay(5000);/* MSD chip select low */MSD_CS_LOW();/* Send CMD0 (GO_IDLE_STATE) to put MSD in SPI m ode */MSD_SendCmd(MSD_GO_IDLE_STATE, 0, 0x95);第三个问题:有时执行还是没有响应。

原因,SD卡初始化SPI时钟要在100kHz到400kHz之间,更改SPI速率为180kHz.第四个问题:读SD卡CSD寄存器没返回数据。

原因:供电不足,平时只有2.9V,SPI通迅时,出现瞬间低于2.7V现像。

短接直接供3.3V,如附图。

继续其它试验。

出处:kimfufree[最后修改于2008-09-03 19:58]。

STM32读写SD卡

STM32读写SD卡

3.20SD卡实验很多单片机系统都需要大容量存储设备,以存储数据。

目前常用的有U盘,FLASH芯片,SD卡等。

他们各有优点,综合比较,最适合单片机系统的莫过于SD卡了,它不仅容量可以做到很大(32Gb以上),而且支持SPI接口,方便移动,有几种体积的尺寸可供选择(标准的SD 卡尺寸,以及TF卡尺寸),能满足不同应用的要求。

只需要4个IO口,就可以外扩一个最大达32GB以上的外部存储器,容量选择尺度很大,更换也很方便,而且方便移动,编程也比较简单,是单片机大容量外部存储器的首选。

ALIENTKE MiniSTM3开发板就带有SD卡接口,利用STM32自带的SPI接口,最大通信速度可达18Mbps,每秒可传输数据2M字节以上,对于一般应用足够了。

本节将向大家介绍,如何在ALIENTEK MiniSTM32开发板上读取SD卡。

本节分为如下几个部分:3.20.1 SD卡简介3.20.2 硬件设计3.20.3 软件设计3.20.4 下载与测试3.20.1 SD卡简介SD卡(Secure Digital Memory Card)中文翻译为安全数码卡,是一种基于半导体快闪记忆器的新一代记忆设备,它被广泛地于便携式装置上使用,例如数码相机、个人数码助理(PDA)和多媒体播放器等。

SD卡由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制。

大小犹如一张邮票的SD记忆卡,重量只有2克,但却拥有高记忆容量、快速数据传输率、极大的移动灵活性以及很好的安全性。

SD卡一般支持2种操作模式:1,SD卡模式;2,SPI模式;主机可以选择以上任意一种模式同SD卡通信,SD卡模式允许4线的高速数据传输。

SPI模式允许简单的通过SPI接口来和SD卡通信,这种模式同SD卡模式相比就是丧失了速度。

SD卡的引脚排序如下图所示:图3.20.1.1 SD卡引脚排序图SD卡引脚功能描述如下表所示:表3.20.1.1 SD卡引脚功能表SD卡只能使用3.3V的IO电平,所以,MCU一定要能够支持3.3V的IO端口输出。

STM32笔记(四)数据帧构成

STM32笔记(四)数据帧构成

STM32笔记(四)数据帧构成113、数据帧构成:(1)帧起始。

表示数据开的段帧起始。

(2)仲裁段。

表示该帧优先级的仲裁段。

(3)控制段。

表示数据的字节及保留位段。

(4)数据段。

数据的内容,一帧可发送0~8个字节的数据。

(5) CRC段。

检查帧的传输错误段。

(6) ACK段。

表示确认正常接收的段。

(7)帧结束。

表示数据的段帧结束。

114、 Stm32f103系列只有一个CAN控制器,有3个发送邮箱和3级深度的2个FIFO,14个过滤组器。

115、 STM32的每个过滤组可以配置为1个32位过滤器和2个16位过滤器。

除此之外,还可以配置为屏蔽位模式(ID 屏蔽)和标识符列表(ID和屏蔽寄存器均用来做ID寄存器)模式。

116、 CAN接收到有效报文被放置在3级邮箱深度的FIFO中,FIFO完全由硬件来管理。

117、 CAN总线的波特率118、触摸屏一般分为电阻式触摸屏和电容式触摸屏。

前者检测触摸的位置原理是利用触摸屏控制器中的A/D转换器经过两次A/D读值后得出X和Y的坐标值。

注意:这个X和Y的值是相对于触摸屏的,而非LCD屏。

所以在这里需要注意两个概念:触摸屏和LCD屏。

这是两个不同的概念,也是两个不同的物理结构,其中电阻触摸屏是由上下两个导电层中间夹着一层非常薄的透明隔层;而LCD就是指显示屏。

119、电阻触摸屏有X和Y、X和Y的比例因子、坐标轴方向、偏移量。

LCD也有自己的这些参数。

两者完全不相干,所以在定位的时候需要进行坐标转换。

公式:通过对屏幕的四个点进行校准,得到四元一次方程,求解即可。

120、 NEC协议的数据帧格式:同步码头、地址码、地址反码、控制码、控制反码。

同步码由一个9ms的低电平和一个4.5ms的高电平组成,地址码、地址反码、控制码、控制反码均是8位数据格式。

按照低位在前,高位在后的顺序发送。

121、 NEC协议在发送的时候,会有560us的38KHz的载波信号,而在接收的时候这部分载波信号被认定为低电平,而剩余的(2.25ms-650us)的逻辑“1”和(1.12ms-650us)的逻辑“0”时间则被认定为高电平。

STM32读写SD卡要点

STM32读写SD卡要点

3.20SD卡实验很多单片机系统都需要大容量存储设备,以存储数据。

目前常用的有U盘,FLASH芯片,SD卡等。

他们各有优点,综合比较,最适合单片机系统的莫过于SD卡了,它不仅容量可以做到很大(32Gb以上),而且支持SPI接口,方便移动,有几种体积的尺寸可供选择(标准的SD 卡尺寸,以及TF卡尺寸),能满足不同应用的要求。

只需要4个IO口,就可以外扩一个最大达32GB以上的外部存储器,容量选择尺度很大,更换也很方便,而且方便移动,编程也比较简单,是单片机大容量外部存储器的首选。

ALIENTKE MiniSTM3开发板就带有SD卡接口,利用STM32自带的SPI接口,最大通信速度可达18Mbps,每秒可传输数据2M字节以上,对于一般应用足够了。

本节将向大家介绍,如何在ALIENTEK MiniSTM32开发板上读取SD卡。

本节分为如下几个部分:3.20.1 SD卡简介3.20.2 硬件设计3.20.3 软件设计3.20.4 下载与测试3.20.1 SD卡简介SD卡(Secure Digital Memory Card)中文翻译为安全数码卡,是一种基于半导体快闪记忆器的新一代记忆设备,它被广泛地于便携式装置上使用,例如数码相机、个人数码助理(PDA)和多媒体播放器等。

SD卡由日本松下、东芝及美国SanDisk公司于1999年8月共同开发研制。

大小犹如一张邮票的SD记忆卡,重量只有2克,但却拥有高记忆容量、快速数据传输率、极大的移动灵活性以及很好的安全性。

SD卡一般支持2种操作模式:1,SD卡模式;2,SPI模式;主机可以选择以上任意一种模式同SD卡通信,SD卡模式允许4线的高速数据传输。

SPI模式允许简单的通过SPI接口来和SD卡通信,这种模式同SD卡模式相比就是丧失了速度。

SD卡的引脚排序如下图所示:图3.20.1.1 SD卡引脚排序图SD卡引脚功能描述如下表所示:表3.20.1.1 SD卡引脚功能表SD卡只能使用3.3V的IO电平,所以,MCU一定要能够支持3.3V的IO端口输出。

基于stm32f103对sd卡底层的基本操作方法

基于stm32f103对sd卡底层的基本操作方法

基于stm32f103对sd卡底层的基本操作方法基于STM32F103的SD卡底层操作方法是指通过STM32F103系列微控制器来对SD卡进行读写操作的一组基本方法。

本文将详细介绍如何配置STM32F103的SPI接口和相关寄存器,以及如何使用SPI接口与SD卡进行通信和文件操作。

一、硬件连接首先,需要连接STM32F103与SD卡之间的硬件接口。

STM32F103的SPI接口包括四根引脚,分别是NSS(片选信号)、SCK(时钟信号)、MISO(数据输入信号)和MOSI(数据输出信号)。

通常,可以将SD卡的NSS引脚连接到STM32F103的任一GPIO引脚上作为片选信号,并通过软件控制片选信号的高低电平来选择SD卡进行读写操作。

此外,还需要将SD卡的SCK、MISO和MOSI引脚分别连接到STM32F103的SPI接口的SCK、MISO和MOSI引脚上。

为了方便起见,可以直接使用STM32F1的SPI中的SPI1进行配置。

二、SPI接口配置在STM32F103中,SPI接口由SPI1、SPI2和SPI3三个外设实现,其中SPI1位于APB2总线上,SPI2和SPI3位于APB1总线上。

在本文中,我们将使用SPI1进行SD卡的底层操作。

首先,需要在CubeMX中将SPI1的NSS、SCK、MISO和MOSI引脚分别配置为GPIO输出、SPI时钟、SPI数据输入和SPI数据输出功能。

然后,需要配置SPI1的时钟分频系数、数据位数、传输模式等参数。

SPI1的时钟分频系数由BDIV和BR两个参数决定,其中BDIV位于SPI1->CR1寄存器的位6-7位,用于设定SPI1主频的1/2、1/4、1/8还是1/16,BR位于SPI1->CR1寄存器的位3-5位,用于设定SPI1的分频系数。

根据SD卡的时钟特性,一般选择SPI1的分频系数为sclk/32,其中sclk为主控芯片时钟。

在SPI接口配置完成之后,需要打开SPI1外设时钟使能,并设置SPI1的工作模式、数据位数等参数。

STM32笔记(六)SD卡的读写和FatFS文件系统

STM32笔记(六)SD卡的读写和FatFS文件系统

STM32笔记(六)SD卡的读写和FatFS文件系统因为要用,学习了一下SPI操作SD卡,同时移植了一个免费开源的FAT文件系统:FatFS。

感觉挺好,在单片机上实现了读写文件的操作,接下来就可以解释我的G代码咯!我的SD卡底层操作参考了网上几种常见的代码,但又对其结构做了一定的优化,至少看起来用起来比较方便。

既可以作为文件系统的diskio使用,也可以直接使用底层函数,把SD卡作为一块flash读写。

FatFs文件系统体积蛮小,6-7K足矣,对于128Kflash的STM32来说很合适,代价不大。

同时可移植性很高,最少只需要4个函数修改既可以实现文件系统的移植。

相关文件系统的介绍请看这里。

这里给一套比较完整的参考资料,包括fatfs文件系统的原版资料、几个重要的手册和网上下载的代码。

/bbs/bbs_content.jsp?bbs_sn=3210864&bbs_page_no=1&bbs_id=3020 下面是我的代码:其中底层的SPI总线对SD卡的操作在SPI_SD_driver.c/h中,而FATFS的移植文件diskio.c中对磁盘的操作函数中将调用底层的操作函数。

下面是一些底层操作函数:u8 SPI_ReadWriteByte(u8 TxData); //SPI总线读写一个字节u8 SD_WaitReady(void); //等待SD卡就绪u8 SD_SendCommand(u8 cmd, u32 arg, u8 crc); //SD卡发送一个命令u8 SD_SendCommand_NoDeassert(u8 cmd, u32 arg, u8 crc); //SD卡发送一个命令,不断线u8 SD_Init(void); //SD卡初始化u8 SD_ReceiveData(u8 *data, u16 len, u8 release); //SD卡读数据u8 SD_GetCID(u8 *cid_data); //读SD卡CIDu8 SD_GetCSD(u8 *csd_data); //读SD卡CSDu32 SD_GetCapacity(void); //取SD卡容量u8 SD_ReadSingleBlock(u32 sector, u8 *buffer); //读一个sectoru8 SD_WriteSingleBlock(u32 sector, const u8 *buffer); //写一个sectoru8 SD_ReadMultiBlock(u32 sector, u8 *buffer, u8 count); //读多个sectoru8 SD_WriteMultiBlock(u32 sector, const u8 *data, u8 count); //写多个sector这是diskio.c中的一段代码,在disk初始化中,我们调用了SPI_SD_driver.c中的SD卡初始化函数。

智芯STM32开发板SD卡资料SD卡要点说明

智芯STM32开发板SD卡资料SD卡要点说明

SD 卡 要 点 说 明
Written by pasyong
SD卡有两个可选的通信协议:SD模式和SPI模式。

为了电路的简化,选用SPI模式。

模式选择;SD卡默认为SD模式,要进入SPI模式时,要遵守如下操作。

当SD卡接收RESTE命令(CMD0)时,拉低CS即可。

命令CMD0就是0,CMD16就是16,其它以此类推。

SPI命令格式如下,由6个字节构成,高位在前。

SPI模式下Command从CMD0到CMD63。

Command Argument为附加命令,有些CMD命令有,有些无,CRC为校验字节。

下图是SPI模式下的命令分类表。

SPI命令分为11个组,各个组是多个命令的集合,每个组中的命令有相似的功能。

这里介绍三个常用命令。

CMD0,CMD1,CMD16
CMD0 为复位,CMD1为激活初始化,CMD16设置一个读写块的长度。

有些命令发送出去后会有返回值,表示的是错误码。

比如CMD0,CMD1返回值是R1格式的。

一个字节长,0,7位是0,其它位表示错误码。

SD卡初始化
在上电后,主机启动SCK及在CMD线上发送74个高电平的信号,接着发送CMD0进入SPI 模式,然后发送CMD1激活初始化进程。

读扇区:SD卡允许以块数据进行读写,在这里我们用CMD16命令设定每读写的块为512字节,正好是一个扇区。

设置好后用CMD17读块命令读取512放入缓冲区既可。

新版STM32 HAL库SD卡读写不正常总结

新版STM32 HAL库SD卡读写不正常总结
官方给的驱动未使用DMA,读写不正常表现: 单个字节循环写文件,有时候写到1KB就出错,有时候能写到400KB,测试写到1MB,但多次测试没有一次能写完成。 自己移值的驱动使用DMA,因为没有参考,所以移植的也有问题。
2个版本的SD卡驱动改动较大, 看一下对比 V1.14.0 uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks) uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks)
V1.15.0 uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout) uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks)
if(BSP_SD_ReadBlocks_DMA((uint32_t*)buff,(uint32_t)(sector),count) == MSD_OK) {
while( BSP_SD_RxOK()==0 || BSP_SD_GetCardState()!=MSD_OK ) //读写完成的判断需要同时同时满足 {
sd_tx_ok = 1; } void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd) {

stm32f103c8t6 tf卡简单的读写函数

stm32f103c8t6 tf卡简单的读写函数

stm32f103c8t6 tf卡简单的读写函数STM32F103C8T6是一款常用的微控制器,它内部集成了SDIO接口,可以方便地与TF卡进行数据读写。

在本文中,我将介绍一些简单的读写函数,以帮助您在STM32F103C8T6上使用TF卡。

下面是相关内容:一、TF卡介绍TF卡(T-Flash卡)是一种袖珍型存储卡,广泛应用于移动设备中。

它的体积小、价格低廉,并且容量可扩展。

在STM32F103C8T6上使用TF卡,可以实现大量数据存储,方便后续的读写操作。

二、初始化函数在使用TF卡之前,我们需要进行初始化操作。

以下是一个简单的TF卡初始化函数示例:```c#include "stm32f10x.h"void TF_Card_Init(){// 初始化SPI接口RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);SPI_InitTypeDef SPI_InitStructure;SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;SPI_InitStructure.SPI_Mode = SPI_Mode_Master;SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;// 更多SPI参数配置,如速率、时钟极性等// ...SPI_Init(SPI1, &SPI_InitStructure);SPI_Cmd(SPI1, ENABLE);// 等待TF卡初始化完成while(TF_Card_SendCommand(CMD0, 0) != 0x01);}```该函数使用了STM32F10x库,通过SPI1接口与TF卡进行通信。

在实际使用中,您需要根据TF卡的具体规格进行参数的设置和修改。

三、读取函数TF卡的读取操作可以通过发送命令和读取数据实现。

基于STM32F407平台实现FATFS读写大容量(128G)SD卡的心得

基于STM32F407平台实现FATFS读写大容量(128G)SD卡的心得

基于STM32F407平台实现FATFS读写大容量(128G)SD卡的心得本人是沈阳大学的一名小白,之前,无论是STM32,还是FATFS,都是小白一个,甚至不理解那是什么东西,但是据说这种技术目前为止好像是读写大容量卡挺费劲,只能64G,就到头了,但是最近接到一个任务就是做一个数据记录仪而且要把这个东西做成128G 的。

废话不多说,直接来把。

首先你要知道FATFS 是一个文件管理系统,看他的手册,分为应用层,底层驱动等等,但是对于我们嵌入式开发者来说,移植他,我们需要的是修改底层驱动!应用他给出的API 实现自己的任务。

修改底层驱动!应用他给出的API 实现自己的任务。

修改底层驱动!应用他给出的API 实现自己的任务。

1、修改底层驱动官网下载,需注意他的版本,如果你做32G ,64G, OK 那你下载哪个版本都可以,建议下载低版本,如0.10 版本左右的都可以。

如果你想做大容量卡,那一定要移植0.12 之后的版本,现在我写这篇文章的时候,最新版是0.13a,所以我就简单说一下0.13a。

0.13a 的底层驱动,也就是你下载下来的有一个diskio.c 的文件,你打开。

正常的移植,是在这里写或者修改底层驱动,底层驱动是什么呢,例如我这次用的是SDIO 操作读写SD 卡的,大家都知道,SDIO 操作SD 卡有两种方式,一个是SPI,一个是SDIO。

那我要写的就是这两种中的一个了。

我用的是SDIO,因为这种速度块。

继续说,当你打开0.13a 的diskio.c 的时候,你会发现这帮人TMD 写的很随意,这里如果你是个大手你可以自己写好你的底层驱动(就是刚才我说的那个如何通过SDIO 操作SD 卡),如果嫌费劲,直接拿你开发板给出的例程里的diskio.c(每个嵌入式开发者手里都会有开发板吧?!)因为它给出这个一定是调好的!。

基于STM32的几种读SD卡方式的速度探究

基于STM32的几种读SD卡方式的速度探究

F I F O  ̄
C MD7 命令 选择 卡 , 配置 D MA2 , 发送 C MD 2 4 ( 开始 写数据 ) , 查 询D MA 通 道的使 能状 态 寄存器 , 确认 没 有通 道仍 处于 使 能状 态 。 配 置D MA2 的具 体步 骤如 下 :
1 ) 使  ̄D MA2 控 制器 并 清 除所有 的 中断 标志 位 。
特性 , 如 今越 来越 多 的芯 片集 成 了这种 通信 协 议 。
1 . 3 S D1 0
S D 卡 读取 操作 后 , 先 发送一 个起 始数 据 命令 , 接 着发 送 固定数 量 的数据 , 最 后 是2 个 字节 的C RC 校验 。 2 3 S D 卡的 文件存 储
1 . 硬 件设 计
1 . 1 ST M 3 2 F 1 0 3 Z E T6
2 . 1 . 2将S D 卡初 始 化 为S D I O 模 式 首先 上 电( p o we r - o n ) , 然后发出C MD 0, 再接着发送C MD8, 有 应 答
S T M3 2 F 1 0 3 z E T 6 基于 高 性 能3 2 位 RI S C 的AR M C o r t e x - M3 核, 其最 高 工 作频 率为 7 2 MHz 。 片上 集 成了高 速 存储 器 ,
须 与 计 算机 的文 件 系 统 兼容 。 目前 常用 的文 件 系 统 主 要 有 w i n d o WS 下 的
F A T3 2 , NT F S , L u x 下的E XT 2 , E XT 3 等。
2 4 D M A 的配置

S T M3 2 F 1 0 x 系列 MCU支持D MA功 能 , 可 以直接 将数 据从 一 个地 址 空 间

【STM32】使用SDIO进行SD卡读写,包含文件管理FatFs(六)-FatFs使用的思路介绍

【STM32】使用SDIO进行SD卡读写,包含文件管理FatFs(六)-FatFs使用的思路介绍

f_open打开/创建⽂件f_close关闭⽂件f_read读取⽂件f_write写⼊⽂件f_lseek移动读/写指针,扩展⼤⼩f_truncate 截断⽂件f_sync 刷新缓存数据f_forward 转移⽂件数据到⼀个数据流f_expand 为⽂件分配⼀个连续的块f_gets 读取⼀个字符串(string )f_putc写⼊⼀个字符(character )f_puts写⼊⼀个字符串(string )f_printf写⼊⼀个格式化字符串f_tell获取当前读/写指针f_eof⽂件结束测试f_size获取长度f_error测试错误f_opendir 打开⼀个⽬录f_closedir 关闭⼀个已打开的⽬录f_readdir 读取⽬录f_findfirst 打开⼀个⽬录并读取匹配的第⼀个项⽬f_findnext 查找下⼀个匹配的项⽬【STM32】使⽤SDIO 进⾏SD 卡读写,包含⽂件管理FatFs (六)-FatFs 使⽤的思路介绍本篇要来介绍⽂件管理FatFs官⽅的⽹站是:这是⼀个⽇本⼈写的,除了⽂件管理以外,还有其他的,例如解码JPEG 、红外遥控等在官⽹链接内,最下⽅有个Return ,点击后就可以看到相关的开源库以下开始正题(本⽂⾥提到的媒介,其实就是设备了,我不想改图了...)打开官⽅⽹站,页⾯简单明了,就分为4个区块(以下图⽚为FatFs 官⽹上截取的图⽚)第⼀区块、介绍及特性(Features ):FatFs 是⽂件管理系统,可⽤于SD 卡、硬盘(ATA )、RTC 时钟,FTL 和etc 不清楚是什么,另外,也可以⽤于Flash 或是EEPROM第⼆区块、应⽤接⼝(Application Interface ):FatFs 提供了接⼝,使得我们的应⽤可以和它交互。

官⽹左侧为⼀些接⼝的介绍,分四个部分第⼀部分:File Access (⽂件存取)第⼆部分:Directory Access (⽬录访问)f_stat 检查⽂件或⼦⽬录是否存在f_unlink 删除⽂件或⼦⽬录f_rename 重命名/移动⽂件或⼦⽬录f_chmod 更改⽂件或⼦⽬录的属性f_utime更改⽂件或⼦⽬录的时间戳f_mkdir创建⼦⽬录f_chdir 更改当前⽬录f_chdive 更改当前驱动f_getcwd 检索当前⽬录和驱动f_mount注册/注销⼀个⼯作区(挂起与否)f_mkfs在逻辑驱动上创建⼀个FAT 卷f_fdisk 在物理驱动上创建分区f_getfree 获取卷上的可⽤空间f_getlabel 获取卷标f_setlabel 设置卷标f_setcp设置活动代码页disk_status获取设备状态disk_initialize 初始化设备disk_read读取数据disk_write写⼊数据disk_ioctl控制设备相关功能get_fattime 获取当前时间第三部分:File and Dirextor Management (⽂件和⽬录管理)第四部分:Volume Management and System Configuration (卷管理和系统配置)第三区块、媒介访问接⼝(Media Access Interface ):你想管理的存储设备,必须要和FatFs 链接。

STM32下SD卡的读取

STM32下SD卡的读取

STM32下SD卡的读取⼀、SD卡模块介绍1.1 什么是SD卡SD存储卡是⼀种基于半导体快闪记忆器的新⼀代记忆设备,由于它体积⼩、数据传输速度快、可热插拔等优良的特性,被⼴泛地于便携式装置上使⽤,例如数码相机、平板电脑和多媒体播放器等。

控制器对 SD 卡进⾏读写通信操作⼀般有两种通信接⼝可选,⼀种是 SPI 接⼝,另外⼀种是 SDIO 接⼝。

1.2 SD卡的物理结构⼀张SD卡包括有存储单元、存储单元接⼝、电源检测、卡及接⼝控制器和接⼝驱动器5 个部分。

存储单元是存储数据部件,存储单元通过存储单元接⼝与卡控制单元进⾏数据传输;电源检测单元保证SD卡⼯作在合适的电压下,如出现掉电或上状态时,它会使控制单元和存储单元接⼝复位;卡及接⼝控制单元控制SD卡的运⾏状态,它包括有8个寄存器;接⼝驱动器控制 SD 卡引脚的输⼊输出。

⼆、项⽬代码已挂载在Github上烧录程序成功后:主要函数代码分析: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(" mian \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] +0;WriteBuffer[1] = WriteBuffer[1] +1;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 */}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); //取消挂载}程序⾸先进⾏相关初始化,完成后输出mian,之后进⾏SD卡格式化,成功后进⼊循环,进⼊SD卡读写函数,先后进⾏SD卡的初始化,挂载,创⽂件,写⼊,写⼊超过10次,输出while三、相关引脚的配置CS -> PB0SCK -> PA5MISO -> PA6MOSI -> PA7四、实验结果SD卡中⽣成⼀个新的hello.txt⽂件内容如下更改写⼊内容写⼊结果如下:五、⼼得体会在初始化过程中确保SD格式化成FAT⽂件模式,确保单⽚机的供电和SD卡模块的供电最好是5V,不然可能带不动SD卡驱动导致实验失败。

stm32SPI模式读写SD卡

stm32SPI模式读写SD卡

stm32SPI模式读写SD卡SPI模式读写SD卡SD卡初始化过程:1. 初始化STM32的SPI接口使用低速模式2. 延时至少74clock3. 发送CMD0,需要返回0x01,进入Idle状态4. 循环发送CMD55+ACMD41,直到返回0x00,进入Ready状态5. 设置读写block大小为512byte5. 把STM32的SPI设置为高速模式读一个block块的过程1. 发送CMD17(单块)或CMD18(多块)读命令,返回0x002. 接收数据开始令牌0xfe + 正式数据512Bytes + CRC 校验2Bytes写一个block块的过程1. 发送CMD24(单块)或CMD25(多块)写命令,返回0x002. 发送数据开始令牌0xfe + 正式数据512Bytes + CRC校验2Bytes/******************************************************************* ************* Function Name : SD_MMC_SPI_Init* Description : SD_MMC_SPI_Init* Input : None* Output : None* Return : zero init success, non-zero init error************************************************************************ *******/u8 SD_MMC_SPI_Init(void){GPIO_InitTypeDef GPIO_InitStructure;/* Enable SPI1 and GPIO clocks */RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_SD_MMC_SPI_CS, ENABLE);/* Configure SPI1 pins: SCK, MISO and MOSI */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);/* Configure SD_MMC_SPI_CS */GPIO_InitStructure.GPIO_Pin = SD_MMC_SPI_CS_Pin_CS;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(SD_MMC_SPI_CS, &GPIO_InitStructure);///////////////////////////////////////////////////////////////////////////////* initialize SPI with lowest frequency */SD_MMC_Low_Speed();/* card needs 74 cycles minimum to start up */for(u8 i = 0; i < 10; ++i) {/* wait 8 clock cycles */ SD_MMC_ReadWrite_Byte(0x00); } /* address card */ SD_MMC_SPI_SELECT();/* reset card */u8 response;for(u16 i = 0; ; ++i){response = SD_MMC_Send_Command(CMD_GO_IDLE_STATE ,0 );if( response == 0x01 ) break;if(i == 0x1ff) {SD_MMC_SPI_DESELECT(); return 1;}}/* wait for card to get ready */ for(u16 i = 0; ; ++i) {response = SD_MMC_Send_Command(CMD_SEND_OP_COND, 0);if(!(response & (1 << R1_IDLE_STATE)))break;if(i == 0x7fff) {SD_MMC_SPI_DESELECT(); return 1;}}/* set block size to 512 bytes */if(SD_MMC_Send_Command(CMD_SET_BLOCKLEN, 512)) {SD_MMC_SPI_DESELECT();return 1;}/* deaddress card */SD_MMC_SPI_DESELECT();/* switch to highest SPI frequency possible */ SD_MMC_High_Speed();return 0;//////////////////////////////////////////////////////////////////// //////////}/******************************************************************* ************* Function Name : SD_MMC_Read_Single_Block * Description :SD_MMC_Read_Single_Block * Input : sector number and buffer data point * Output : None* Return : zero success, non-zero error************************************************************************ *******/u8 SD_MMC_Read_Single_Block(u32 sector, u8* buffer) {u8 Response;u16 i;u16 Retry = 0;//读命令 send read commandResponse =SD_MMC_Send_Command(CMD_READ_SINGLE_BLOCK, sector<<9); if(Response != 0x00)return Response;SD_MMC_SPI_SELECT();// start byte 0xfewhile(SD_MMC_ReadWrite_Byte(0xff) != 0xfe) {if(++Retry > 0xfffe){SD_MMC_SPI_DESELECT();return 1; //timeout}}for(i = 0; i < 512; ++i) {//读512个数据*buffer++ = SD_MMC_ReadWrite_Byte(0xff); }SD_MMC_ReadWrite_Byte(0xff); //伪crcSD_MMC_ReadWrite_Byte(0xff); //伪crcSD_MMC_SPI_DESELECT();SD_MMC_ReadWrite_Byte(0xff); // extra 8 CLKreturn 0;}/******************************************************************* ************* Function Name : SD_MMC_Write_Single_Block* Description : SD_MMC_Write_Single_Block * Input : sector number and buffer data point* Output : None* Return : zero success, non-zero error.************************************************************************ *******/u8 SD_MMC_Write_Single_Block(u32 sector, u8* buffer) {u8 Response;u16 i;u16 retry=0;//写命令 send write commandResponse =SD_MMC_Send_Command(CMD_WRITE_SINGLE_BLOCK, sector<<9);if(Response != 0x00)return Response;SD_MMC_SPI_SELECT();SD_MMC_ReadWrite_Byte(0xff);SD_MMC_ReadWrite_Byte(0xff);SD_MMC_ReadWrite_Byte(0xff);//发开始符 start byte 0xfeSD_MMC_ReadWrite_Byte(0xfe);//送512字节数据 send 512 bytes datafor(i=0; i<512; i++){SD_MMC_ReadWrite_Byte(*buffer++);}SD_MMC_ReadWrite_Byte(0xff); //dummy crc SD_MMC_ReadWrite_Byte(0xff); //dummy crcResponse = SD_MMC_ReadWrite_Byte(0xff);//等待是否成功 judge if it successfulif( (Response&0x1f) != 0x05){SD_MMC_SPI_DESELECT();return Response;}//等待操作完 wait no busywhile(SD_MMC_ReadWrite_Byte(0xff) != 0x00) {if(retry++ > 0xfffe){SD_MMC_SPI_DESELECT();return 1;}}SD_MMC_SPI_DESELECT();SD_MMC_ReadWrite_Byte(0xff);// extra 8 CLKreturn 0;}if( SD_MMC_SPI_Init() ==1)printf(" _SD_MMC Initialization ERROR\r\n"); else{printf(" _SD_MMC Initialization OK\r\n"); //memset(buffer,0,512); //读取一个扇区的内容这里读的是0扇区SD_MMC_Read_Single_Block( 0 , buffer );Uart1_PutString( buffer , 512 );}。

调试STM32+FATFS+SDIO的总结

调试STM32+FATFS+SDIO的总结

这两天调试stm32单片机的sdio接口读写sd卡,把调试经验总结一下。

我首先采用的是官方例程里面得dma方式,直接使用官方提供的sdcard.c文件。

首先声明一个uint32类型的数据缓冲区,读写sd卡的每个扇区完全正常,随后添加fatfs的文件,然后改好接口函数,其中有一处做了强制转换,就是fatfs声明的缓冲区都是uint8*类型的,而sdcard.c文件要求为uint32*类型,所以我把uint8*强制转换为uint32*类型。

编译成功后执行,结果fatfs的初始化函数返回“没有文件系统”,经过多次小改动后重试,问题依然如此,后来我怀疑是我强制转换出的问题,为了验证我的想法,我做了如下程序:#include <stdio.h>#include <string.h>void main(void){unsigned char i;//AA[] = {0,1,2,3,4,5,6,7,8,9,0,4};unsigned char * aa;unsigned int * bb;for(i=0;i<10;i++){*(aa+i) = i;}bb = (unsigned int *)aa;printf("bb is: 0X%04x \n",*bb);bb = (unsigned int *)(aa+1);printf("bb is: 0X%04x \n",*bb);while(1);}以上程序验证结果为:在IAR EWARM 5.40中,强制转换不会对数据存取产生影响。

既然不是这个问题,那会是什么呢?!我只好单步执行程序,一步步追踪下去,看看到底问题出在哪里。

功夫不负有心人,最后终于发现出问题的地方,如下图:原来是DMA传输出了错误,fatfs声明的uint8*的缓冲区不是从整4倍字节地址开始的,而DMA控制器在操作uint32*类型地址的时候必须从整4倍字节地址开始,由于强制转换,产生了2个字节的偏移,从而导致最终的数据错误。

stm32f103c8t6 tf卡简单的读写函数

stm32f103c8t6 tf卡简单的读写函数

文章标题:探索STM32F103C8T6与TF卡的简单读写函数在嵌入式系统开发中,TF卡的读写功能一直是一个不可或缺的部分。

而对于如何在STM32F103C8T6芯片上实现简单的TF卡读写函数,也是我们经常需要探讨的一个问题。

在本文中,我们将会从简单到复杂地讨论如何在STM32F103C8T6芯片上实现TF卡的读写功能,以便读者能更深入地理解这一过程。

1. TF卡简介在开始讨论TF卡的读写函数之前,我们先简要介绍一下TF卡的基本知识。

TF卡,全称TransFlash卡,又称MicroSD卡,是一种常见的存储卡,常用于嵌入式系统、手机、相机等设备中。

TF卡具有体积小、读写速度快、存储容量大等优点,因此在嵌入式系统中得到广泛应用。

2. STM32F103C8T6与TF卡的连接在实现TF卡读写功能之前,首先需要将TF卡与STM32F103C8T6芯片进行连接。

一般来说,TF卡的连接方式是通过SPI接口进行。

SPI接口是一种串行外设接口,可以实现与外部设备的高速数据传输。

通过SPI接口连接TF卡,可以在STM32F103C8T6芯片上实现对TF卡的读写操作。

3. TF卡读写函数的实现在STM32F103C8T6芯片上实现TF卡的读写函数,一般需要以下几个步骤:初始化SPI接口、初始化TF卡、读取TF卡数据、写入TF卡数据。

需要初始化SPI接口,设置好SPI的时钟频率、数据传输格式等参数。

通过初始化TF卡,可以对TF卡进行一些基本的设置,比如设置TF卡的工作模式、文件系统类型等。

接下来,可以通过读取TF 卡数据和写入TF卡数据函数,实现对TF卡的读写操作。

4. 个人观点和总结通过深入地探讨STM32F103C8T6与TF卡的简单读写函数,我对于嵌入式系统中TF卡的应用有了更深入的理解。

在实际应用中,我们需要根据具体的需求和硬件评台来选择合适的读写函数,并且需要注意好数据的正确读取和写入,以保证系统的稳定性和可靠性。

stm32SPI模式读写SD卡

stm32SPI模式读写SD卡

stm32SPI模式读写SD卡SPI模式读写SD卡SD卡初始化过程:1. 初始化STM32的SPI接口使用低速模式2. 延时至少74clock3. 发送CMD0,需要返回0x01,进入Idle状态4. 循环发送CMD55+ACMD41,直到返回0x00,进入Ready状态5. 设置读写block大小为512byte5. 把STM32的SPI设置为高速模式读一个block块的过程1. 发送CMD17(单块)或CMD18(多块)读命令,返回0x002. 接收数据开始令牌0xfe + 正式数据512Bytes + CRC 校验2Bytes写一个block块的过程1. 发送CMD24(单块)或CMD25(多块)写命令,返回0x002. 发送数据开始令牌0xfe + 正式数据512Bytes + CRC校验2Bytes/******************************************************************* ************* Function Name : SD_MMC_SPI_Init* Description : SD_MMC_SPI_Init* Input : None* Output : None* Return : zero init success, non-zero init error************************************************************************ *******/u8 SD_MMC_SPI_Init(void){GPIO_InitTypeDef GPIO_InitStructure;/* Enable SPI1 and GPIO clocks */RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_SD_MMC_SPI_CS, ENABLE);/* Configure SPI1 pins: SCK, MISO and MOSI */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);/* Configure SD_MMC_SPI_CS */GPIO_InitStructure.GPIO_Pin = SD_MMC_SPI_CS_Pin_CS;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(SD_MMC_SPI_CS, &GPIO_InitStructure);///////////////////////////////////////////////////////////////////////////////* initialize SPI with lowest frequency */SD_MMC_Low_Speed();/* card needs 74 cycles minimum to start up */for(u8 i = 0; i < 10; ++i) {/* wait 8 clock cycles */ SD_MMC_ReadWrite_Byte(0x00); } /* address card */ SD_MMC_SPI_SELECT();/* reset card */u8 response;for(u16 i = 0; ; ++i){response = SD_MMC_Send_Command(CMD_GO_IDLE_STATE ,0 );if( response == 0x01 ) break;if(i == 0x1ff) {SD_MMC_SPI_DESELECT(); return 1;}}/* wait for card to get ready */ for(u16 i = 0; ; ++i) {response = SD_MMC_Send_Command(CMD_SEND_OP_COND, 0);if(!(response & (1 << R1_IDLE_STATE)))break;if(i == 0x7fff) {SD_MMC_SPI_DESELECT(); return 1;}}/* set block size to 512 bytes */if(SD_MMC_Send_Command(CMD_SET_BLOCKLEN, 512)) {SD_MMC_SPI_DESELECT();return 1;}/* deaddress card */SD_MMC_SPI_DESELECT();/* switch to highest SPI frequency possible */ SD_MMC_High_Speed();return 0;//////////////////////////////////////////////////////////////////// //////////}/******************************************************************* ************* Function Name : SD_MMC_Read_Single_Block * Description :SD_MMC_Read_Single_Block * Input : sector number and buffer data point * Output : None* Return : zero success, non-zero error************************************************************************ *******/u8 SD_MMC_Read_Single_Block(u32 sector, u8* buffer) {u8 Response;u16 i;u16 Retry = 0;//读命令 send read commandResponse =SD_MMC_Send_Command(CMD_READ_SINGLE_BLOCK, sector<<9); if(Response != 0x00)return Response;SD_MMC_SPI_SELECT();// start byte 0xfewhile(SD_MMC_ReadWrite_Byte(0xff) != 0xfe) {if(++Retry > 0xfffe){SD_MMC_SPI_DESELECT();return 1; //timeout}}for(i = 0; i < 512; ++i) {//读512个数据*buffer++ = SD_MMC_ReadWrite_Byte(0xff); }SD_MMC_ReadWrite_Byte(0xff); //伪crcSD_MMC_ReadWrite_Byte(0xff); //伪crcSD_MMC_SPI_DESELECT();SD_MMC_ReadWrite_Byte(0xff); // extra 8 CLKreturn 0;}/******************************************************************* ************* Function Name : SD_MMC_Write_Single_Block* Description : SD_MMC_Write_Single_Block * Input : sector number and buffer data point* Output : None* Return : zero success, non-zero error.************************************************************************ *******/u8 SD_MMC_Write_Single_Block(u32 sector, u8* buffer) {u8 Response;u16 i;u16 retry=0;//写命令 send write commandResponse =SD_MMC_Send_Command(CMD_WRITE_SINGLE_BLOCK, sector<<9);if(Response != 0x00)return Response;SD_MMC_SPI_SELECT();SD_MMC_ReadWrite_Byte(0xff);SD_MMC_ReadWrite_Byte(0xff);SD_MMC_ReadWrite_Byte(0xff);//发开始符 start byte 0xfeSD_MMC_ReadWrite_Byte(0xfe);//送512字节数据 send 512 bytes datafor(i=0; i<512; i++){SD_MMC_ReadWrite_Byte(*buffer++);}SD_MMC_ReadWrite_Byte(0xff); //dummy crc SD_MMC_ReadWrite_Byte(0xff); //dummy crcResponse = SD_MMC_ReadWrite_Byte(0xff);//等待是否成功 judge if it successfulif( (Response&0x1f) != 0x05){SD_MMC_SPI_DESELECT();return Response;}//等待操作完 wait no busywhile(SD_MMC_ReadWrite_Byte(0xff) != 0x00) {if(retry++ > 0xfffe){SD_MMC_SPI_DESELECT();return 1;}}SD_MMC_SPI_DESELECT();SD_MMC_ReadWrite_Byte(0xff);// extra 8 CLKreturn 0;}if( SD_MMC_SPI_Init() ==1)printf(" _SD_MMC Initialization ERROR\r\n"); else{printf(" _SD_MMC Initialization OK\r\n"); //memset(buffer,0,512); //读取一个扇区的内容这里读的是0扇区SD_MMC_Read_Single_Block( 0 , buffer );Uart1_PutString( buffer , 512 );}。

(整理)stm32Fatfs读写SD卡.

(整理)stm32Fatfs读写SD卡.

stm32 Fatfs 读写SD卡读写SD是嵌入式系统中一个比较基础的功能,在很多应用中都可以用得上SD 卡。

折腾了几天,总算移植成功了最新版Fatfs(Fatfs R0.09),成功读写SD卡下文件。

FatFs (/fsw/ff/00index_e.html)是一个通用的文件系统模块,用于在小型嵌入式系统中实现FAT文件系统。

FatFs 的编写遵循ANSI C,因此不依赖于硬件平台。

它可以嵌入到便宜的微控制器中,如8051, PIC, AVR, SH, Z80, H8, ARM 等等,不需要做任何修改。

1. SD卡/TF卡硬件接口SD卡有两种操作接口,SDIO和SPI。

使用SDIO口的速度比较快,SPI的速度比较慢。

SD卡引脚描述如下: SD卡SPI接法如下:我使用的是正点原子的开发板,所以采用的是SPI接口的模式。

TF卡SDIO 模式和SPI模式引脚定义:可以发现Micro SD卡只有8个引脚是因为比SD卡少了一个Vss。

使用TF转SD的卡套套在Micro SD卡上,这样一来大小就和SD卡一样大,这时候卡套上的9个引脚就和SD卡一样了,你可以完全当做SD卡来操作。

2. SD卡底层驱动SD卡的操作比较复杂,需要多看看一些文档。

这里附上SD底层驱动代码,代码说明详见注释Sd卡SPi操作底层代码: sdcard.c sdcard.h3. Fatfs 移植FatFs 软件包中相关文件:ffconf.h FatFs 模块配置文件ff.h FatFs 和应用模块公用的包含文件ff.c FatFs 模块diskio.h FatFs and disk I/O 模块公用的包含文件integer.h 数据类型定义option 可选的外部功能diskio.c FatFs 与disk I/O 模块接口层文件(不属于FatFs 需要由用户提供)FatFs 配置,文件系统的配置项都在ffconf.h 文件之中:(1) _FS_TINY :这个选项在R0.07 版本之中开始出现,在之前的版本都是以独立的文件出现,现在通过一个宏来修改使用起来更方便;(2) _FS_MINIMIZE、_FS_READONLY、_USE_STRFUNC、_USE_MKFS、_USE_FORWARD 这些宏是用来对文件系统进行裁剪(3) _CODE_PAGE :本选项用于设置语言码的类型(4) _USE_LFN :取值为0~3,主要用于长文件名的支持及缓冲区的动态分配:0:不支持长文件名;1:支持长文件名存储的静态分配,一般是存储在BSS 段;2:支持长文件名存储的动态分配,存储在栈上;3:支持长文件名存储的动态分配,存储在堆上。

基于STM32F407平台实现FATFS读写大容量SD卡的心得

基于STM32F407平台实现FATFS读写大容量SD卡的心得

基于STM32F407平台实现FATFS读写大容量SD卡的心得在基于STM32F407平台实现FATFS读写大容量(128G)SD卡的过程中,我积累了一些心得和经验。

下面我将简要介绍一下这些经验。

首先,在使用FATFS文件系统之前,我们需要确保已经正确初始化了SD卡的硬件和配置。

这包括对GPIO、SPI或SDIO等外设进行初始化,并设置正确的时钟源和参数。

对于不同的硬件配置,可能会有所不同,因此需要仔细查看STM32F407的相关文档和资料。

其次,在FATFS文件系统的使用中,我们需要了解和掌握以下几个核心概念和操作:1. 初始化文件系统和 Mount 卷标:在开始进行 SD 卡的读写之前,我们需要使用 f_mount 函数初始化文件系统,并使用 f_mount 函数挂载指定的卷标。

卷标可以是 0 到 9 之间的一个整数,用于表示 SD 卡上的不同分区或逻辑盘符。

2. 打开文件和读写操作:在进行文件读写之前,我们需要使用f_open 函数打开指定的文件,并返回一个文件指针。

然后可以使用f_read 和 f_write 函数进行读写操作。

读操作可以使用 f_read 函数读取指定长度的数据到缓冲区中,写操作可以使用 f_write 函数从缓冲区中写入指定长度的数据到文件中。

对于大容量的SD卡,我们可能需要提前进行一些准备工作,以确保能够正确读写数据:1. 使用 f_mkfs 函数进行格式化:在首次使用 SD 卡之前,我们可能需要对其进行格式化。

可以使用 f_mkfs 函数来完成格式化操作,指定分区号和扇区大小等参数。

2.适当分割文件:为了提高读写性能和避免内存溢出,我们可以将大的文件分割为多个小文件进行读写。

这可以通过调整缓冲区大小和每次读取或写入的数据长度来实现。

3.合理规划缓冲区内存:在进行SD卡读写时,我们需要使用一些缓冲区来暂存读取或写入的数据。

在选择缓冲区大小时,需要考虑到STM32F407的内存限制和其他功能的内存占用。

stm32学习心得体会

stm32学习心得体会

stm32学习⼼得体会 stm32作为现在嵌⼊式物联⽹单⽚机⾏业中经常要⽤多的技术,相信⼤家都有所接触,今天这篇就给⼤家详细的分析下有关于stm32的出⼝,还不是很清楚的朋友要注意看看了哦,在最后还会为⼤家分享有些关于stm32的视频资料便于学习参考。

什么是串⼝ UART : Universal Asynchronous Receiver/Transmitter 通⽤异步收发器 USART : Universal Synchronous Asynchronous Receiver/Transmitter 通⽤同步/异步收发器 ⼀种是常⽤也是最简单的串⾏数据传输协议。

数据线只需要两根就可以实现全双⼯。

Tx: 发送数据线 Rx: 接收数据线 A B TX -----------> Rx Rx <------------Tx 全双⼯: 两个设备可以同时发送和接收 串⾏数据: 发送只⼀根线,⼀次只能发送⼀bit. ⼀bit接着⼀bit发送和接收。

模块通信: 上位机 下位机 通信⼀般需要两个设备,我们把这两个设备,⼈为叫做上位机, 下位机。

上位机: 把处理性能强的机⼦,上位机。

数据⼤部分处理都在上位机完成。

下位机: 把数据采集的终端,处理性能单⼀的机⼦,下位机。

串⼝只有⼀根发送数据线,假如 A要发送⼀个字符数据 10101010 给B A -------- --------- -------- ------- ... ⾼电平周期是多长?即使是不发送数据Tx线上也有⼀个电平状态,接收⽅ 它怎么知道你是在发送呢?.... UART数据如何传输? UART protocol 串⼝协议。

串⼝发送和接收数据是以帧为单位. Frame 1帧(Frame)= 1 start bit(起始位) + 5-9bits数据位 + 0/1bit 校验位 + stop bits(0.5, 1,1,5,2) 起始位: ⼀个周期的低电平 数据位: 5-9bits数据位,具体是多少bits,需要双⽅协商。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

由于自己也在使用SD卡,使用的过程中也遇到了一些问题,下面是在EDN论坛上zxb1717高手的经验,希望可以帮助大家
调试关键点:
1. 上电时要延时足够长的时间给SD卡一个准备过程,在我的程序里是5秒,根据不同的卡设置不同的延时时间。

SD卡初始化第一步在发送CMD命令之前,在片选有效的情况下首先要发送至少74个时钟,否则将有可能出现SD卡不能初始化的问题。

2. SD卡发送复位命令CMD0后,要发送版本查询命令CMD8,返回状态一般分两种,若返回0x01表示此SD卡接受CMD8,也就是说此SD卡支持版本2;若返回0x05则表示此SD卡支持版本1。

因为不同版本的SD卡操作要求有不一样的地方,所以务必查询SD卡的版本号,否则也会出现SD卡无法正常工作的问题。

3. 理论上要求发送CMD58获得SD卡电压参数,但实际过程中由于事先都知道了SD卡的工作电压,因此可省略这一步简化程序。

协议书上也建议尽量不要用这个命令。

4. SD卡读写超时时间要按照协议说明书书上的给定值(读超时:100ms;写超时:250ms),这个值要在程序中准确计算出来,否则将会出现不能正常读写数据的问题。

我自己定义了一个计算公式:超时时间=(8/clk)*arg。

5. 2GB以内的SD卡(标准卡)和2GB以上的SD卡(大容量卡)在地址访问形式上不同,这一点尤其要注意,否则将会出现无法读写数据的问题。

如标准卡在读写操作时,对读或写命令令牌当中的地址域符初值0x10,表示对第16个字节以后的地址单元进行操作(前提是此SD卡支持偏移读写操作),而对大容量卡读或写命令令牌当中的地址域符初值0x10时,则表示对第16块进行读写操作,而且大容量卡只支持块读写操作,块大小固定为512字节,对其进行字节操作将会出错。

6. 对某一块要进行写操作时最好先执行擦出命令,这样写入的速度就能大大提高。

进行擦除操作时不管是标准卡还是大容量卡都按块操作执行,也就是一次擦除至少512字节。

7. 对标准卡进行字节操作时,起始和终止必须在一个物理扇区内,否则将不能进行读写操作。

实际操作过程中建议用块操作以提高效率。

不管是标准卡还是大容量卡一个读写命令只能对一个块进行操作,不允许跨物理层地址操作。

8. 在写数据块前要先写入若干个dummy data字节,写完一个块数据时,主机要监测MISO数据线,如果从机处于忙状态这根数据线会保持低电平,这样主机就可以根据这根数据线的状态以决定是否发送下一个命令,在从机没有释放MISO数据线之前,主机绝对不能执行其他命令,否则将会导致写入的数据出错,而且从机也不会响应主机的命令。

9. 在SPI模式下,CRC校验是被忽略的,但依然要求主从机发送CRC码,只是数值可以是任意值,一般主机的CRC码通常设为0x00或0xFF。

读多块操作和写多块操作的传输停止形式不一样,读多块操作时用用命令CMD12终止传输,而写多块操作时用Stop Tran Token(停止传输令牌,值为0xFD)终止传输。

相关文档
最新文档