[RISC-V MCU 应用开发] 二十五、CH32V103应用教程——SD卡测试

[复制链接]
 楼主| RISCVLAR 发表于 2020-12-12 11:40 | 显示全部楼层 |阅读模式
本帖最后由 RISCVLAR 于 2020-12-12 11:39 编辑

CH32V103应用教程——SD卡测试

本章教程将在CH32V103开发板上实现SD卡检测和SD卡容量信息读取。

1、SD卡简介及相关函数介绍
SD存储卡( Secure Digital Memory Card)是一种基于半导体快闪存储器的新一代高速存储设备。SD存储卡的技术是从MMC卡( MultiMedia Card格式上发展而来,在兼容SD存储卡基础上发展了SDIO( SD Input/ Output)卡,此兼容性包括机械,电子,电力,信号和软件,通常将SD、SDIO卡俗称SD存储卡。

SD卡具有高**容量、快速数据传输率、极大的移动灵活性以及很好的安全性,它被广泛地应用于便携式装置上,例如数码相机、平板电脑和多媒体播放器等。根据SD卡容量大小不同,可将SD卡分为以下几类:
0~2G:SD卡;2~32G:SDHC卡;32~2T:SDXC卡;

其中,SD卡协议和SDHC卡版本协议基本兼容,但SDXC卡与SD卡和SDHC卡相差较大,本章主要介绍使用SD卡和SDHC卡。

控制器对SD卡进行读写通信操作一般有两种通信接口可选,一种是SPI接口,另外一种是SDIO接口。 SPI协议驱动SD卡方式相较于SDIO驱动SD卡方式,使用引脚资源少,控制程序相对较为简单,但传输速度不如使用SDIO接口的快。由于CH32V103开发板上SD卡槽与芯片引脚的连接方式为SPI驱动方式,因此本章教程采用SPI协议驱动SD卡方式。
使用SPI方式驱动SD卡需要用到以下几个寄存器:
① CID:卡识别号(Card identification number),用来识别卡的唯一的个体号码;
② CSD:卡的特定数据(Card Specific Data),指卡的操作条件信息;
③ SCR:SD配置寄存器(SD Configuration Register),SD卡特殊性信息;
④ OCR:操作条件寄存器(Operation conditions register)
关于SD卡其他寄存器信息,可参考SD 简易规格文件《 Physical Layer Simplified Specification V2.0》。

关于SD命令格式,固定为48bit,通过命令线(CMD)连续传输,其具体命令格式以及命令解释如下:
图片1.png
起始位和终止位:命令的主体包含在起始位与终止位之间,它们都只包含一个数据位,起始位为0,终止位为1
传输标志:用于区分传输方向,该位为1时表示命令,方向为主机传输到SD卡,该位为0时表示响应,方向为SD卡传输到主机。
命令主体内容包括命令、地址信息/参数和 CRC 校验三个部分。
1.命令号:它固定占用6bit,所以总共有64个命令(代号: CMD0~CMD63),每个命令都有特定的用途,部分命令不适用于SPI总线,或不适用于SD卡操作,只是专门用于MMC卡或者SDI/O卡。
2.地址/参数:每个命令有32bit地址信息/参数用于命令附加内容,例如,广播命令没有地址信息,这32bit用于指定参数,而寻址命令这32bit用于指定目标SD卡的地址,使用SPI总线驱动时,通过片选引脚来选择不同的卡,所以使用这些命令时地址可填充任意值。
3.CRC7校验:长度为7bit的校验位用于验证命令传输内容正确性,如果发生外部干扰导致传输数据个别位状态改变将导致校准失败,也意味着命令传输失败,SD卡不执行命令。使用SPI驱动时,命令中的CRC7校验默认是关闭的,即这CRC7校验位中可以写入任意值而不影响通讯,仅在发送CMD0命令时需要强制带标准的CRC7校验。

SPI模式下有以下几个重要的操作指令:
图片2.png
SD卡R1响应格式如下:
图片3.png
关于SD卡具体信息,可参考《 Physical Layer Simplified Specification V2.0》关于SPI具体配置介绍,可参考CH32V103应用手册以及前面SPI教程介绍。

2硬件设计
本章教程主要进**检测、初始化以及读取SD卡容量大小,需要用到CH32V103开发板TF CARD模块以及一张容量大小不超过32G的SD卡。

3软件设计
本章教程由于使用SPI驱动方式,需要用到部分SPI程序,关于SPI内容在此不再过多介绍,SD卡具体程序如下:
sd.h文件
  1. #ifndef __SD_H_
  2. #define __SD_H_

  3. #include "ch32v10x_conf.h"

  4. // SD卡类型定义
  5. #define SD_TYPE_ERR     0X00
  6. #define SD_TYPE_MMC     0X01
  7. #define SD_TYPE_V1      0X02
  8. #define SD_TYPE_V2      0X04
  9. #define SD_TYPE_V2HC    0X06

  10. // SD卡指令表
  11. #define CMD0    0       //卡复位
  12. #define CMD1    1
  13. #define CMD8    8       //命令8 ,SEND_IF_COND
  14. #define CMD9    9       //命令9 ,读CSD数据
  15. #define CMD10   10      //命令10,读CID数据
  16. #define CMD12   12      //命令12,停止数据传输
  17. #define CMD16   16      //命令16,设置SectorSize 应返回0x00
  18. #define CMD17   17      //命令17,读sector
  19. #define CMD18   18      //命令18,读Multi sector
  20. #define CMD23   23      //命令23,设置多sector写入前预先擦除N个block
  21. #define CMD24   24      //命令24,写sector
  22. #define CMD25   25      //命令25,写Multi sector
  23. #define CMD41   41      //命令41,应返回0x00
  24. #define CMD55   55      //命令55,应返回0x01
  25. #define CMD58   58      //命令58,读OCR信息
  26. #define CMD59   59      //命令59,使能/禁止CRC,应返回0x00

  27. //数据写入回应字意义
  28. #define MSD_DATA_OK                0x05
  29. #define MSD_DATA_CRC_ERROR         0x0B
  30. #define MSD_DATA_WRITE_ERROR       0x0D
  31. #define MSD_DATA_OTHER_ERROR       0xFF

  32. //SD卡回应标记字
  33. #define MSD_RESPONSE_NO_ERROR      0x00
  34. #define MSD_IN_IDLE_STATE          0x01
  35. #define MSD_ERASE_RESET            0x02
  36. #define MSD_ILLEGAL_COMMAND        0x04
  37. #define MSD_COM_CRC_ERROR          0x08
  38. #define MSD_ERASE_SEQUENCE_ERROR   0x10
  39. #define MSD_ADDRESS_ERROR          0x20
  40. #define MSD_PARAMETER_ERROR        0x40
  41. #define MSD_RESPONSE_FAILURE       0xFF

  42. //这部分应根据具体的连线来修改!
  43. //MiniSTM32开发板使用的是PA3作为SD卡的CS脚.
  44. #define SD_CS_H  GPIO_SetBits(GPIOA,GPIO_Pin_3)     //SD卡片选引脚拉高
  45. #define SD_CS_L  GPIO_ResetBits(GPIOA,GPIO_Pin_3)   //SD卡片选引脚拉低

  46. extern u8  SD_Type;         //SD卡的类型
  47. //函数申明区
  48. u8 SD_SPI_ReadWriteByte(u8 data);
  49. u8 SD_Detect(void);                             //检测SD卡是否存在
  50. u8 SD_WaitReady(void);                          //等待SD卡准备
  51. u8 SD_GetResponse(u8 Response);                 //获得相应
  52. u8 SD_Initialize(void);                         //初始化
  53. u8 SD_ReadDisk(u8*buf,u32 sector,u8 cnt);       //读块
  54. u8 SD_WriteDisk(u8*buf,u32 sector,u8 cnt);      //写块
  55. u32 SD_GetSectorCount(void);                    //读扇区数
  56. u8 SD_GetCID(u8 *cid_data);                     //读SD卡CID
  57. u8 SD_GetCSD(u8 *csd_data);                     //读SD卡CSD

  58. #endif
sd.h文件主要包括各种宏定义及函数声明,包括SD卡类型定义、SD卡指令定义等以及函数声明;

sd.c文件

  1. #include "sd.h"
  2. #include "spi.h"

  3. u8  SD_Type=0;//SD卡的类型

  4. //data:要写入的数据
  5. //返回值:读到的数据
  6. u8 SD_SPI_ReadWriteByte(u8 data)
  7. {
  8.     return SPI1_ReadWriteByte(data);
  9. }


  10. u8 SD_Detect(void)
  11. {
  12.   u8 status = 1;

  13.   /* Check GPIO to detect SD */
  14.   if (GPIO_ReadInputData(GPIOA) & GPIO_Pin_8)
  15.   {
  16.     status = 0;
  17.   }
  18.   return status;
  19. }


  20. //SPI硬件层初始化
  21. void SD_SPI_Init(void)
  22. {
  23.     //设置硬件上与SD卡相关联的控制引脚输出
  24.     //禁止其他外设(NRF/W25Q64)对SD卡产生影响
  25.     GPIO_InitTypeDef GPIO_InitStructure;
  26.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE ); //PORTA时钟使能

  27.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  28.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;
  29.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  30.     GPIO_Init(GPIOA, &GPIO_InitStructure);
  31.     GPIO_SetBits(GPIOA,GPIO_Pin_3); //PA3上拉

  32.     SPI1_Init();
  33.     SD_CS_H;
  34. }


  35. //取消选择,释放SPI总线
  36. void SD_DisSelect(void)
  37. {
  38.     SD_CS_H;
  39.     SD_SPI_ReadWriteByte(0xff);//提供额外的8个时钟
  40. }


  41. //选择sd卡,并且等待卡准备OK
  42. //返回值:0,成功;1,失败;
  43. u8 SD_Select(void)
  44. {
  45.     SD_CS_L;
  46.     if(SD_WaitReady()==0)return 0;//等待成功
  47.     SD_DisSelect();
  48.     return 1;//等待失败
  49. }


  50. //等待卡准备好
  51. //返回值:0,准备好了;其他,错误代码
  52. u8 SD_WaitReady(void)
  53. {
  54.     u32 t=0;
  55.     do
  56.     {
  57.         if(SD_SPI_ReadWriteByte(0XFF)==0XFF)return 0;//OK
  58.         t++;
  59.     }while(t<0XFFFFFF);//等待
  60.     return 1;
  61. }


  62. //等待SD卡回应
  63. //Response:要得到的回应值
  64. //返回值:0,成功得到了该回应值
  65. //    其他,得到回应值失败
  66. u8 SD_GetResponse(u8 Response)
  67. {
  68.     u16 Count=0xFFFF;//等待次数
  69.     while ((SD_SPI_ReadWriteByte(0XFF)!=Response)&&Count)Count--;//等待得到准确的回应
  70.     if (Count==0)return MSD_RESPONSE_FAILURE;//得到回应失败
  71.     else return MSD_RESPONSE_NO_ERROR;//正确回应
  72. }


  73. //从sd卡读取一个数据包的内容
  74. //buf:数据缓存区
  75. //len:要读取的数据长度.
  76. //返回值:0,成功;其他,失败;
  77. u8 SD_RecvData(u8*buf,u16 len)
  78. {
  79.     if(SD_GetResponse(0xFE))return 1;//等待SD卡发回数据起始令牌0xFE
  80.     while(len--)//开始接收数据
  81.     {
  82.         *buf=SPI1_ReadWriteByte(0xFF);
  83.         buf++;
  84.     }
  85.     //下面是2个伪CRC(dummy CRC)
  86.     SD_SPI_ReadWriteByte(0xFF);
  87.     SD_SPI_ReadWriteByte(0xFF);
  88.     return 0;//读取成功
  89. }


  90. //向sd卡写入一个数据包的内容 512字节
  91. //buf:数据缓存区
  92. //cmd:指令
  93. //返回值:0,成功;其他,失败;
  94. u8 SD_SendBlock(u8*buf,u8 cmd)
  95. {
  96.     u16 t;
  97.     if(SD_WaitReady())return 1;//等待准备失效
  98.     SD_SPI_ReadWriteByte(cmd);
  99.     if(cmd!=0XFD)//不是结束指令
  100.     {
  101.         for(t=0;t<512;t++)SPI1_ReadWriteByte(buf[t]);//提高速度,减少函数传参时间
  102.         SD_SPI_ReadWriteByte(0xFF);//忽略crc
  103.         SD_SPI_ReadWriteByte(0xFF);
  104.         t=SD_SPI_ReadWriteByte(0xFF);//接收响应
  105.         if((t&0x1F)!=0x05)return 2;//响应错误
  106.     }
  107.     return 0;//写入成功
  108. }


  109. //向SD卡发送一个命令
  110. //输入: u8 cmd   命令
  111. //      u32 arg  命令参数
  112. //      u8 crc   crc校验值
  113. //返回值:SD卡返回的响应
  114. u8 SD_SendCmd(u8 cmd, u32 arg, u8 crc)
  115. {
  116.     u8 r1;
  117.     u8 Retry=0;
  118.     SD_DisSelect();//取消上次片选
  119.     if(SD_Select())return 0XFF;//片选失效
  120.     //发送
  121.     SD_SPI_ReadWriteByte(cmd | 0x40);//分别写入命令
  122.     SD_SPI_ReadWriteByte(arg >> 24);
  123.     SD_SPI_ReadWriteByte(arg >> 16);
  124.     SD_SPI_ReadWriteByte(arg >> 8);
  125.     SD_SPI_ReadWriteByte(arg);
  126.     SD_SPI_ReadWriteByte(crc);
  127.     if(cmd==CMD12)SD_SPI_ReadWriteByte(0xff);//Skip a stuff byte when stop reading
  128.     //等待响应,或超时退出
  129.     Retry=0X1F;
  130.     do
  131.     {
  132.         r1=SD_SPI_ReadWriteByte(0xFF);
  133.     }while((r1&0X80) && Retry--);
  134.     //返回状态值
  135.     return r1;
  136. }


  137. //获取SD卡的CID信息,包括制造商信息
  138. //输入: u8 *cid_data(存放CID的内存,至少16Byte)
  139. //返回值:0:NO_ERR
  140. //       1:错误
  141. u8 SD_GetCID(u8 *cid_data)
  142. {
  143.     u8 r1;
  144.     //发CMD10命令,读CID
  145.     r1=SD_SendCmd(CMD10,0,0x01);
  146.     if(r1==0x00)
  147.     {
  148.         r1=SD_RecvData(cid_data,16);//接收16个字节的数据
  149.     }
  150.     SD_DisSelect();//取消片选
  151.     if(r1)return 1;
  152.     else return 0;
  153. }


  154. //获取SD卡的CSD信息,包括容量和速度信息
  155. //输入:u8 *cid_data(存放CID的内存,至少16Byte)
  156. //返回值:0:NO_ERR
  157. //       1:错误
  158. u8 SD_GetCSD(u8 *csd_data)
  159. {
  160.     u8 r1;
  161.     r1=SD_SendCmd(CMD9,0,0x01);//发CMD9命令,读CSD
  162.     if(r1==0)
  163.     {
  164.         r1=SD_RecvData(csd_data, 16);//接收16个字节的数据
  165.     }
  166.     SD_DisSelect();//取消片选
  167.     if(r1)return 1;
  168.     else return 0;
  169. }


  170. //获取SD卡的总扇区数(扇区数)
  171. //返回值:0: 取容量出错
  172. //       其他:SD卡的容量(扇区数/512字节)
  173. //每扇区的字节数必为512,因为如果不是512,则初始化不能通过.
  174. u32 SD_GetSectorCount(void)
  175. {
  176.     u8 csd[16];
  177.     uint64_t Capacity;
  178.     u8 n;
  179.     u16 csize;
  180.     //取CSD信息,如果期间出错,返回0
  181.     if(SD_GetCSD(csd)!=0) return 0;
  182.     //如果为SDHC卡,按照下面方式计算
  183.     if((csd[0]&0xC0)==0x40)  //V2.00的卡
  184.     {
  185.         csize = csd[9] + ((u16)csd[8] << 8) + 1;
  186.         Capacity = (u32)csize << 10;//得到扇区数
  187.     }else//V1.XX的卡
  188.     {
  189.         n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
  190.         csize = (csd[8] >> 6) + ((u16)csd[7] << 2) + ((u16)(csd[6] & 3) << 10) + 1;
  191.         Capacity= (u32)csize << (n - 9);//得到扇区数
  192.     }
  193.     return Capacity;
  194. }


  195. //初始化SD卡
  196. u8 SD_Initialize(void)
  197. {
  198.     u8 r1;      // 存放SD卡的返回值
  199.     u16 retry;  // 用来进行超时计数
  200.     u8 buf[4];
  201.     u16 i;

  202.     SD_SPI_Init();      //初始化IO
  203.     for(i=0;i<10;i++)SD_SPI_ReadWriteByte(0XFF);//发送最少74个脉冲
  204.     retry=20;
  205.     do
  206.     {
  207.         r1=SD_SendCmd(CMD0,0,0x95);//进入IDLE状态
  208.     }while((r1!=0X01) && retry--);
  209.     SD_Type=0;//默认无卡
  210.     if(r1==0X01)
  211.     {
  212.         if(SD_SendCmd(CMD8,0x1AA,0x87)==1)//SD V2.0
  213.         {
  214.             for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF);  //Get trailing return value of R7 resp
  215.             if(buf[2]==0X01&&buf[3]==0XAA)//卡是否支持2.7~3.6V
  216.             {
  217.                 retry=0XFFFE;
  218.                 do
  219.                 {
  220.                     SD_SendCmd(CMD55,0,0X01);   //发送CMD55
  221.                     r1=SD_SendCmd(CMD41,0x40000000,0X01);//发送CMD41
  222.                 }while(r1&&retry--);
  223.                 if(retry&&SD_SendCmd(CMD58,0,0X01)==0)//鉴别SD2.0卡版本开始
  224.                 {
  225.                     for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF);//得到OCR值
  226.                     if(buf[0]&0x40)SD_Type=SD_TYPE_V2HC;    //检查CCS
  227.                     else SD_Type=SD_TYPE_V2;
  228.                 }
  229.             }
  230.         }else//SD V1.x/ MMC V3
  231.         {
  232.             SD_SendCmd(CMD55,0,0X01);       //发送CMD55
  233.             r1=SD_SendCmd(CMD41,0,0X01);    //发送CMD41
  234.             if(r1<=1)
  235.             {
  236.                 SD_Type=SD_TYPE_V1;
  237.                 retry=0XFFFE;
  238.                 do //等待退出IDLE模式
  239.                 {
  240.                     SD_SendCmd(CMD55,0,0X01);   //发送CMD55
  241.                     r1=SD_SendCmd(CMD41,0,0X01);//发送CMD41
  242.                 }while(r1&&retry--);
  243.             }else//MMC卡不支持CMD55+CMD41识别
  244.             {
  245.                 SD_Type=SD_TYPE_MMC;//MMC V3
  246.                 retry=0XFFFE;
  247.                 do //等待退出IDLE模式
  248.                 {
  249.                     r1=SD_SendCmd(CMD1,0,0X01);//发送CMD1
  250.                 }while(r1&&retry--);
  251.             }
  252.             if(retry==0||SD_SendCmd(CMD16,512,0X01)!=0)SD_Type=SD_TYPE_ERR;//错误的卡
  253.         }
  254.     }
  255.     SD_DisSelect();//取消片选
  256.     if(SD_Type)return 0;
  257.     else if(r1)return r1;
  258.     return 0xaa;//其他错误
  259. }


  260. //读SD卡
  261. //buf:数据缓存区
  262. //sector:扇区
  263. //cnt:扇区数
  264. //返回值:0,ok;其他,失败.
  265. u8 SD_ReadDisk(u8*buf,u32 sector,u8 cnt)
  266. {
  267.     u8 r1;
  268.     if(SD_Type!=SD_TYPE_V2HC)sector <<= 9;//转换为字节地址
  269.     if(cnt==1)
  270.     {
  271.         r1=SD_SendCmd(CMD17,sector,0X01);//读命令
  272.         if(r1==0)//指令发送成功
  273.         {
  274.             r1=SD_RecvData(buf,512);//接收512个字节
  275.         }
  276.     }else
  277.     {
  278.         r1=SD_SendCmd(CMD18,sector,0X01);//连续读命令
  279.         do
  280.         {
  281.             r1=SD_RecvData(buf,512);//接收512个字节
  282.             buf+=512;
  283.         }while(--cnt && r1==0);
  284.         SD_SendCmd(CMD12,0,0X01);   //发送停止命令
  285.     }
  286.     SD_DisSelect();//取消片选
  287.     return r1;//
  288. }


  289. //写SD卡
  290. //buf:数据缓存区
  291. //sector:起始扇区
  292. //cnt:扇区数
  293. //返回值:0,ok;其他,失败.
  294. u8 SD_WriteDisk(u8*buf,u32 sector,u8 cnt)
  295. {
  296.     u8 r1;
  297.     if(SD_Type!=SD_TYPE_V2HC)sector *= 512;//转换为字节地址
  298.     if(cnt==1)
  299.     {
  300.         r1=SD_SendCmd(CMD24,sector,0X01);//写命令
  301.         if(r1==0)//指令发送成功
  302.         {
  303.             r1=SD_SendBlock(buf,0xFE);//写512个字节,0xFE表示开始写
  304.         }
  305.     }else
  306.     {
  307.         if(SD_Type!=SD_TYPE_MMC)
  308.         {
  309.             SD_SendCmd(CMD55,0,0X01);
  310.             SD_SendCmd(CMD23,cnt,0X01);//发送指令
  311.         }
  312.         r1=SD_SendCmd(CMD25,sector,0X01);//连续写命令
  313.         if(r1==0)
  314.         {
  315.             do
  316.             {
  317.                 r1=SD_SendBlock(buf,0xFC);//0xFC表示多块数据写入开始
  318.                 buf+=512;
  319.             }while(--cnt && r1==0);
  320.             r1=SD_SendBlock(0,0xFD);//0xFD表示多块数据写入结束
  321.         }
  322.     }
  323.     SD_DisSelect();//取消片选
  324.     return r1;//
  325. }
