2019-07-20 04:56发布
正点原子 发表于 2018-11-22 02:00 103没有双缓冲! 所以,只能单缓冲操作了。
weilexuexi12 发表于 2018-11-21 19:16 原子哥这是我第一次发帖子,希望被翻 我现在在做一个运用STM32F103的V3.5库函数来实现对WM8978音频播放, ...
最多设置5个标签!
你好原子哥,咱们有相关的关于这个 单缓冲操作,但是有双缓冲的那种效果的例程代码吗?我再网上看了看一些代码,但是写进去效果都不好。
下面是一部分代码:
DMA_Double_Buf_Init((uint32_t)databuf2,(uint32_t)databuf,2048); (这是自己编写的双缓冲代码);
void DMA_Double_Buf_Init(u32 addr1,u32 addr2, u32 size)
{
buf_addr1=addr1;
buf_addr2=addr2;
buf_size=size;
buf_n=1;
I2S_Configuration();
DMA_Configuration(addr1,size);
}
//这是IIS配置函数
void I2S_Configuration(void)
{
I2S_InitTypeDef I2S_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
/* Configure SPI2 pins: CK, WS and SD ---------------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Configure SPI2 pins: CK, WS and SD ---------------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Configure SPI2 pins: MCK ---------------------------------*/
#ifdef OPEN_MCK
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
#endif
/*打开I2S时钟*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
SPI_I2S_DeInit(SPI2);
/* I2S peripheral configuration */
I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
#ifdef OPEN_MCK
I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable;
#else
I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
#endif
I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_44k;
I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;//Rx 是在录音模式下使用,Tx 是在播放模式下使用
I2S_Init(SPI2, &I2S_InitStructure);
I2S_Cmd(SPI2, ENABLE);
// SPI_I2S_SendData(SPI2,0xffff);
// SPI_I2S_SendData(SPI2,0x0000);
// SPI_I2S_SendData(SPI2,0xffff);
}
//DMA配置函数
void DMA_Configuration(u32 addr, u32 size)
{
NVIC_InitTypeDef NVIC_InitStructure;
/*open DMA clock*/
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_Cmd(DMA1_Channel5, DISABLE);
I2S_Cmd(SPI2, DISABLE);
DMA_DeInit(DMA1_Channel5);
/* DMA Channel configuration ----------------------------------------------*/
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(0x4000380c);//SPI发送寄存器地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32) addr;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = size;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
//DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
/* Enable SPI DMA Tx request */
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
I2S_Cmd(SPI2, ENABLE);
DMA_Cmd(DMA1_Channel5, ENABLE);
}
这是一个IIS通过DMA双缓冲直接发送数据,下面是DMA中断:
void DMA1_Channel5_IRQHandler(void)
{
if(DMA_GetITStatus(DMA1_IT_TC5) != RESET)
{
DMA_ClearITPendingBit(DMA1_IT_TC5);
DMA_Double_Buf_Change();
}
}
void DMA_Double_Buf_Change(void)
{
DMA1_Channel5->CCR &= (uint16_t)(~DMA_CCR1_EN);
DMA1_Channel5->CNDTR = buf_size;
if(buf_n==1)
{
DMA1_Channel5->CMAR = buf_addr2;
buf_n=2;
}
else
{
DMA1_Channel5->CMAR = buf_addr1;
buf_n=1;
}
DMA1_Channel5->CCR |= DMA_CCR1_EN;
buf_fin=1;
LED1=!LED1;
}
103没有双缓冲!
所以,只能单缓冲操作了。
一周热门 更多>