通过stm32L152给SD卡创建文本,但是数据无法写入成功

2019-03-23 16:50发布

本帖最后由 y909334873 于 2016-9-5 11:03 编辑

刚开始学习文件系统,给单片机移植了fat文件系统,出现了这样一个问题,我创建了一个文本文件(比如说是y.txt),然后给这个文本文件写入一段文本,通过电脑查看SD卡里的内容,显示这个文本文件(y.txt)显示还是0字节;
2.png
同时连接是会出现修复U盘的提示。也就是说往文本文件里写数据没有成功。
但是如果我通过电脑给这个文本文件写一句话,保存后是这样的
1.png
接下来我在通过单片机给这个文件进行写数据,那么我写的数据量不能超过这个文本文件的13字节,不超过的部分,可以通过电脑正常显示,也可以通过单片机读文件操作。超过的部分通过电脑查看,或者单片机读文件操作读是不成功看不到的

此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
20条回答
y909334873
2019-03-25 15:33
flyword 发表于 2016-9-7 14:49
使用的SPI吗?贴出来那部分代码看看!
  1. void SD_LowLevel_DeInit(void)
  2. {
  3.   GPIO_InitTypeDef  GPIO_InitStructure;
  4.   
  5.   SPI_Cmd(SD_SPI, DISABLE); /*!< SD_SPI disable */
  6.   SPI_DeInit(SD_SPI);   /*!< DeInitializes the SD_SPI */
  7.   
  8.   /*!< SD_SPI Periph clock disable */
  9.   RCC_APB1PeriphClockCmd(SD_SPI_CLK, DISABLE);

  10.   /*!< Configure SD_SPI pins: SCK */
  11.   GPIO_InitStructure.GPIO_Pin = SD_SPI_SCK_PIN;
  12.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  13.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  14.   GPIO_Init(SD_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);

  15.   /*!< Configure SD_SPI pins: MISO */
  16.   GPIO_InitStructure.GPIO_Pin = SD_SPI_MISO_PIN;
  17.   GPIO_Init(SD_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);

  18.   /*!< Configure SD_SPI pins: MOSI */
  19.   GPIO_InitStructure.GPIO_Pin = SD_SPI_MOSI_PIN;
  20.   GPIO_Init(SD_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);

  21.   /*!< Configure SD_SPI_CS_PIN pin: SD Card CS pin */
  22.   GPIO_InitStructure.GPIO_Pin = SD_CS_PIN;
  23.   GPIO_Init(SD_CS_GPIO_PORT, &GPIO_InitStructure);

  24.   /*!< Configure SD_SPI_DETECT_PIN pin: SD Card detect pin */
  25. //  GPIO_InitStructure.GPIO_Pin = SD_DETECT_PIN;
  26. //  GPIO_Init(SD_DETECT_GPIO_PORT, &GPIO_InitStructure);
  27. }
