请选择 进入手机版 | 继续访问电脑版
搜索
查看: 3349|回复: 3

[已解决] STM32L151RDT6 SDIO读写SD卡 FIFO下溢错误,不知是什么原因

[复制链接]

该用户从未签到

9

主题

21

帖子

4

蝴蝶豆

中级会员

最后登录
2020-6-2
发表于 2018-10-23 10:01:09 | 显示全部楼层 |阅读模式
系统介绍:
1.MCU :STM32L151RDT6
2.时钟配置: 外部晶振12M ,PLL分频得到48M给SDIO适配器使用,PLL分频得到系统主时钟32M SDIO外设 PCLK2时钟32M
3.SD_CK上电初始化时400KHz,初始化完成后分频改成24MHz。
SD原理图:

问题:
SD卡上电初始化没有问题,能够读取卡的CID,块的大小等信息。在测试块写入数据时提示SD_TX_UNDERRUN 错误,也就是FIFO下溢错误。
我尝试减小时钟频率的话出现SD_DATA_CRC_FAIL错误,也就是数据块CRC错误。不知什么原因造成的。我是按照原子STM32F407SD卡的例子改的。
  1. SD_Error SD_WriteBlock(u8 *buf,long long addr,  u16 blksize)
  2. {
  3.         SD_Error errorstatus = SD_OK;
  4.         
  5.         u8  power=0,cardstate=0;
  6.         
  7.         u32 timeout=0,bytestransferred=0;
  8.         
  9.         u32 cardstatus=0,count=0,restwords=0;
  10.         
  11.         u32        tlen=blksize;   //总长度
  12.         
  13.         u32*tempbuff=(u32*)buf;                                       
  14.         
  15.          if(buf==NULL)return SD_INVALID_PARAMETER;//参数错误
  16.         
  17.   SDIO->DCTRL=0x0;                                                        //数据寄存器清零关DMA
  18.         
  19.         SDIO_DataInitStructure.SDIO_DataBlockSize= 0;//清除DPSM状态机配置
  20.         SDIO_DataInitStructure.SDIO_DataLength= 0 ;
  21.         SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
  22.         SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
  23.         SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
  24.         SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
  25.   SDIO_DataConfig(&SDIO_DataInitStructure);
  26.         
  27.         
  28.         if(SDIO->RESP1&SD_CARD_LOCKED)return SD_LOCK_UNLOCK_FAILED;//卡锁了
  29.          if(CardType==SDIO_HIGH_CAPACITY_SD_CARD)        //大容量卡
  30.         {
  31.                 blksize=512;
  32.                 addr/=512;
  33.         }   
  34.         if((blksize>0)&&(blksize<=2048)&&((blksize&(blksize-1))==0))
  35.         {
  36.                 power=convert_from_bytes_to_power_of_two(blksize);        
  37.                
  38.                 SDIO_CmdInitStructure.SDIO_Argument = blksize;//发送CMD16+设置数据长度 blksize,短响应
  39.                 SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN;
  40.                 SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  41.                 SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  42.                 SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  43.                 SDIO_SendCommand(&SDIO_CmdInitStructure);        
  44.                
  45.                 errorstatus=CmdResp1Error(SD_CMD_SET_BLOCKLEN);        //等待R1响应
  46.                
  47.                 if(errorstatus!=SD_OK)return errorstatus;           //这里返回SD_OK
  48.                
  49.         }else return SD_INVALID_PARAMETER;        
  50.         
  51.                         SDIO_CmdInitStructure.SDIO_Argument = (u32)RCA<<16;//发送CMD13,查询卡的状态,短响应
  52.                   SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_STATUS;
  53.                         SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  54.                         SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  55.                         SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  56.                         SDIO_SendCommand(&SDIO_CmdInitStructure);        

  57.           errorstatus=CmdResp1Error(SD_CMD_SEND_STATUS);                //等待R1响应
  58.         
  59.         if(errorstatus!=SD_OK)return errorstatus;            //这里返回SD_OK
  60.         cardstatus=SDIO->RESP1;                                                                                                         
  61.         timeout=SD_DATATIMEOUT;
  62.            while(((cardstatus&0x00000100)==0)&&(timeout>0))         //¼ì²éREADY_FOR_DATAλÊÇ·ñÖÃλ
  63.         {
  64. timeout--;  
  65.                
  66.                 SDIO_CmdInitStructure.SDIO_Argument = (u32)RCA<<16;//发送CMD13,查询卡的状态,短响应
  67.                 SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SEND_STATUS;
  68.                 SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  69.                 SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  70.                 SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  71.                 SDIO_SendCommand(&SDIO_CmdInitStructure);        
  72.                
  73.                 errorstatus=CmdResp1Error(SD_CMD_SEND_STATUS);        //等待R1响应
  74.                
  75.                 if(errorstatus!=SD_OK)return errorstatus;               
  76.                
  77.                 cardstatus=SDIO->RESP1;                                                                                                         
  78.         }
  79.         if(timeout==0)return SD_ERROR;

  80.                         SDIO_CmdInitStructure.SDIO_Argument = addr;//发送CMD24,写单块指令,短响应
  81.                         SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_WRITE_SINGLE_BLOCK;
  82.                         SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
  83.                         SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
  84.                         SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
  85.                         SDIO_SendCommand(&SDIO_CmdInitStructure);        
  86.         
  87.         errorstatus=CmdResp1Error(SD_CMD_WRITE_SINGLE_BLOCK);//等待R1响应
  88.         
  89.         if(errorstatus!=SD_OK)return errorstatus;//这里反会SD_OK
  90.         
  91.         StopCondition=0;                                                                        //单块写不需要发送停止传输指令

  92.         SDIO_DataInitStructure.SDIO_DataBlockSize= power<<4; ;        //blksize, 控制器到卡
  93.         SDIO_DataInitStructure.SDIO_DataLength= blksize ;
  94.         SDIO_DataInitStructure.SDIO_DataTimeOut=SD_DATATIMEOUT ;
  95.         SDIO_DataInitStructure.SDIO_DPSM=SDIO_DPSM_Enable;
  96.         SDIO_DataInitStructure.SDIO_TransferDir=SDIO_TransferDir_ToCard;
  97.         SDIO_DataInitStructure.SDIO_TransferMode=SDIO_TransferMode_Block;
  98.   SDIO_DataConfig(&SDIO_DataInitStructure);

  99.         timeout=SDIO_DATATIMEOUT;
  100.                
  101.   if(errorstatus!=SD_OK)return errorstatus;           //这里返回OK
复制代码


Snipaste_2018-10-23_09-17-35.png
回复

使用道具 举报

  • TA的每日心情
    奋斗
    2021-4-15 11:47
  • 签到天数: 537 天

    [LV.9]

    29

    主题

    2176

    帖子

    127

    蝴蝶豆

    论坛元老

    最后登录
    2023-8-27
    发表于 2018-10-23 10:57:03 | 显示全部楼层
    Underrun(underflow)
          In computing, buffer underrun or buffer underflow is a state occurring when a buffer used to communicate between two devices or processes is fed with data at a lower speed than the data is being read from it. This requires the program or device reading from the buffer to pause its processing while the buffer refills. This can cause undesired and sometimes serious side effects, since the data being buffered is generally not suited to stop-start access of this kind.

    既然是TX Underrun,你把发送的频率提高一些试试?

    评分

    参与人数 1蝴蝶豆 +3 收起 理由
    STMCU + 3

    查看全部评分

    回复 支持 反对

    使用道具 举报

    该用户从未签到

    9

    主题

    21

    帖子

    4

    蝴蝶豆

    中级会员

    最后登录
    2020-6-2
     楼主| 发表于 2018-10-23 11:43:30 | 显示全部楼层
    stm1024 发表于 2018-10-23 10:57
    Underrun(underflow)
          In computing, buffer underrun or buffer underflow is a state occurring whe ...

    24Mhz已经是SD_CK的最大时钟了 我用407的板子调试是没问题的  是不是这块芯片的SDIO硬件有问题
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    9

    主题

    21

    帖子

    4

    蝴蝶豆

    中级会员

    最后登录
    2020-6-2
     楼主| 发表于 2018-10-24 09:14:11 | 显示全部楼层
    wanghailong1314 发表于 2018-10-23 11:43
    24Mhz已经是SD_CK的最大时钟了 我用407的板子调试是没问题的  是不是这块芯片的SDIO硬件有问题 ...

    对于SD卡FIFO下溢错误 解决办法1.降低SD_CK的频率 2.开启硬件流控制。
    对于SD_DATA_CRC_FAIL错误,我调试的时候先让板子用1线模式调试能够正确写进数据,改成4线模式就出现SD_DATA_CRC_FAIL错误,那问题就是配置4线的程序有问题。后来我使用了官网例程的配置4线模式函数,降低时钟频率,运行SD_OK了。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

    GMT+8, 2024-3-29 14:15 , Processed in 1.200168 second(s), 40 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表