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

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

回复评论 (25)

1 来自 21楼 y909334873 

问题已经变向的解决了,换成了官方例子下包含的FATFS版本可以用了,谢谢大家帮助
Hello astroturfers
点赞  2016-9-8 16:58
读一下扇区看看问题出在哪里了
点赞  2016-9-5 10:53
贴一贴你C语言操作读写文件的代码
点赞  2016-9-5 11:32
单独读写扇区  正常嘛
点赞  2016-9-5 13:10
怀疑你没有修改文件长度
点赞  2016-9-5 14:50
引用: xinjitmzy 发表于 2016-9-5 13:10
单独读写扇区  正常嘛

正常
Hello astroturfers
点赞  2016-9-6 18:04
引用: huo_hu 发表于 2016-9-5 14:50
怀疑你没有修改文件长度

修改了
Hello astroturfers
点赞  2016-9-6 18:05
贴出代码看看行不行,我原来出现过只能创建文件,不能读写文件,是因为读写函数有问题。
点赞  2016-9-7 08:29
  1. void Test_f_write(void)//写数据到文件,如果没有此文件则创建文件
  2. {
  3.     FATFS fs;            // Work area (file system object) for logical drive
  4.     FRESULT res;         // FatFs function common result code
  5.         FIL Make_file;
  6.     char file_name[20]="jj.txt";
  7.     char Storage_buffer[] ="1234567890";       
  8.         UINT bw;
  9.         //检测磁盘是否插好
  10.         if( disk_detect_OK()==FALSE ) return;
  11.          logout("\r\n inaert_ok:>");
  12.     // Register a work area for logical drive 0
  13.     f_mount(0, &fs);

  14.         logout("\r\n Make file Name:>");
  15. //        USART_Scanf_Name(file_name);//通过串口输入源文件路径名/dir/file.txt或者0:dir/file.txt或者0:/dir/file.txt

  16.    res = f_open(&Make_file, file_name,  FA_OPEN_ALWAYS | FA_WRITE); //可写方式打开 没有文件则创建
  17.          logout("\r\n open_ok:>");
  18.          die(res);
  19.    res = f_lseek(&Make_file, bsize); //指针移到文件最后  
  20.    logout("\r\n seek_ok:>");
  21.          die(res);
  22.          res = f_write(&Make_file, Storage_buffer, (sizeof (Storage_buffer))-1 , &bw); //每次需要写入的数据字节数,去掉最后的\0所以-1  
  23.    logout("\r\n write_ok:>");
  24.          die(res);
  25.          //logout("文件大小=%d字节\r\n",Make_file.fsize);
  26.         res = f_lseek(&Make_file, Make_file.fsize); //指针移到文件最后  
  27.         //logout("文件大小=%d字节\r\n",Make_file.fsize);
  28.         f_close(&Make_file);//关闭文件
  29.         logout("\r\n close_ok:>");
  30.   //logout("文件大小=%d字节\r\n",Make_file.fsize);
  31.         logout("\r\n写文件测试OK!\r\n");

  32.         // Unregister a work area before discard it
  33.    f_mount(0, NULL);
  34. }






  35. //其中调用的f_wriite函数如下
  36. FRESULT f_write (
  37.     FIL *fp,            /* Pointer to the file object */
  38.     const void *buff,    /* Pointer to the data to be written */
  39.     UINT btw,            /* Number of bytes to write */
  40.     UINT *bw            /* Pointer to number of bytes written */
  41. )
  42. {
  43.     FRESULT res;
  44.     DWORD clst, sect;
  45.     UINT wcnt, cc;
  46.     const BYTE *wbuff = buff;
  47.    
  48.     BYTE csect;

  49.   bsize+=btw;
  50.     *bw = 0;    /* Initialize byte counter */
  51.     logout("1111111111111111111\r\n");
  52.     res = validate(fp->fs, fp->id);            /* Check validity */
  53.     fp->fsize =fp->fsize +btw;
  54.     logout("wenjian=%d\r\n",fp->fsize);
  55.     //f_sync (fp);
  56.     if (res != FR_OK) LEAVE_FF(fp->fs, res);
  57.     if (fp->flag & FA__ERROR)                /* Aborted file? */
  58.         LEAVE_FF(fp->fs, FR_INT_ERR);
  59.     logout("22222222222222222222222222\r\n");
  60.     if (!(fp->flag & FA_WRITE))                /* Check access mode */
  61.         LEAVE_FF(fp->fs, FR_DENIED);
  62.     if ((DWORD)(fp->fsize + btw) < fp->fsize) btw = 0;    /* File size cannot reach 4GB */
  63.    logout("333333333333333333333333\r\n");
  64.     for ( ;  btw;                            /* Repeat until all data written */
  65.         wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) {
  66.             logout("44444444444444444\r\n");
  67.         if ((fp->fptr % SS(fp->fs)) == 0)
  68.         {    /* On the sector boundary? */
  69.             
  70.             csect = (BYTE)(fp->fptr / SS(fp->fs) & (fp->fs->csize - 1));    /* Sector offset in the cluster */
  71.             if (!csect)
  72.                 {
  73.                     /* On the cluster boundary? */
  74.                 if (fp->fptr == 0) {        /* On the top of the file? */
  75.                     clst = fp->sclust;        /* Follow from the origin */
  76.                     if (clst == 0)            /* When no cluster is allocated, */
  77.                         fp->sclust = clst = create_chain(fp->fs, 0);    /* Create a new cluster chain */
  78.                 } else {                    /* Middle or end of the file */
  79. #if _USE_FASTSEEK
  80.                     if (fp->cltbl)
  81.                         clst = clmt_clust(fp, fp->fptr);    /* Get cluster# from the CLMT */
  82.                     else
  83. #endif
  84.                     
  85.                         clst = create_chain(fp->fs, fp->clust);    /* Follow or stretch cluster chain on the FAT */
  86.                 }
  87.                 if (clst == 0) break;        /* Could not allocate a new cluster (disk full) */
  88.                 if (clst == 1) ABORT(fp->fs, FR_INT_ERR);   
  89.                         
  90.                 if (clst == 0xFFFFFFFF) ABORT(fp->fs, FR_DISK_ERR);
  91.                 fp->clust = clst;            /* Update current cluster */
  92.                 //fp->pad1 = 0;
  93.             }
  94.             
  95. #if _FS_TINY
  96.             if (fp->fs->winsect == fp->dsect && move_window(fp->fs, 0))    /* Write-back sector cache */
  97.                 ABORT(fp->fs, FR_DISK_ERR);
  98. #else
  99.             if (fp->flag & FA__DIRTY) {        /* Write-back sector cache */
  100.                 if (disk_write(fp->fs->drv, fp->buf, fp->dsect, 1) != RES_OK)
  101.                     ABORT(fp->fs, FR_DISK_ERR);
  102.                 fp->flag &= ~FA__DIRTY;
  103.             }
  104. #endif
  105.             sect = clust2sect(fp->fs, fp->clust);    /* Get current sector */
  106.             if (!sect) ABORT(fp->fs, FR_INT_ERR);
  107.             sect += csect;
  108.             cc = btw / SS(fp->fs);            /* When remaining bytes >= sector size, */
  109.             if (cc) {                        /* Write maximum contiguous sectors directly */
  110.                 if (csect + cc > fp->fs->csize)    /* Clip at cluster boundary */
  111.                     cc = fp->fs->csize - csect;
  112.                 if (disk_write(fp->fs->drv, wbuff, sect, (BYTE)cc) != RES_OK)
  113.                     ABORT(fp->fs, FR_DISK_ERR);
  114. #if _FS_TINY
  115.                 if (fp->fs->winsect - sect < cc) {    /* Refill sector cache if it gets invalidated by the direct write */
  116.                     mem_cpy(fp->fs->win, wbuff + ((fp->fs->winsect - sect) * SS(fp->fs)), SS(fp->fs));
  117.                     //logout("tiny");
  118.                     fp->fs->wflag = 0;
  119.                 }
  120. #else
  121.                 if (fp->dsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */
  122.                     mem_cpy(fp->buf, wbuff + ((fp->dsect - sect) * SS(fp->fs)), SS(fp->fs));
  123.                     //logout("no tiny");
  124.                     fp->flag &= ~FA__DIRTY;
  125.                 }
  126. #endif
  127.                 wcnt = SS(fp->fs) * cc;        /* Number of bytes transferred */
  128.                 continue;
  129.             }
  130. #if _FS_TINY
  131.             if (fp->fptr >= fp->fsize) {    /* Avoid silly cache filling at growing edge */
  132.                 if (move_window(fp->fs, 0)) ABORT(fp->fs, FR_DISK_ERR);
  133.                 fp->fs->winsect = sect;
  134.             }
  135. #else
  136.             if (fp->dsect != sect) {        /* Fill sector cache with file data */
  137.                 if (fp->fptr < fp->fsize &&
  138.                     disk_read(fp->fs->drv, fp->buf, sect, 1) != RES_OK)
  139.                         ABORT(fp->fs, FR_DISK_ERR);
  140.             }
  141. #endif
  142.             fp->dsect = sect;
  143.         }
  144.         logout("555555555555555555\r\n");
  145.         wcnt = SS(fp->fs) - (fp->fptr % SS(fp->fs));/* Put partial sector into file I/O buffer */
  146.         if (wcnt > btw) wcnt = btw;
  147. #if _FS_TINY
  148.         if (move_window(fp->fs, fp->dsect))    /* Move sector window */
  149.             ABORT(fp->fs, FR_DISK_ERR);
  150.         mem_cpy(&fp->fs->win[fp->fptr % SS(fp->fs)], wbuff, wcnt);    /* Fit partial sector */
  151.         fp->fs->wflag = 1;
  152. #else
  153.         mem_cpy(&fp->buf[fp->fptr % SS(fp->fs)], wbuff, wcnt);    /* Fit partial sector */
  154.         fp->flag |= FA__DIRTY;
  155. #endif
  156.     }

  157.     if (fp->fptr > fp->fsize)
  158.     fp->fsize = fp->fptr;    /* Update file size if needed */
  159.     fp->flag |= FA__WRITTEN;                        /* Set file change flag */

  160.     LEAVE_FF(fp->fs, FR_OK);
  161. }
  162. //感觉涉及的函数有点多,不知道该贴些啥。。。