复制代码SPI初始化,应该没有什么问题,sd卡 的读文件,创建文件,和删除文件功能都是正常的

  1. SD_Error SD_Init(void)
  2. {
  3.         uint32_t i = 0;
  4.         uint8_t r1 = 0;
  5.         uint16_t retry = 0;
  6.         uint8_t buf[4];
  7.   //SPI_InitTypeDef   SPI_InitStructure;  
  8.         //logout("sd init ");
  9.   /*!< Initialize SD_SPI */
  10.    for(i=0;i<0xf00;i++);
  11.         //logout("SD_LowLevel_Init done ");
  12.   /*!< SD chip select high */

  13.    SPI2_SetSpeed(SPI_BaudRatePrescaler_256);
  14.   /*!< Send dummy byte 0xFF, 10 times with CS high */
  15.   /*!< Rise CS and MOSI for 80 clocks cycles */
  16.   for(i=0;i<10;i++)SD_ReadWriteByte(0XFF);//发送最少74个脉冲
  17.         retry=20;
  18.         do
  19.         {
  20.                 r1 = SD_SendCmd1(SD_CMD_GO_IDLE_STATE,0,0x95);//进入IDLE状态
  21.         }while((r1!=0X01) && retry--);
  22.         //logout("SD_idle_pass ");
  23.         //logout("R1 = %d ",r1);

  24.         SD_Type=0;//默认无卡
  25.        
  26.         if(r1==0X01)
  27.         {
  28.                 //logout("1111");
  29.                 if(SD_SendCmd1(SD_CMD_SEND_IF_COND,0x1AA,0x87)==1)//SD V2.0
  30.                 {
  31.                         for(i=0;i<4;i++)buf[i]=SD_ReadWriteByte(0XFF);        //Get trailing return value of R7 resp
  32.                         if(buf[2]==0X01&&buf[3]==0XAA)//卡是否支持2.7~3.6V
  33.                         {
  34.                                 retry=0XFFFE;
  35.                                 do
  36.                                 {
  37.                                         SD_SendCmd1(55,0,0X01);        //发送CMD55
  38.                                         r1=SD_SendCmd1(41,0x40000000,0X01);//发送CMD41
  39.                                 }while(r1&&retry--);
  40.                                 if(retry&&SD_SendCmd1(58,0,0X01)==0)//鉴别SD2.0卡版本开始
  41.                                 {
  42.                                         for(i=0;i<4;i++)buf[i]=SD_ReadWriteByte(0XFF);//得到OCR值
  43.                                         if(buf[0]&0x40)SD_Type=SD_TYPE_V2HC;    //检查CCS
  44.                                         else SD_Type=SD_TYPE_V2;   
  45.                                 }
  46.                         }
  47.                 }
  48.                 else//SD V1.x/ MMC        V3
  49.                 {
  50.                         //logout("222");
  51.                         SD_SendCmd1(55,0,0X01);                //发送CMD55
  52.                         r1=SD_SendCmd1(41,0,0X01);        //发送CMD41
  53.                         if(r1<=1)
  54.                         {               
  55.                                 SD_Type=SD_TYPE_V1;
  56.                                 retry=0XFFFE;
  57.                                 do //等待退出IDLE模式
  58.                                 {
  59.                                         SD_SendCmd1(55,0,0X01);        //发送CMD55
  60.                                         r1=SD_SendCmd1(41,0,0X01);//发送CMD41
  61.                                 }while(r1&&retry--);
  62.                         }else//MMC卡不支持CMD55+CMD41识别
  63.                         {
  64.                                 SD_Type=SD_TYPE_MMC;//MMC V3
  65.                                 logout("MMC");
  66.                                 retry=0XFFFE;
  67.                                 do //等待退出IDLE模式
  68.                                 {                                                                                            
  69.                                         r1=SD_SendCmd1(1,0,0X01);//发送CMD1
  70.                                 }while(r1&&retry--);  
  71.                         }
  72.                         if(retry==0||SD_SendCmd1(16,512,0X01)!=0)SD_Type=SD_TYPE_ERR,logout("fau");//错误的卡
  73.                 }
  74.         }
  75.         SD_DisSelect();//取消片选
  76.         SPI2_SetSpeed(SPI_BaudRatePrescaler_2);
  77.         if(SD_Type)
  78.         {
  79.                 //logout("0");       
  80.                 return 0;
  81.         }
  82.         else if(r1)
  83.         {
  84.                 logout("R1 = %d ",r1);  
  85.                 return r1;
  86.         }       
  87.        
  88. }
