基于STM32采用CS创世 SD NAND(贴片SD卡)完成FATFS文件系统移植与测试_stm32 i2c1

2023-03-28 18:16:15

 

1.基于stm32f4

原标题:基于STM32采用CS创世 SD NAND(贴片SD卡)完成FATFS文件系统移植与测试一、前言在STM32项目开发中,经常会用到存储芯片存储数据 比如:关机时保存机器运行过程中的状态数据,上电再从存储芯片里读取数据恢复;在存储芯片里也会存放很多资源文件。

2.基于stm32的

比如,开机音乐,界面上的菜单图标,字库文件,方便设备开机加载为了让单片机更加方便的读写这些资源文件,通常都会加文件系统,如果没有文件系统,直接读取写扇区的方式,对数据不好管理 这篇文章就手把手教大家,在STM32上完成FATFS文件系统的移植;主控芯片采用STM32F103ZET6, 存储芯片我这里采用(雷龙) CS创世 SD NAND 。

3.基于stm32f103

SD NAND 简单来说就是贴片式SD卡,使用起来与普通的SD卡一样,简单的区别就是:比TF卡稳定,比eMMC便宜 下面章节里会详细介绍下 CS创世 SD NAND下面是CS创世 SD NAND 与STM32开发的板的接线实物图:

4.基于stm32f103c8t6

这是读写扇区测试的结果:二、SD NAND 介绍我当前使用的SD NAND型号是,CSNP32GCR01-AOW,容量是4GB下面是通过编写STM32代码读取的存储信息:Card Type:SDHC V2.0。

5.基于stm32的简单项目

Card ManufacturerID:102Card RCA:5000Card Capacity:3696 MBCard BlockSize:512芯片的详细参数如下:【1】不用写驱动程序自带坏块管理

6.基于stm32的c语言

【2】尺寸小巧,简单易用,兼容性强,稳定可靠,固件可定制,LGA-8封装【3】标准SDIO接口,兼容SPI,兼容拔插式TF卡/SD卡,可替代普通TF卡/SD卡【4】尺寸6.2x8mm,直接贴片,不占空间

7.基于stm32的i2c程序

【5】内置平均读写算法,通过1万次随机掉电测试【6】耐高低温,机贴手贴都非常方便【7】速度级别Class10(读取速度23.5MB/S写入速度12.3MB/S)【8】支持标准的SD 2.0协议,用户可以直接移植标准驱动代码,省去了驱动代码编程环节。

8.基于stm32课设

支持TF卡启动的SOC都可以用SD NAND【9】比TF卡稳定,比eMMC便宜**下面是芯片的实物图: ** 这是官网申请的样品,焊接了转接板,可以直接插在SD卡卡槽上测试 最终选型之后,设计PCB板时,设计接口,直接贴片上去使用,非常稳定,抖动也不会导致,外置卡TF卡这种容易松动的问题。

9.基于stm32的c语言程序设计详解

这是雷龙的官网: http://www.longsto.com/product/35.html

10.基于stm32的设计

三、编写SD NAND驱动代码SD NAND 的驱动代码与正常的SD卡协议是一样的,支持标准的SD 2.0协议,下面我就直接贴出写好的驱动代码包括了模拟SPI,硬件SPI,SDIO等3种方式,完成对SD NAND 的读写。

我当前使用的主控板子是STM32F103ZET6,如果你使用的板子不是这一款,可能还是其他的CPU也没关系;我这里直接贴出了SPI模拟时序的驱动代码,可以直接移植到任何单片机上使用,代码拷贝过去也只需要修改GPIO口即可,非常方便。

3.1 SPI模拟时序驱动方式(1)整体工程代码这是当前工程的截图: 代码采用寄存器风格编写,非常简洁。当前工程完成SD NAND卡初始化,扇区的读写,测试芯片基本的使用情况。

(2) sd.c#include "sdcard.h" static u8 SD_Type=0; //存放SD卡的类型/*函数功能:SD卡底层接口,通过SPI时序向SD卡读写一个字节函数参数:data是要写入的数据

返 回 值:读到的数据*/u8 SDCardReadWriteOneByte(u8 DataTx){ u8 i;u8 data=0;for(i=0;i<8;i++){SDCARD_SCK=0;if(DataTx&0x80)SDCARD_MOSI=1;

else SDCARD_MOSI=0;SDCARD_SCK=1;DataTx<<=1;data<<=1;if(SDCARD_MISO)data|=0x01;}return data;}//4种: 边沿两种、电平是两种

