打印

SDMMC DMA FATFS读取SD卡

[复制链接]
301|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
roucun|  楼主 | 2018-7-10 16:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
u8 SD_Init(void)
{
    u8 SD_Error;
   
   //³õʼ»¯Ê±µÄʱÖÓ²»ÄÜ´óÓÚ400KHZ
    SDCARD_Handler.Instance = SDMMC1;
    SDCARD_Handler.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;          //ÉÏÉýÑØ     
    SDCARD_Handler.Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE;     //²»Ê¹ÓÃbypassģʽ£¬Ö±½ÓÓÃHCLK½øÐзÖƵµÃµ½SDIO_CK
    SDCARD_Handler.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;    //¿ÕÏÐʱ²»¹Ø±ÕʱÖÓµçÔ´
    SDCARD_Handler.Init.BusWide = SDMMC_BUS_WIDE_1B;                        //1λÊý¾ÝÏß
    SDCARD_Handler.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;//¹Ø±ÕÓ²¼þÁ÷¿Ø
    SDCARD_Handler.Init.ClockDiv = 4;//SD´«ÊäʱÖÓƵÂÊ×î´ó25MHZ SDMMC_INIT_CLK_DIV SDMMC_TRANSFER_CLK_DIV
   SD_Error = HAL_SD_Init(&SDCARD_Handler);
   //printf("
HAL_SD_Init:%d",SD_Error);
   if(SD_Error != HAL_OK) return 1;
  
    SD_Error = HAL_SD_ConfigWideBusOperation(&SDCARD_Handler,SDMMC_BUS_WIDE_4B);//ʹÄÜ¿í×ÜÏßģʽ
    //printf("
HAL_SD_ConfigWideBusOperation:%d",SD_Error);
    if(SD_Error != HAL_OK) return 2;
   
   SD_Error = SD_GetCardInfo(&SDCardInfo);
   //printf("
SD_GetCardInfo:%d",SD_Error);
    if(SD_Error != HAL_OK) return 3;
   
    return 0;
}
//SDMMCµ×²ãÇý¶¯£¬Ê±ÖÓʹÄÜ£¬Òý½ÅÅäÖã¬DMAÅäÖÃ
//´Ëº¯Êý»á±»HAL_SD_Init()µ÷ÓÃ
//hsd:SD¿¨¾ä±ú
void HAL_SD_MspInit(SD_HandleTypeDef *hsd)
{
    GPIO_InitTypeDef GPIO_Initure;

    __HAL_RCC_SDMMC1_CLK_ENABLE();//ʹÄÜSDMMCʱÖÓ
    __HAL_RCC_DMA2_CLK_ENABLE();    //ʹÄÜDMA2ʱÖÓ
    __HAL_RCC_GPIOC_CLK_ENABLE();   //ʹÄÜGPIOCʱÖÓ
    __HAL_RCC_GPIOD_CLK_ENABLE();   //ʹÄÜGPIODʱÖÓ
   
   //PC8,9,10,11,12
    GPIO_Initure.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
    GPIO_Initure.Mode = GPIO_MODE_AF_PP;      //ÍÆÍ츴ÓÃ
    GPIO_Initure.Pull = GPIO_PULLUP;          //ÉÏÀ
    GPIO_Initure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;     //¸ßËÙ
    GPIO_Initure.Alternate = GPIO_AF12_SDMMC1;//GPIO_AF12_SDIO;  //¸´ÓÃΪSDIO
    HAL_GPIO_Init(GPIOC,&GPIO_Initure);     //³õʼ»¯
    //PD2
   GPIO_Initure.Pin = GPIO_PIN_2;
    GPIO_Initure.Mode = GPIO_MODE_AF_PP;
    GPIO_Initure.Pull = GPIO_PULLUP;
    GPIO_Initure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_Initure.Alternate = GPIO_AF12_SDMMC1;           
    HAL_GPIO_Init(GPIOD,&GPIO_Initure);     //³õʼ»¯

#if (SD_DMA_MODE == 1)                        //ʹÓÃDMAģʽ
    HAL_NVIC_SetPriority(DMA2_Channel4_IRQn, 2, 0);  //·¢ËÍDMAÖжÏÓÅÏȼ¶
    HAL_NVIC_EnableIRQ(DMA2_Channel4_IRQn);
  
    HAL_NVIC_SetPriority(DMA2_Channel5_IRQn, 2, 0);  //½ÓÊÕDMAÖжÏÓÅÏȼ¶
    HAL_NVIC_EnableIRQ(DMA2_Channel5_IRQn);
  HAL_NVIC_SetPriority(SDMMC1_IRQn,1,0);  //ÅäÖÃSDMMC1Öжϣ¬ÇÀÕ¼ÓÅÏȼ¶2£¬×ÓÓÅÏȼ¶0
    HAL_NVIC_EnableIRQ(SDMMC1_IRQn);        //ʹÄÜSDMMC1ÖжÏ
  
    SDRxDMAHandler.Instance=DMA2_Channel4;
    SDRxDMAHandler.Init.Request=DMA_REQUEST_7;
    SDRxDMAHandler.Init.Direction=DMA_PERIPH_TO_MEMORY;
    SDRxDMAHandler.Init.PeriphInc=DMA_PINC_DISABLE;
    SDRxDMAHandler.Init.MemInc=DMA_MINC_ENABLE;
    SDRxDMAHandler.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;
    SDRxDMAHandler.Init.MemDataAlignment=DMA_PDATAALIGN_BYTE;// DMA_MDATAALIGN_BYTE  DMA_MDATAALIGN_WORD
    SDRxDMAHandler.Init.Mode = DMA_NORMAL;//DMA_NORMAL;DMA_CIRCULAR
    SDRxDMAHandler.Init.Priority = DMA_PRIORITY_LOW;
    HAL_DMA_Init(&SDRxDMAHandler);   
    __HAL_LINKDMA(hsd, hdmarx, SDRxDMAHandler); //½«½ÓÊÕDMAºÍSD¿¨µÄ·¢ËÍDMAÁ¬½ÓÆðÀ´   
    SDTxDMAHandler.Instance=DMA2_Channel5;
    SDTxDMAHandler.Init.Request=DMA_REQUEST_7;
    SDTxDMAHandler.Init.Direction=DMA_MEMORY_TO_PERIPH;
    SDTxDMAHandler.Init.PeriphInc=DMA_PINC_DISABLE;
    SDTxDMAHandler.Init.MemInc=DMA_MINC_ENABLE;
    SDTxDMAHandler.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;
    SDTxDMAHandler.Init.MemDataAlignment=DMA_PDATAALIGN_BYTE;
    SDTxDMAHandler.Init.Mode=DMA_NORMAL;
    SDTxDMAHandler.Init.Priority=DMA_PRIORITY_LOW;
    HAL_DMA_Init(&SDTxDMAHandler);  
    __HAL_LINKDMA(hsd, hdmatx, SDTxDMAHandler);//½«·¢ËÍDMAºÍSD¿¨µÄ·¢ËÍDMAÁ¬½ÓÆðÀ´   
#endif
}
//µÃµ½¿¨ÐÅÏ¢
//cardinfo:¿¨ÐÅÏ¢´æ´¢Çø
//·µ»ØÖµ:´íÎó״̬
u8 SD_GetCardInfo(HAL_SD_CardInfoTypeDef *cardinfo)
{
    u8 sta;
    sta = HAL_SD_GetCardInfo(&SDCARD_Handler,cardinfo);
    return sta;
}
#if (SD_DMA_MODE == 1)        //DMAģʽ
/**
  * @brief Configure the DMA to receive data from the SD card
  * @retval
  *  HAL_ERROR or HAL_OK
  */