Hello astroturfers
点赞  2016-9-7 09:16
引用: flyword 发表于 2016-9-7 08:29
贴出代码看看行不行,我原来出现过只能创建文件,不能读写文件,是因为读写函数有问题。

贴了一段代码不知道能不能看出些什么问题
Hello astroturfers
点赞  2016-9-7 09:16
使用的SPI吗?贴出来那部分代码看看!
点赞  2016-9-7 14:49
引用: 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\r\n");
  9.   /*!< Initialize SD_SPI */
  10.    for(i=0;i<0xf00;i++);
  11.         //logout("SD_LowLevel_Init done\r\n");
  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\r\n");
  23.         //logout("R1 = %d\r\n",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\r\n",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\r\n");
  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\r\n");
  85.     r1 = SD_SendCmd1(SD_CMD_SEND_CSD,0,0x01);//发CMD9命令,读CSD
  86.           logout("gCSD2\r\n");
  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. }

后面的这些也是照着写的

Hello astroturfers
点赞  2016-9-7 18:50
引用: flyword 发表于 2016-9-7 14:49
使用的SPI吗?贴出来那部分代码看看!

就是感觉好像,我进行写操作时,文件没有空间给我往下写的,不知道是不是那里是不是缺了什么操作
Hello astroturfers
点赞  2016-9-7 18:59
引用: flyword 发表于 2016-9-7 14:49
使用的SPI吗?贴出来那部分代码看看!