/*函数功能:底层SD卡接口初始化本程序SPI接口如下:PC11 片选 SDCardCSPC12 时钟 SDCardSCLKPD2 输出 SPI_MOSI--主机输出从机输入PC8 输入 SPI_MISO--主机输入从机输出

*/void SDCardSpiInit(void){/*1. 开启时钟*/RCC->APB2ENR|=1

GPIOC->CRH&=0xFFF00FF0;GPIOC->CRH|=0x00033008;GPIOD->CRL&=0xFFFFF0FF;GPIOD->CRL|=0x00000300;/*3. 上拉*/

GPIOC->ODR|=1

{SDCARD_CS=1;SDCardReadWriteOneByte(0xff);//提供额外的8个时钟}/*函数 功 能:选择sd卡,并且等待卡准备OK函数返回值:0,成功;1,失败;*/void SDCardSelectCS(void)

{SDCARD_CS=0;SDCardWaitBusy();//等待成功}/*函数 功 能:等待卡准备好函数返回值:0,准备好了;其他,错误代码*/void SDCardWaitBusy(void){while(SDCardReadWriteOneByte(0XFF)!=0XFF){}

}/*函数功能:等待SD卡回应函数参数:Response:要得到的回应值返 回 值:0,成功得到了该回应值其他,得到回应值失败*/u8 SDCardGetAck(u8 Response){u16 Count=0xFFFF;//等待次数

while((SDCardReadWriteOneByte(0XFF)!=Response)&&Count)Count--;//等待得到准确的回应 if(Count==0)return SDCard_RESPONSE_FAILURE;//得到回应失败

else return SDCard_RESPONSE_NO_ERROR;//正确回应}/*函数功能:从sd卡读取一个数据包的内容函数参数:buf:数据缓存区len:要读取的数据长度.返回值:0,成功;其他,失败;

*/u8 SDCardRecvData(u8*buf,u16 len){ if(SDCardGetAck(0xFE))return 1;//等待SD卡发回数据起始令牌0xFEwhile(len--)//开始接收数据

{*buf=SDCardReadWriteOneByte(0xFF);buf++;}//下面是2个伪CRC(dummy CRC)SDCardReadWriteOneByte(0xFF);SDCardReadWriteOneByte(0xFF);

return 0;//读取成功}/*函数功能:向sd卡写入一个数据包的内容 512字节函数参数:buf 数据缓存区cmd 指令返 回 值:0表示成功;其他值表示失败;*/u8 SDCardSendData(u8*buf,u8 cmd)

{ u16 t; SDCardWaitBusy(); //等待忙状态SDCardReadWriteOneByte(cmd);if(cmd!=0XFD)//不是结束指令{for(t=0;t<512;t++)SDCardReadWriteOneByte(buf[t]);//提高速度,减少函数传参时间

SDCardReadWriteOneByte(0xFF); //忽略crcSDCardReadWriteOneByte(0xFF);t=SDCardReadWriteOneByte(0xFF); //接收响应

if((t&0x1F)!=0x05)return 2; //响应错误 } return 0;//写入成功}/*函数功能:向SD卡发送一个命令函数参数:u8 cmd 命令 u32 arg 命令参数u8 crc crc校验值

返回值:SD卡返回的响应*/ u8 SendSDCardCmd(u8 cmd, u32 arg, u8 crc){u8 r1; SDCardCancelCS(); //取消上次片选SDCardSelectCS(); //选中SD卡

//发送数据SDCardReadWriteOneByte(cmd | 0x40);//分别写入命令SDCardReadWriteOneByte(arg >> 24);SDCardReadWriteOneByte(arg >> 16);

SDCardReadWriteOneByte(arg >> 8);SDCardReadWriteOneByte(arg); SDCardReadWriteOneByte(crc); if(cmd==SDCard_CMD12)SDCardReadWriteOneByte(0xff);//Skip a stuff byte when stop reading

do{r1=SDCardReadWriteOneByte(0xFF);}while(r1&0x80); //等待响应,或超时退出return r1; //返回状态值}/*函数功能:获取SD卡的CID信息,包括制造商信息

函数参数:u8 *cid_data(存放CID的内存,至少16Byte) 返 回 值:0:成功,1:错误 */u8 GetSDCardCISDCardOutnfo(u8 *cid_data){u8 r1;

//发SDCard_CMD10命令,读CIDr1=SendSDCardCmd(SDCard_CMD10,0,0x01);if(r1==0x00){r1=SDCardRecvData(cid_data,16);//接收16个字节的数据

}SDCardCancelCS();//取消片选if(r1)return 1;else return 0;} /*函数说明:获取SD卡的CSD信息,包括容量和速度信息函数参数:u8 *cid_data(存放CID的内存,至少16Byte)

返 回 值:0:成功,1:错误 */u8 GetSDCardCSSDCardOutnfo(u8 *csd_data){u8 r1; r1=SendSDCardCmd(SDCard_CMD9,0,0x01); //发SDCard_CMD9命令,读CSD

if(r1==0){r1=SDCardRecvData(csd_data, 16);//接收16个字节的数据 }SDCardCancelCS();//取消片选if(r1)return 1;else return 0;

} /*函数功能:获取SD卡的总扇区数(扇区数) 返 回 值:0表示容量检测出错,其他值表示SD卡的容量(扇区数/512字节)说 明:每扇区的字节数必为512字节,如果不是512字节,则初始化不能通过.

*/u32 GetSDCardSectorCount(void){u8 csd[16];u32 Capacity; u16 csize; if(GetSDCardCSSDCardOutnfo(csd)!=0) return 0; //取CSD信息,如果期间出错,返回0

if((csd[0]&0xC0)==0x40) //SDHC卡,按照下面方式计算{ csize = csd[9] + ((u16)csd[8] << 8) + 1;Capacity = (u32)csize << 10;//得到扇区数

}return Capacity;}/*函数功能: 初始化SD卡返 回 值: 非0表示初始化失败!*/u8 SDCardDeviceInit(void){u8 r1; // 存放SD卡的返回值u8 buf[4];

u16 i;SDCardSpiInit();//初始化底层IO口for(i=0;i<10;i++)SDCardReadWriteOneByte(0xFF); //发送最少74个脉冲do{r1=SendSDCardCmd(SDCard_CMD0,0,0x95);//进入IDLE状态 闲置

}while(r1!=0X01);SD_Type=0; //默认无卡if(r1==0X01){if(SendSDCardCmd(SDCard_CMD8,0x1AA,0x87)==1) //SD V2.0

{for(i=0;i<4;i++)buf[i]=SDCardReadWriteOneByte(0XFF);if(buf[2]==0X01&&buf[3]==0XAA) //卡是否支持2.7~3.6V{do

{SendSDCardCmd(SDCard_CMD55,0,0X01); //发送SDCard_CMD55r1=SendSDCardCmd(SDCard_CMD41,0x40000000,0X01);//发送SDCard_CMD41

}while(r1);if(SendSDCardCmd(SDCard_CMD58,0,0X01)==0)//鉴别SD2.0卡版本开始{for(i=0;i<4;i++)buf[i]=SDCardReadWriteOneByte(0XFF);//得到OCR值

if(buf[0]&0x40)SD_Type=SDCard_TYPE_V2HC; //检查CCSelse SD_Type=SDCard_TYPE_V2; }}}}printf("SD_Type=0x%X\r\n",SD_Type);

SDCardCancelCS(); //取消片选if(SD_Type)return 0; //初始化成功返回0else if(r1)return r1; //返回值错误值 return 0xaa; //其他错误

}/*函数功能:读SD卡函数参数:buf:数据缓存区sector:扇区cnt:扇区数返回值:0,ok;其他,失败.说 明:SD卡一个扇区大小512字节*/u8 SDCardReadData(u8*buf,u32 sector,u32 cnt)

{u8 r1;if(SD_Type!=SDCard_TYPE_V2HC)sector<<=9;//转换为字节地址if(cnt==1){r1=SendSDCardCmd(SDCard_CMD17,sector,0X01);//读命令

if(r1==0) //指令发送成功{r1=SDCardRecvData(buf,512); //接收512个字节 }}else{r1=SendSDCardCmd(SDCard_CMD18,sector,0X01);//连续读命令

do{r1=SDCardRecvData(buf,512);//接收512个字节 buf+=512; }while(--cnt && r1==0); SendSDCardCmd(SDCard_CMD12,0,0X01); //发送停止命令

} SDCardCancelCS();//取消片选return r1;//}/*函数功能:向SD卡写数据函数参数:buf:数据缓存区sector:起始扇区cnt:扇区数返回值:0,ok;其他,失败.说 明:

SD卡一个扇区大小512字节*/u8 SDCardWriteData(u8*buf,u32 sector,u32 cnt){u8 r1;if(SD_Type!=SDCard_TYPE_V2HC)sector *= 512;//转换为字节地址

if(cnt==1){r1=SendSDCardCmd(SDCard_CMD24,sector,0X01);//读命令if(r1==0)//指令发送成功{r1=SDCardSendData(buf,0xFE);//写512个字节

}}else{if(SD_Type!=SDCard_TYPE_MMC){SendSDCardCmd(SDCard_CMD55,0,0X01); SendSDCardCmd(SDCard_CMD23,cnt,0X01);//发送指令

}r1=SendSDCardCmd(SDCard_CMD25,sector,0X01);//连续读命令if(r1==0){do{r1=SDCardSendData(buf,0xFC);//接收512个字节

buf+=512; }while(--cnt && r1==0);r1=SDCardSendData(0,0xFD);//接收512个字节 }} SDCardCancelCS();//取消片选return r1;//

} (3) sd.h#ifndef SD_H#define SD_H_ #include "stm32f10x.h"#include "led.h"#include "usart.h"/*----------------------------------------------

本程序SPI接口如下:PC11 片选 SDCardCSPC12 时钟 SDCardSCLKPD2 输出 SPI_MOSI--主机输出从机输入PC8 输入 SPI_MISO--主机输入从机输出------------------------------------------------*/

#define SDCARD_CS PCout(11)#define SDCARD_SCK PCout(12)#define SDCARD_MOSI PDout(2)#define SDCARD_MISO PCin(8)

// SD卡类型定义 #define SDCard_TYPE_ERR 0X00 //卡类型错误#define SDCard_TYPE_MMC 0X01 //MMC卡#define SDCard_TYPE_V1 0X02

#define SDCard_TYPE_V2 0X04#define SDCard_TYPE_V2HC 0X06 // SD卡指令表 #define SDCard_CMD0 0 //卡复位#define SDCard_CMD1 1

#define SDCard_CMD8 8 //命令8 ,SEND_IF_COND#define SDCard_CMD9 9 //命令9 ,读CSD数据#define SDCard_CMD10 10 //命令10,读CID数据

#define SDCard_CMD12 12 //命令12,停止数据传输#define SDCard_CMD13 16 //命令16,设置扇区大小 应返回0x00#define SDCard_CMD17 17 //命令17,读扇区

#define SDCard_CMD18 18 //命令18,读Multi 扇区#define SDCard_CMD23 23 //命令23,设置多扇区写入前预先擦除N个block#define SDCard_CMD24 24 //命令24,写扇区

#define SDCard_CMD25 25 //命令25,写多个扇区#define SDCard_CMD41 41 //命令41,应返回0x00#define SDCard_CMD55 55 //命令55,应返回0x01

#define SDCard_CMD58 58 //命令58,读OCR信息#define SDCard_CMD59 59 //命令59,使能/禁止CRC,应返回0x00、/*SD卡回应标记字*/#define SDCard_RESPONSE_NO_ERROR 0x00 //正确回应

#define SDCard_SD_IN_IDLE_STATE 0x01 //闲置状态#define SDCard_SD_ERASE_RESET 0x02 //擦除复位#define SDCard_RESPONSE_FAILURE 0xFF //响应失败

//函数声明 u8 SDCardReadWriteOneByte(u8 data); //底层接口,SPI读写字节函数void SDCardWaitBusy(void); //等待SD卡准备u8 SDCardGetAck(u8 Response); //获得应答

u8 SDCardDeviceInit(void); //初始化u8 SDCardReadData(u8*buf,u32 sector,u32 cnt); //读块(扇区)u8 SDCardWriteData(u8*buf,u32 sector,u32 cnt); //写块(扇区)

u32 GetSDCardSectorCount(void); //读扇区数u8 GetSDCardCISDCardOutnfo(u8 *cid_data); //读SD卡CIDu8 GetSDCardCSSDCardOutnfo(u8 *csd_data); //读SD卡CSD

#endif(4)运行效果返回搜狐,查看更多责任编辑:


以上就是关于《基于STM32采用CS创世 SD NAND(贴片SD卡)完成FATFS文件系统移植与测试_stm32 i2c1》的全部内容,本文网址:https://www.7ca.cn/baike/9174.shtml,如对您有帮助可以分享给好友,谢谢。
标签:
声明

排行榜