sd.c文件主要进行SD初始化等操作,关于SD卡初始化函数SD_Initialize,其具体操作流程如下:
(1)调用SD_SPI_Init函数初始化GPIO口及SPI工作模式,同时控制片选引脚使之输出高电平;
(2)利用for循环并调用SD_SPI_ReadWriteByte函数进行10读写操作,,同时产生80个时钟信号,满足SD卡初始化至少需要74个时钟的要求;
(3)调用SD_SendCmd函数发送CMD0命令,复位SD卡同时进入空闲状态;
(4)调用SD_SendCmd函数发送相关命令对SD卡版本类型进行判断,同时返回响应信息。
关于sd.c文件中其他函数,程序中都有相应注释,可结合注释以及《 Physical Layer Simplified Specification V2.0》手册进行理解。

main.c文件
  1. int main(void)
  2. {
  3.     u32 sd_size;

  4.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  5.     Delay_Init();
  6.         USART_Printf_Init(115200);

  7.         printf("SystemClk:%d\r\n",SystemCoreClock);
  8.         printf("This is SD Test example\r\n");

  9.         if(SD_Detect()==0)
  10.         {
  11.             printf("未检测SD卡插入!\n");
  12.         }
  13.         else
  14.         {
  15.             printf("已检测SD卡插入!\n");

  16.             if(SD_Initialize())
  17.             {
  18.                 printf("SD卡初始化出错,请检查!!\n");
  19.                 Delay_Ms(500);
  20.             }
  21.             else
  22.             {
  23.                 printf("SD卡初始化完成!\n");
  24.                 sd_size=SD_GetSectorCount();//得到扇区数
  25.                 printf("SD Card Size(MB):%d\n",sd_size>>11);
  26.             }
  27.         }

  28.         while(1)
  29.     {
  30.         }
  31. }
