简述

花了较长的时间,来弄读写储存卡(大部分教程讲的比较全但是不是很容易懂),这里希望我的代码经验能够帮助到你。

操作分析及实现

0.整个流程

1、上电以后储存卡的初始化

2、如何进行读写

实现

1.上电以后储存卡的初始化

上电给MicroSD卡至少74个时钟信号发送CDM0 (x041)复位发送CMD1 让MicroSD卡进入SPI模式

2.如何进行读写

这里主要对1,3进行详细的讨论你需要知道的是spi通信是怎样进行的就可以完成以上连个任务了

3.下面是具体的过程

//首先看一下我们的函数char SD_Init(void); //初始化函数char WriteSectorToMicroSD(long addr,char *buff);//写一个扇区 512bitchar ReadSectorFromMicroSD(long sector,char *buffer);// 读一个扇区 

下面是主函数里的的部分

//定义读入缓冲区extern char MicroSDDataBuff[512];void MicroSDTest(){//这是在内存卡初始化以后的测试进行读写如果不成功还是从读写序列号开始吧 //WriteSectorToMicroSD(2,"Hello I here did you find me!!!"); delay_ms(200); ReadSectorFromMicroSD(2,MicroSDDataBuff); //printf("MicroSD read is:%s!!!!",MicroSDDataBuff);}int main(){char arr[100]={0},key=-1;int x=0,y=0;SPI2_Init();uart_init(115200);delay_init();SD_Init();MicroSDTest();printf("Read:%s",MicroSDDataBuff);while(1);}
//下面是MicroSD的初始化及读写函数#define MicroSD_CS_SET GPIO_SetBits(GPIOB,GPIO_Pin_0)#define MicroSD_CS_RESET GPIO_ResetBits(GPIOB,GPIO_Pin_0)char MicroSDDataBuff[512]={0};//一个扇区的大小char SentCommandToMicroSD(char cmd,int data,char crc){char result=0,times=0;MicroSD_CS_SET;//禁止SD卡片选 同步时钟SPI1_ReadWriteByte(0xff); MicroSD_CS_RESET;//开始传输SPI1_ReadWriteByte(cmd);for(times=0;times<4;times++) {  SPI1_ReadWriteByte((data>>24)&0xff); data<<=8; } SPI1_ReadWriteByte(crc);SPI1_ReadWriteByte(0xff); //八个时钟 times=0;do{ //读取后8位 result = SPI1_ReadWriteByte(0xFF); times++;}while((result==0xff)&&(times<200));return result;}//初始化化不是很稳定也就是说明传输数据可能不是很稳定char SD_Init(void){char i,temp=0;//char CMD[] = {0x40,0x00,0x00,0x00,0x00,0x95};int retry=0;GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );//PORTB时钟使能 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //PB0GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB0GPIO_SetBits(GPIOB,GPIO_Pin_0);//初始化SPI1SPI1_Init();MicroSD_CS_SET;//发送至少74个时钟信号,数据顺便填写for (i=0;i<0x2f;i++){SPI1_ReadWriteByte(0xff);} //为了能够成功写入CMD0,在这里写200次do { temp=SentCommandToMicroSD(0x40,0,0x95); retry++; if(retry>800){ //超过200次 //CMD0 Error!return(INIT_CMD0_ERROR); printf("Init MicroSD CMD0 Error!!!Back:%d",temp);return 0;} }while(temp!=0x01); //回应01h,停止写入printf("Reset MicroSD successfully!!!times:%d",retry);//发送CMD1到SD卡 retry=0; do{//为了能成功写入CMD1,写100次 temp=SentCommandToMicroSD(0x41,0,0xff);retry++; if(retry>800) { //超过100次printf("Init 1MicroSD CMD1 Error!!!Back:%d",temp);return 0;}}while(temp!=0x00);//回应00h停止写入 MicroSD_CS_SET; //片选无效printf("Init MicroSD sent CMD1 successfully!!!times:%d",retry);//更换更快的SPI速率SPI1_SetSpeed(SPI_BaudRatePrescaler_4);return 0;}char WriteSectorToMicroSD(long addr,char *buff) {  int tmp,retry;  unsigned int i;  addr = addr << 9; //addr = addr * 512  //写命令24到SD卡中去  retry=0;  do{ //为了可靠写入,写100次  tmp=SentCommandToMicroSD(0x58,addr,0xff);  retry++;  if(retry>800)  { printf("Write CMD58 Error!!!"); return 1; //send commamd Error! }  }  while(tmp!=0);//在写之前先产生100个时钟信号  for (i=0;i<100;i++)  {  SPI1_ReadWriteByte(0xff);  } //写入开始字节  SPI1_ReadWriteByte(0xfe);  //现在可以写入512个字节  for (i=0;i<512;i++)  {  SPI1_ReadWriteByte(*buff); buff++; } //CRC-Byte spi模式只需要在前两个命令发送,后面的crc自动不校验  SPI1_ReadWriteByte(0xFF); //Dummy CRC  SPI1_ReadWriteByte(0xFF); //CRC Code tmp=SPI1_ReadWriteByte(0xff); // read response  if((tmp & 0x1F)!=0x05) // 写入的512个字节是未被接受  {  MicroSD_CS_SET; printf("Write data didn't accept by MicroSD"); return 1; //Error!  }  //等到SD卡不忙为止  //因为数据被接受后,SD卡在向储存阵列中编程数据  while (SPI1_ReadWriteByte(0xff)!=0xff); //禁止SD卡 写入成功 MicroSD_CS_SET; return 0; }char ReadSectorFromMicroSD(long sector,char *buffer) {int retry; //命令16  int times=0;//unsigned char CMD[] = {0x51,0x00,0x00,0x00,0x00,0xFF};  unsigned char temp;  //地址变换 由逻辑块地址转为字节地址  sector = sector << 9; //sector = sector * 512//将命令16写入SD卡 retry=0; do{ //为了保证写入命令 一共写100次  temp=SentCommandToMicroSD(0x51,sector,0xff);  retry++;  if(retry>800)  {  printf("Read sector from MicroSD is failed!!"); return 1; //block write Error!  }  }  while(temp!=0);  //Read Start Byte form MMC/SD-Card (FEh/Start Byte)  //Now data is ready,you can read it out.  while (SPI1_ReadWriteByte(0xff) != 0xfe); for(times=0;times<512;times++) {  MicroSDDataBuff[times]=SPI1_ReadWriteByte(0xff); } //禁止SD卡 读出完成 MicroSD_CS_SET; return 0;} 