复制代码
SD卡 的初始化仿照f103的写的
  1. uint8_t SD_SendCmd1(uint8_t  cmd, uint32_t  arg, uint8_t  crc)
  2. {
  3.   uint8_t r1;       
  4.         uint8_t Retry=0;
  5.         SD_DisSelect();//取消上次片选
  6.         if(SD_Select())return 0XFF;//片选失效
  7.         //发送
  8.     SD_ReadWriteByte(cmd | 0x40);//分别写入命令
  9.     SD_ReadWriteByte(arg >> 24);
  10.     SD_ReadWriteByte(arg >> 16);
  11.     SD_ReadWriteByte(arg >> 8);
  12.     SD_ReadWriteByte(arg);          
  13.     SD_ReadWriteByte(crc);
  14.         if(cmd==SD_CMD_STOP_TRANSMISSION)SD_ReadWriteByte(0xff);//Skip a stuff byte when stop reading
  15.     //等待响应,或超时退出
  16.         Retry=0X1F;
  17.         do
  18.         {
  19.                 r1=SD_ReadWriteByte(0xff);
  20.         }while((r1&0X80) && Retry--);         
  21.         //返回状态值
  22.     return r1;
  23. }
  24. ///////////////////////////////////////////////////////////////////////////////////
  25. //取消选择,释放SPI总线
  26. void SD_DisSelect(void)
  27. {
  28.         SD_CS_HIGH();
  29.         SD_ReadWriteByte(0xff);//提供额外的8个时钟
  30. }
  31. //选择sd卡,并且等待卡准备OK
  32. //返回值:0,成功;1,失败;
  33. uint8_t SD_Select(void)
  34. {
  35.         SD_CS_LOW();
  36.         if(SD_WaitReady()==0)return 0;//等待成功
  37.         SD_DisSelect();
  38.         return 1;//等待失败
  39. }
  40. //等待卡准备好
  41. //返回值:0,准备好了;其他,错误代码
  42. uint8_t SD_WaitReady(void)
  43. {
  44.         uint32_t t=0;
  45.         do
  46.         {
  47.                 if(SD_ReadWriteByte(0XFF)==0XFF)return 0;//OK
  48.                 t++;                         
  49.         }while(t<0XFFFFFF);//等待
  50.         return 1;
  51. }

  52. uint32_t  SD_GetSectorCount(void)
  53. {
  54.     uint8_t csd[16];
  55.     uint32_t  Capacity;  
  56.     uint8_t  n;
  57.           uint16_t  csize;                                              
  58.         //取CSD信息,如果期间出错,返回0
  59.     if(SD_GetCSD(csd)!=0)
  60.                 {
  61.                         logout("csd fail ");
  62.                         return 0;
  63.                 }            
  64.     //如果为SDHC卡,按照下面方式计算
  65.     if((csd[0]&0xC0)==0x40)         //V2.00的卡
  66.     {       
  67.                 csize = csd[9] + ((uint16_t)csd[8] << 8) + 1;
  68.                 Capacity = (uint32_t)csize << 10;//得到扇区数                           
  69.     }else//V1.XX的卡
  70.     {       
  71.                 n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
  72.                 csize = (csd[8] >> 6) + ((uint16_t)csd[7] << 2) + ((uint16_t)(csd[6] & 3) << 10) + 1;
  73.                 Capacity= (uint32_t)csize << (n - 9);//得到扇区数   
  74.     }
  75.     return Capacity;
  76. }
  77. //获取SD卡的CSD信息,包括容量和速度信息
  78. //输入:uint8_t *cid_data(存放CID的内存,至少16Byte)            
  79. //返回值:0:NO_ERR
  80. //                 1:错误                                                                                                                  
  81. uint8_t SD_GetCSD(uint8_t *csd_data)
  82. {
  83.     uint8_t r1;         
  84.           logout("gCSD1 ");
  85.     r1 = SD_SendCmd1(SD_CMD_SEND_CSD,0,0x01);//发CMD9命令,读CSD
  86.           logout("gCSD2 ");
  87.     if(r1==0)
  88.         {
  89.             r1= SD_RecvData(csd_data, 16);//接收16个字节的数据
  90.     }
  91.         SD_DisSelect();//取消片选
  92.         if(r1)return 1;
  93.         else return 0;
  94. }
  95. //从sd卡读取一个数据包的内容
  96. //buf:数据缓存区
  97. //len:要读取的数据长度.
  98. //返回值:0,成功;其他,失败;       
  99. uint8_t SD_RecvData(uint8_t *buf,uint16_t len)
  100. {                                    
  101.         if(SD_GetResponse(0xFE))return 1;//等待SD卡发回数据起始令牌0xFE
  102.     while(len--)//开始接收数据
  103.     {
  104.         *buf=SD_ReadWriteByte(0xFF);
  105.         buf++;
  106.     }
  107.     //下面是2个伪CRC(dummy CRC)
  108.     SD_ReadWriteByte(0xFF);
  109.     SD_ReadWriteByte(0xFF);                                                                                                                      
  110.     return 0;//读取成功
  111. }
  112. void SPI2_SetSpeed(uint8_t SpeedSet)
  113. {
  114.         SPI_InitStructure.SPI_BaudRatePrescaler = SpeedSet ;
  115.   SPI_Init(SPI2, &SPI_InitStructure);
  116.         SPI_Cmd(SPI2,ENABLE);
  117. }
  118. //读SD卡
  119. //buf:数据缓存区
  120. //sector:扇区
  121. //cnt:扇区数
  122. //返回值:0,ok;其他,失败.
  123. uint8_t SD_ReadDisk(uint8_t*buf,uint32_t sector,uint8_t cnt)
  124. {
  125.         uint8_t r1;
  126.         if(SD_Type!=SD_TYPE_V2HC)sector <<= 9;//转换为字节地址
  127.         if(cnt==1)
  128.         {
  129.                 r1=SD_SendCmd1(SD_CMD_READ_SINGLE_BLOCK,sector,0X01);//读命令
  130.                 if(r1==0)//指令发送成功
  131.                 {
  132.                         r1=SD_RecvData(buf,512);//接收512个字节          
  133.                 }
  134.         }else
  135.         {
  136.                 r1=SD_SendCmd1(SD_CMD_READ_MULT_BLOCK,sector,0X01);//连续读命令
  137.                 do
  138.                 {
  139.                         r1=SD_RecvData(buf,512);//接收512个字节         
  140.                         buf+=512;  
  141.                 }while(--cnt && r1==0);        
  142.                 SD_SendCmd(SD_CMD_STOP_TRANSMISSION,0,0X01);        //发送停止命令
  143.         }   
  144.         SD_DisSelect();//取消片选
  145.         return r1;//
  146. }
  147. //写SD卡
  148. //buf:数据缓存区
  149. //sector:起始扇区
  150. //cnt:扇区数
  151. //返回值:0,ok;其他,失败.
  152. uint8_t SD_WriteDisk(const uint8_t*buf,uint32_t sector,uint8_t cnt)
  153. {
  154.         uint8_t r1;
  155.         if(SD_Type!=SD_TYPE_V2HC)sector *= 512;//转换为字节地址
  156.         if(cnt==1)
  157.         {
  158.                 r1=SD_SendCmd1(SD_CMD_WRITE_SINGLE_BLOCK,sector,0X01);//读命令
  159.                 if(r1==0)//指令发送成功
  160.                 {
  161.                         r1=SD_SendBlock(buf,0xFE);//写512个字节          
  162.                 }
  163.         }else
  164.         {
  165.                 if(SD_Type!=SD_TYPE_MMC)
  166.                 {
  167.                         SD_SendCmd1(55,0,0X01);       
  168.                         SD_SendCmd1(SD_CMD_SET_BLOCK_COUNT,cnt,0X01);//发送指令       
  169.                 }
  170.                 r1=SD_SendCmd1(SD_CMD_WRITE_MULT_BLOCK,sector,0X01);//连续读命令
  171.                 if(r1==0)
  172.                 {
  173.                         do
  174.                         {
  175.                                 r1=SD_SendBlock(buf,0xFC);//接收512个字节         
  176.                                 buf+=512;  
  177.                         }while(--cnt && r1==0);
  178.                         r1=SD_SendBlock(0,0xFD);//接收512个字节
  179.                 }
  180.         }   
  181.         SD_DisSelect();//取消片选
  182.         return r1;//
  183. }       

  184. uint8_t SD_SendBlock(const uint8_t *buf,uint8_t cmd)
  185. {       
  186.         uint16_t  t;                            
  187.         if(SD_WaitReady())return 1;//等待准备失效
  188.         SD_ReadWriteByte(cmd);
  189.         if(cmd!=0XFD)//不是结束指令
  190.         {
  191.                 for(t=0;t<512;t++)SD_ReadWriteByte(buf[t]);//提高速度,减少函数传参时间
  192.             SD_ReadWriteByte(0xFF);//忽略crc
  193.             SD_ReadWriteByte(0xFF);
  194.                 t=SD_ReadWriteByte(0xFF);//接收响应
  195.                 if((t&0x1F)!=0x05)return 2;//响应错误                                                                                                                      
  196.         }                                                                                                                                                                       
  197.     return 0;//写入成功
  198. }
复制代码
后面的这些也是照着写的

一周热门 更多>