main.c文件主要进行相关函数初始化以及SD卡插入检测、初始化检测以及读取SD卡容量大小。

4下载验证
将编译好的程序下载到开发板并复位,当未插入SD卡时,串口打印情况具体如下:
图片4.png
插入SD卡并复位后,串口打印情况如下:
图片5.png


24、SPISD.rar

509.76 KB, 下载次数: 160

MianQi 发表于 2021-2-24 11:12 | 显示全部楼层
只看到PA3接CS,SCK、MOSI、MISO怎么接?
 楼主| RISCVLAR 发表于 2021-2-24 15:07 | 显示全部楼层
MianQi 发表于 2021-2-24 11:12
只看到PA3接CS,SCK、MOSI、MISO怎么接?

486196035fb1618af5.png
程序下面有SPI初始化函数
小明噢噢噢噢 发表于 2021-5-19 10:44 | 显示全部楼层
这个串口调试助手叫什么名字呀?我在网上下载了好多都不是这个

评论

@RISCVLAR :谢啦  发表于 2021-5-25 16:29
这是下载链接:https://bbs.21ic.com/icview-3072640-1-1.html  发表于 2021-5-19 11:23
guijial511 发表于 2021-5-20 12:37 来自手机 | 显示全部楼层
谢谢楼主的分享
1435283587 发表于 2021-8-16 15:23 | 显示全部楼层
楼主主函数里为什么没有sd卡初始化函数