HAL_StatusTypeDef SD_DMAConfigRx(SD_HandleTypeDef *hsd)
{
  HAL_StatusTypeDef status = HAL_ERROR;
  
  /* Configure DMA Rx parameters */
  SDRxDMAHandler.Instance = DMA2_Channel4;
SDRxDMAHandler.Init.Request = DMA_REQUEST_7;
SDRxDMAHandler.Init.Direction = DMA_PERIPH_TO_MEMORY;
SDRxDMAHandler.Init.PeriphInc = DMA_PINC_DISABLE;
SDRxDMAHandler.Init.MemInc = DMA_MINC_ENABLE;
SDRxDMAHandler.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
SDRxDMAHandler.Init.MemDataAlignment = DMA_PDATAALIGN_BYTE;
SDRxDMAHandler.Init.Mode = DMA_NORMAL;
  SDRxDMAHandler.Init.Priority = DMA_PRIORITY_LOW;
  /* Associate the DMA handle */
  __HAL_LINKDMA(hsd,hdmarx,SDRxDMAHandler);
  /* Stop any ongoing transfer and reset the state*/
  HAL_DMA_Abort(&SDRxDMAHandler);
  
  /* Deinitialize the Channel for new transfer */
  HAL_DMA_DeInit(&SDTxDMAHandler);//????!!!DeInit???????!!!
  /* Configure the DMA Channel */
  status = HAL_DMA_Init(&SDRxDMAHandler);
   
  return (status);
}
/**
  * @brief Configure the DMA to transmit data to the SD card
  * @retval
  *  HAL_ERROR or HAL_OK
  */