驱动MicroSD卡如果像我用的stm32f103c8t6的核心板的话,可能还会好一点。网上的资料由一点乱,如果想要具体的keil工程的话留下联系方式我会发给你的。

另外呢后面的工程会用到这里的MicroSD的驱动,然后架设文件系统,所以这里还是关键的,还有一些坑需要深挖。

termux获取sd卡读写权限_stm32 SPI读写储存卡(MicroSD TF卡)相关推荐

  1. termux获取sd卡读写权限_我牵手金士顿小蓝TF卡成功上岛啦

    春风吹,战鼓擂,我中奖了我怕sei~啦啦啦,激动的心情难以言表,今天来分享一下我在一个Switch活动中获奖的金士顿的Canvas Go!Plus小蓝128G TF卡. 其实...我是盯着那个特等奖N ...

  2. stm32 SPI读写储存卡(MicroSD TF卡)

    stm32 SPI读写储存卡(MicroSD TF卡) 简述 操作分析及实现 0.整个流程 1.上电以后储存卡的初始化 2.如何进行读写 3.下面是具体的过程 博客原址:http://www.code ...

  3. termux获取sd卡读写权限_TF卡戴套客串SD卡真的靠谱吗?用数据说话

    大家好,我是黄昏百分百,今天为大家带来一次硬核测试,看一看TF卡搭配卡套,能否当作SD卡使用,卡套是否会降低其读写性能.包括我在内,很多朋友都对这个问题感兴趣,但是貌似全网没有几个人做过类似的测试,所 ...

  4. Android有文件读写权限,无法读写文件 open failed: EACCES (Permission denied) 获取设备唯一不变id 所有文件读写权限按钮无法打开

    最近有个需求,要获取设备唯一id,Android一直没有什么完善的方案获取设备唯一不变的id,我就结合了几种方案组成了一下: 1. 首先获取IMEI; IMEI获取失败后 2. 获取SN序列号,序列号 ...

  5. 阿里云使用js 实现OSS图片上传、获取OSS图片列表、获取图片外网访问地址(读写权限私有、读写权限公共);...

    详情请参考:https://help.aliyun.com/document_detail/32069.html?spm=a2c4g.11186623.6.763.ZgC59a 或者https://h ...

  6. termux获取sd卡读写权限_原来是用错了读卡器,雷克沙lexar 1667X 真实读写性能测试...

    上一篇文章结合泥坑D3300套装老设备对雷克沙新版1667x 进行兼容性部分的测试,可以正常使用,而且在拍摄性能上有了很大的提升.当然雷克沙新版1667x 主要还是用来搭配SONY A6100来进行视 ...

  7. termux获取sd卡读写权限_索尼发布“世界最快”USB-C Hub及TOUGH SF-M系列SD卡

    7月14日消息,据Cool3c报道,索尼宣布推出新的TOUGH SF-M系列SD卡及USB-C扩展坞MRW-S3.这款MRW-S3号称"世界最快"的UHS-II SD和microS ...

  8. termux获取sd卡读写权限_重回SD市场 三星128GB/256GB PRO Plus存储卡评测

    当前数码相机的性能越来越强,视频/照片双修的拍摄能力也逐步得到提高,对于大多数人来说,大容量的存储卡需求也在逐渐增大,一款好的SD卡不但能够进行快速的视频.照片捕捉,而且在抗磁.耐高温等一些特定环境的 ...

  9. SD卡硬件规格 SD/miniSD/microSD(TF卡)

    SD miniSD microSD 尺寸 卡片种类 SD, SDHC, SDXC SD, SDHC SD, SDHC, SDXC 面积 768 mm2 (100) 430 mm2 165 mm2 卡片 ...

