<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> STM32 >> 瀏覽文章

        STM32f407在調試SDIO中的一些問題

        作者:嵌入式高手   來源:會員上傳   點擊數:  更新時間:2014年05月20日   【字體:

        我之前也調了3天,不知道為什么不行,遇到了一些問題,但今天都沒有問題了,很穩定,和大家交流一下。

        1.首先,一定要確定你的卡是好的,我這個就浪費了我一天的時間,你用筆記本看看是不是能識別和讀寫這個大卡,不要把小卡拿出來試試放回到卡套里,因為我就是卡套壞了。
        2.基于官方給的這兩個文件來修改的話,首先要注意引腳是否需要修改,主要是有個檢測引腳可能會修改。
         
         3.在剛加入這兩個文件后,我也遇到了一些提示錯誤,但是現在都不見了,我重新加入新的沒有改動的這兩個文件,也不會提示有問題,我是想說,原廠文件應該 是沒有問題的,網上說的會提示的錯誤我也不知道為什么會有,我的非常穩定,4bit和25mhz,杠杠的,但是可以給出以下的建議,防止一些錯誤。
        4.首先是初始化的時候,網上說應該在上電之后加入74clk時鐘,其實可以不加,只要你上電之后初始化其他東西的時間足夠,我是沒有加,也沒有任何問題。
        5.然后就是在讀寫的時候可能有人遇到crc校驗不正;蛘邲]有檢測到起始信號,給出以下提示:
        • 因為讀寫塊函數調用了DMA的配置函數SD_LowLevel_DMA_TxConfig和SD_LowLevel_DMA_RxConfig,這兩個函數中值得注意的是,SDDMA_InitStructure.DMA_BufferSize = xxx;這里的xxx其實可以為任意值,因為后面會有一句 DMA_FlowControllerConfig(SD_SDIO_DMA_STREAM, DMA_FlowCtrl_Peripheral);這個是硬件流控制,不論你設置多少的數,都會在初始化之后成為0xffff,詳情看dma的硬件流部分。
        • SDIO也有一個硬件流,勸不要打開,因為打開之后會出現SDIO還需要數據的時候DMA已經停止工作了,具體原因不詳。
        • 官方給的讀寫塊函數,里面最好把DMA的使能還有SDIO的使能放在SDIO_DataInitStructure配置玩之后,安全點。舉例如下,注意顏色部分是改動的。

         

        SD_Error SD_WriteBlock(uint8_t *writebuff, uint64_t WriteAddr, uint16_t BlockSize)
        {
          SD_Error errorstatus = SD_OK;

        #if defined (SD_POLLING_MODE)
          uint32_t bytestransferred = 0, count = 0, restwords = 0;
          uint32_t *tempbuff = (uint32_t *)writebuff;
        #endif

          TransferError = SD_OK;
          TransferEnd = 0;
          StopCondition = 0;
          SDIO->DCTRL = 0x0;


          if (CardType == SDIO_HIGH_CAPACITY_SD_CARD)
          {
            BlockSize = 512;
            WriteAddr /= 512;
          }

         
          SDIO_CmdInitStructure.SDIO_Argument = (uint32_t) BlockSize;
          SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_SET_BLOCKLEN;
          SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
          SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
          SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
          SDIO_SendCommand(&SDIO_CmdInitStructure);

          errorstatus = CmdResp1Error(SD_CMD_SET_BLOCKLEN);

          if (SD_OK != errorstatus)
          {
            return(errorstatus);
          }

         
          SDIO_CmdInitStructure.SDIO_Argument = (uint32_t)WriteAddr;
          SDIO_CmdInitStructure.SDIO_CmdIndex = SD_CMD_WRITE_SINGLE_BLOCK;
          SDIO_CmdInitStructure.SDIO_Response = SDIO_Response_Short;
          SDIO_CmdInitStructure.SDIO_Wait = SDIO_Wait_No;
          SDIO_CmdInitStructure.SDIO_CPSM = SDIO_CPSM_Enable;
          SDIO_SendCommand(&SDIO_CmdInitStructure);

          errorstatus = CmdResp1Error(SD_CMD_WRITE_SINGLE_BLOCK);

          if (errorstatus != SD_OK)
          {
            return(errorstatus);
          }

          SDIO_DataInitStructure.SDIO_DataTimeOut = SD_DATATIMEOUT;
          SDIO_DataInitStructure.SDIO_DataLength = BlockSize;
          SDIO_DataInitStructure.SDIO_DataBlockSize = (uint32_t) 9 << 4;
          SDIO_DataInitStructure.SDIO_TransferDir = SDIO_TransferDir_ToCard;
          SDIO_DataInitStructure.SDIO_TransferMode = SDIO_TransferMode_Block;
          SDIO_DataInitStructure.SDIO_DPSM = SDIO_DPSM_Enable;
          SDIO_DataConfig(&SDIO_DataInitStructure);

         
        #if defined (SD_POLLING_MODE)
          while (!(SDIO->STA & (SDIO_FLAG_DBCKEND | SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_STBITERR)))
          {
            if (SDIO_GetFlagStatus(SDIO_FLAG_TXFIFOHE) != RESET)
            {
              if ((512 - bytestransferred) < 32)
              {
                restwords = ((512 - bytestransferred) % 4 == 0) ? ((512 - bytestransferred) / 4) : (( 512 -  bytestransferred) / 4 + 1);
                for (count = 0; count < restwords; count++, tempbuff++, bytestransferred += 4)
                {
                  SDIO_WriteData(*tempbuff);
                }
              }
              else
              {
                for (count = 0; count < 8; count++)
                {
                  SDIO_WriteData(*(tempbuff + count));
                }
                tempbuff += 8;
                bytestransferred += 32;
              }
            }
          }
          if (SDIO_GetFlagStatus(SDIO_FLAG_DTIMEOUT) != RESET)
          {
            SDIO_ClearFlag(SDIO_FLAG_DTIMEOUT);
            errorstatus = SD_DATA_TIMEOUT;
            return(errorstatus);
          }
          else if (SDIO_GetFlagStatus(SDIO_FLAG_DCRCFAIL) != RESET)
          {
            SDIO_ClearFlag(SDIO_FLAG_DCRCFAIL);
            errorstatus = SD_DATA_CRC_FAIL;
            return(errorstatus);
          }
          else if (SDIO_GetFlagStatus(SDIO_FLAG_TXUNDERR) != RESET)
          {
            SDIO_ClearFlag(SDIO_FLAG_TXUNDERR);
            errorstatus = SD_TX_UNDERRUN;
            return(errorstatus);
          }
          else if (SDIO_GetFlagStatus(SDIO_FLAG_STBITERR) != RESET)
          {
            SDIO_ClearFlag(SDIO_FLAG_STBITERR);
            errorstatus = SD_START_BIT_ERR;
            return(errorstatus);
          }
        #elif defined (SD_DMA_MODE)
          SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_RXOVERR | SDIO_IT_STBITERR, ENABLE);
         SD_LowLevel_DMA_TxConfig((uint32_t *)writebuff, BlockSize);
         SDIO_DMACmd(ENABLE);
        #endif

         
          return(errorstatus);
        }

        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