评论

有的,下面if判断里有进行初始化  发表于 2021-8-16 17:03
gygp 发表于 2021-9-2 20:39 | 显示全部楼层
SDIO驱动SD速度快吗?      
chenci2013 发表于 2021-9-2 20:39 | 显示全部楼层
这个FATFS的速度是多少?      
biechedan 发表于 2021-9-2 20:40 | 显示全部楼层
这个可以使用DMA吗?              
wangdezhi 发表于 2021-9-2 20:40 | 显示全部楼层
最大支持多大的sd卡呢?         
isseed 发表于 2021-9-2 20:40 | 显示全部楼层
使用的是spi,不是sdio吧            
xietingfeng 发表于 2021-9-2 20:41 | 显示全部楼层
usb的驱动有了吗   
suzhanhua 发表于 2021-9-2 20:41 | 显示全部楼层
CH32V103集成的外设功能真多。   
mituzu 发表于 2021-9-2 20:41 | 显示全部楼层
这个如果做字库,会不会很慢呢?   
hellosdc 发表于 2021-9-2 20:41 | 显示全部楼层
SDHC也能读取吗?         
uiint 发表于 2021-9-2 20:42 | 显示全部楼层
文件系统搞起来吧。           
ah99 发表于 2022-8-30 11:15 | 显示全部楼层
烧录24后,SD卡插入,复位,识别失败报错

8GSD卡识别失败

8GSD卡识别失败
tifmill 发表于 2022-9-5 15:29 | 显示全部楼层
需要文件系统吗  
hilahope 发表于 2022-9-5 17:07 | 显示全部楼层
可以做成U盘吗      
alvpeg 发表于 2022-9-7 21:05 | 显示全部楼层
SDIO接口速度快吗  
您需要登录后才可以回帖 登录 | 注册

本版积分规则

133

主题

296

帖子

45

粉丝
快速回复 在线客服 返回列表 返回顶部