FR_DISK_ERR,                        /* (1) A hard error occured in the low level disk I/O layer */进入f_write函数会有这个报错的返回值
Hello astroturfers
点赞  2016-9-7 19:13

FR_DISK_ERR,                        /* (1) A hard error occured in the low level disk I/O layer */进入f_write函数会有这个报错的返回值
Hello astroturfers
点赞  2016-9-7 19:13

FR_DISK_ERR,                        /* (1) A hard error occured in the low level disk I/O layer */进入f_write函数会有这个报错的返回值
Hello astroturfers
点赞  2016-9-7 19:13
单步运行,看看哪里有错误!
点赞  2016-9-8 14:29
引用: flyword 发表于 2016-9-8 14:29
单步运行,看看哪里有错误!

9楼贴的代码100那一行会报disk_err
Hello astroturfers
点赞  2016-9-8 14:54
在第一次使用SD卡之前,格式化一下,用f_mkfs函数格式化,在用f_mount挂在SD卡,以后就不用在格式化
点赞  2016-9-8 16:49
引用: qwerghf 发表于 2016-9-8 16:49
在第一次使用SD卡之前,格式化一下,用f_mkfs函数格式化,在用f_mount挂在SD卡,以后就不用在格式化

刚刚特地试了一些,写完之后,tf卡在插到电脑上直接就让格式化。。。
Hello astroturfers
点赞  2016-9-8 16:56
12下一页
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复