HAL_StatusTypeDef SD_DMAConfigTx(SD_HandleTypeDef *hsd)
{
  HAL_StatusTypeDef status;
  
  /* SDMMC1_TX Init */
SDTxDMAHandler.Instance = DMA2_Channel5;
SDTxDMAHandler.Init.Request = DMA_REQUEST_7;
SDTxDMAHandler.Init.Direction = DMA_MEMORY_TO_PERIPH;
SDTxDMAHandler.Init.PeriphInc = DMA_PINC_DISABLE;
SDTxDMAHandler.Init.MemInc = DMA_MINC_ENABLE;
SDTxDMAHandler.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
SDTxDMAHandler.Init.MemDataAlignment = DMA_PDATAALIGN_BYTE;
SDTxDMAHandler.Init.Mode = DMA_NORMAL;//??NORMAL??????,???
SDTxDMAHandler.Init.Priority = DMA_PRIORITY_LOW;
  /* Associate the DMA handle */
  __HAL_LINKDMA(hsd, hdmatx, SDTxDMAHandler);
  
  /* Stop any ongoing transfer and reset the state*/
  HAL_DMA_Abort(&SDTxDMAHandler);
  
  /* Deinitialize the Channel for new transfer */
  HAL_DMA_DeInit(&SDRxDMAHandler);  //????!!!DeInit???????!!!
  
  /* Configure the DMA Channel */
  status = HAL_DMA_Init(&SDTxDMAHandler);
  return (status);
}
//ͨ¹ýDMA¶ÁÈ¡SD¿¨Ò»¸öÉÈÇø
//buf:¶ÁÊý¾Ý»º´æÇø
//sector:ÉÈÇøµØÖ·
//blocksize:ÉÈÇø´óС(Ò»°ã¶¼ÊÇ512×Ö½Ú)
//cnt:ÉÈÇø¸öÊý
//·µ»ØÖµ:´íÎó״̬;0,Õý³£;ÆäËû,´íÎó´úÂë;
u8 SD_ReadBlocks_DMA(uint8_t *buf,uint64_t sector,uint32_t cnt)
{
    u8 sd_state = HAL_OK;

  if(SD_DMAConfigRx(&SDCARD_Handler) != HAL_OK)
  {
    return HAL_ERROR;
  }
    if(HAL_SD_ReadBlocks_DMA(&SDCARD_Handler,buf,sector,cnt) != HAL_OK)//¶ÁÈ¡³É¹¦
    {
    sd_state = HAL_ERROR;
    }
    return sd_state;
}
//дSD¿¨
//buf:дÊý¾Ý»º´æÇø
//sector:ÉÈÇøµØÖ·
//blocksize:ÉÈÇø´óС(Ò»°ã¶¼ÊÇ512×Ö½Ú)
//cnt:ÉÈÇø¸öÊý
//·µ»ØÖµ:´íÎó״̬;0,Õý³£;ÆäËû,´íÎó´úÂë;
u8 SD_WriteBlocks_DMA(uint8_t *buf,uint64_t sector,uint32_t cnt)
{
    u8 sd_state = HAL_OK;

  if(SD_DMAConfigTx(&SDCARD_Handler) != HAL_OK)
  {
    return HAL_ERROR;
  }
    if(HAL_SD_WriteBlocks_DMA(&SDCARD_Handler,buf,sector,cnt) != HAL_OK)//д³É¹¦
    {     
       sd_state = HAL_ERROR;
    }
    return sd_state;
}
//¶ÁSD¿¨
//buf:¶ÁÊý¾Ý»º´æÇø
//sector:ÉÈÇøµØÖ·
//cnt:ÉÈÇø¸öÊý
//·µ»ØÖµ:´íÎó״̬;0,Õý³£;ÆäËû,´íÎó´úÂë;
u8 SD_ReadDisk(u8* buf,u32 sector,u32 cnt)
{
    u8 sta=HAL_OK;
    long long lsector=sector;
    u8 n;
    //if(SDCardInfo.CardType != CARD_SDSC)lsector<<=9;
    if((u32)buf%4!=0)
    {
        for(n=0;n<cnt;n++)
        {
            //sta=SD_ReadBlocks_DMA((uint8_t*)SDIO_DATA_BUFFER,lsector+512*n,1);
      sta=SD_ReadBlocks_DMA(SDIO_DATA_BUFFER,lsector+n,1);
            memcpy(buf,SDIO_DATA_BUFFER,512);
            buf+=512;
        }
    }else
    {
        sta=SD_ReadBlocks_DMA(buf,lsector, cnt);
    }
    return sta;
}  
//дSD¿¨
//buf:дÊý¾Ý»º´æÇø
//sector:ÉÈÇøµØÖ·
//cnt:ÉÈÇø¸öÊý
//·µ»ØÖµ:´íÎó״̬;0,Õý³£;ÆäËû,´íÎó´úÂë;
u8 SD_WriteDisk(u8 *buf,u32 sector,u32 cnt)
{   
    u8 sta=HAL_OK;
    long long lsector=sector;
    u8 n;
    //if(SDCardInfo.CardType != CARD_SDSC)lsector<<=9;
    if((u32)buf%4!=0)
    {
        for(n=0;n<cnt;n++)
        {
            //sta=SD_WriteBlocks_DMA((uint8_t*)SDIO_DATA_BUFFER,lsector+512*n,1);//µ¥¸ösectorµÄд²Ù×÷
      sta=SD_WriteBlocks_DMA(SDIO_DATA_BUFFER,lsector+n,1);//µ¥¸ösectorµÄд²Ù×÷
       memcpy(SDIO_DATA_BUFFER,buf,512);
            buf+=512;
        }
    }else
    {
        sta=SD_WriteBlocks_DMA(buf,lsector,cnt);//¶à¸ösectorµÄд²Ù×
    }
    return sta;
}
//SDMMC1ÖжϷþÎñº¯Êý
void SDMMC1_IRQHandler(void)
{
    HAL_SD_IRQHandler(&SDCARD_Handler);
}
void DMA2_Channel4_IRQHandler(void)
{
    HAL_DMA_IRQHandler(&SDRxDMAHandler);
  //HAL_DMA_IRQHandler(SDCARD_Handler.hdmarx);
}
void DMA2_Channel5_IRQHandler(void)
{
    HAL_DMA_IRQHandler(&SDTxDMAHandler);
  //HAL_DMA_IRQHandler(SDCARD_Handler.hdmatx);
}

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

421

主题

446

帖子

0

粉丝