最新文章

  1. 建站常用13种PHP开源CMS比较
  2. Xamarin图表开发基础教程(2)OxyPlot框架
  3. U3D打apk包的常见错误
  4. Linux查看版本当前操作系统内核信息
  5. 在centos 7 下安装图形界面
  6. 在同个工程中使用 Swift 和 Objective-C(Swift 2.0更新)-b
  7. java怎么生成class文件_怎样将java的class文件生成jar包
  8. 填料吸收塔,填料教学实训,填料吸收实验系列QY-HGYL
  9. 五分钟学Java:一篇文章带你搞懂spring全家桶套餐
  10. 一个Vue+Canvas的酷炫后台管理
  11. [E::hts_idx_push] NO_COOR reads not in a single block at the end 10 -1
  12. 推荐一款中文转拼音的前端插件-pinyin
  13. 利用for语句,编程输出如下图形:* *** *****
  14. Bluetooth Baseband介绍
  15. [经济学原理|政治部分]剩余价值理论
  16. 矩阵乘法的并行化算法讨论
  17. 动易的默认数据库、用户和密码、认证码大全还有找后台方法
  18. playwright用Firefox设置代理
  19. Nessus: 漏洞扫描器-网络取证工具
  20. 7.1 求解矩阵的逆

热门文章

  1. Python中使用Tkinter 快速布局编写桌面GUI程序
  2. excel乘法公式怎么输入_电气计算太慢?62套自动计算EXCEL表格,一键下载秒出结果...
  3. OpenCV SIFT源码讲解——构建高斯金字塔
  4. js字符串截取函数的三种方式(slice()、substring()、substr())
  5. 对象的创建、发布、逸出
  6. nat123内网映射到外网
  7. #UI教程#3分钟打造金色玫瑰
  8. 使用最大后验概率学习正态分布的参数
  9. 撤销 图层调整 合并图层 图层选择 图层锁定(ps尚硅谷学习)
  10. [二造] 浙江土建实务案例题(索赔、结算、偏差分析)