|
想在MP3播放例程中将SPI改为用DMA来控制发送,但是DMA配置一直不成功,麻烦版主帮忙看下:
void bsp_CfgSPIForVS1053B(void)
{
    SPI_InitTypeDef  SPI_InitStructure;
    /* 打开SPI时钟 */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
    
        /* 使能  DMA clock */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
    /* SPI1 配置 */
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;    /* 选择2线全双工模式 */
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;        /* CPU的SPI作为主设备 */
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;    /* 8个数据 */
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;            /* CLK引脚空闲状态电平 = 0 */
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;        /* 数据采样在第1个边沿(上升沿) */
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;              /* 软件控制片选 */
    /*
        由于SPI1的时钟源是84M, SPI3的时钟源是42M。为了获得更快的速度,软件上选择SPI1。
        pdf page=23 vs1053B SPI输入时钟 4个CLKI cycles; CLKI = 12.288M
        因此最大SPI时钟 = 12.288 / 4 = 3.072MHz
        需要 32分频
    */
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;    /* 最高位先传输 */
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(SPI1,&SPI_InitStructure);
    SPI_Cmd(SPI1, DISABLE);            /* 先禁止SPI  */
    SPI_Cmd(SPI1, ENABLE);            /* 使能SPI  */
    
    SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
}
void SPI1_DMA_TxConfig(uint32_t *BufferDST, uint32_t BufferSize)
{
    DMA_InitTypeDef DMA_InitStructure;
    
    //DMA_ClearFlag(SD_SDIO_DMA_STREAM, SD_SDIO_DMA_FLAG_FEIF | SD_SDIO_DMA_FLAG_DMEIF | SD_SDIO_DMA_FLAG_TEIF | SD_SDIO_DMA_FLAG_HTIF | SD_SDIO_DMA_FLAG_TCIF);
//    DMA_ClearFlag(SPI_SDIO_DMA_STREAM, SPI_SDIO_DMA_FLAG_FEIF | SPI_SDIO_DMA_FLAG_DMEIF
//                                     | SPI_SDIO_DMA_FLAG_TEIF | SPI_SDIO_DMA_FLAG_HTIF | SPI_SDIO_DMA_FLAG_TCIF);
    
    /* DMA2 Stream3  or Stream6 disable */
    DMA_Cmd(SPI_SDIO_DMA_STREAM, DISABLE);
    
    while (DMA_GetCmdStatus(SPI_SDIO_DMA_STREAM) != DISABLE)
    {
    }
    DMA_InitStructure.DMA_BufferSize = BufferSize;/* 配置DMA大小 */
     DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;                  /* 在这个程序里面使能或者禁止都可以的 */
     DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;          /* 设置阀值 */
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single ;           /* 设置内存为单字节突发模式 */
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;        /* 设置内存数据的位宽是字节 */
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                /* 使能地址自增 */
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                          /* 设置DMA是正常模式 */
    DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t) (&(SPI1->DR)) ; /* 设置外设地址 */
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;    /* 设置外设为单字节突发模式 */
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;; /* 设置外设数据的位宽是字节 */
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;/* 禁止外设地址自增 */
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;             /* 设置优先级 */
    
    /* 配置 TX DMA */
    DMA_InitStructure.DMA_Channel = SPI_SDIO_DMA_CHANNEL ;      /* 配置发送通道 */
    DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral ;     /* 设置从内存到外设 */
    DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)BufferDST ; /* 设置内存地址 */
    DMA_Init(SPI_SDIO_DMA_STREAM,&DMA_InitStructure);
    
    DMA_FlowControllerConfig(SPI_SDIO_DMA_STREAM, DMA_FlowCtrl_Peripheral);
    /* DMA2 Stream3 enable */
    DMA_Cmd(SPI_SDIO_DMA_STREAM, ENABLE);
    
    while (DMA_GetCmdStatus(SPI_SDIO_DMA_STREAM) != ENABLE);
}
操作控制部分:
static uint8_t Mp3Pro(void)
{
    uint32_t bw,i;
    char buf[32];
    /* 如果VS1003空闲,则写入新的数据 */
    if (vs1053_ReqNewData())
    {
        f_read(&g_Mp3File, &buf, 32, &bw);
        if (bw <= 0)
        {
            return 1;
        }
        /* 计算进度 */
        g_tMP3.uiProgress += bw;
        vs1053_PreWriteData();    /* 写数据准备,设置好片选 */
//        for (i = 0; i < bw; i++)
//        {
//            vs1053_WriteData(buf);
//        }
        SPI1_DMA_TxConfig((uint32_t *)buf, 32);
        GPIOA->BSRRH = GPIO_Pin_5;
        while (DMA_GetFlagStatus(SPI_SDIO_DMA_STREAM,SPI_SDIO_DMA_FLAG_TCIF)==RESET);
        /* 清除DMA传输完成标志 */
        DMA_ClearFlag(SPI_SDIO_DMA_STREAM,SPI_SDIO_DMA_FLAG_TCIF);
        GPIOA->BSRRL = GPIO_Pin_5;
    }
    return 0;
}
V5-121_VS1053B MP3硬件解码器例程(修改).zip
(14.33 MB, 下载次数: 152)
上传附件,版主有空帮忙看下,非常感谢 |
|