|
楼主 |
发表于 2018-12-29 11:12:57
|
显示全部楼层
录音的时候,改成发送DMA使用循环模式,接收DMA用双缓冲,但是还是没跑起来,下面是发送和接收DMA的配置,帮忙看下有没有问题;
DMA配置
void init_codec_adc(void)
{
DMA_InitTypeDef DMA_InitStructure;
//
codec_rx_tem = &codec_buf[0][0];
codec_rx_tem = &codec_buf[1][0];
//DMA1时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);
//通道0,流3指向I2S_RX
DMA_DeInit(DMA1_Stream3);
/* 配置 DMA Stream */
//通道0 SPI2_RX通道
DMA_InitStructure.DMA_Channel = DMA_Channel_3;
//外设地址为:(u32)&SPI2->DR
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&I2S2ext->DR;
//DMA 存储器0地址 //此处可以不配置
DMA_InitStructure.DMA_Memory0BaseAddr = (u32)codec_rx_tem;
//外设到存储器模式
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
//
//数据传输量//100ms
DMA_InitStructure.DMA_BufferSize = 3200; //3200或者1600
//外设非增量模式
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
//存储器增量模式
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
//外设数据长度:16位
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
//存储器数据长度:16位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
//使用循环模式 //双缓冲模式时此位无效
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
//高优先级
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
//不使用FIFO模式
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
//
//外设突发单次传输
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
//存储器突发单次传输
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
//初始化DMA Stream
DMA_Init(DMA1_Stream3, &DMA_InitStructure);
//
DMA_ITConfig(DMA1_Stream3,DMA_IT_TC,DISABLE);
//
//DMA_Memory_0首先被传输
DMA_DoubleBufferModeConfig(DMA1_Stream3,(uint32_t)codec_rx_ok,DMA_Memory_1);
//使能双缓冲模式
DMA_DoubleBufferModeCmd(DMA1_Stream3,ENABLE);
//
cur_dma_ct = 0;
store_dma_ct = 0;
codec_dma_stream_is_enable = False;
}
//
void init_codec_tx_dma(void)
{
DMA_InitTypeDef DMA_InitStructure;
//
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);
//
DMA_DeInit(DMA1_Stream4);
/* 配置 DMA Stream */
DMA_InitStructure.DMA_Channel = DMA_Channel_0; //通道0 SPI2_TX通道
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI2->DR;//外设地址为:(u32)&SPI2->DR
DMA_InitStructure.DMA_Memory0BaseAddr = (u32)codec_tx_buf;//DMA 存储器0地址 //此处可以不配置
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;//存储器到外设模式
//
DMA_InitStructure.DMA_BufferSize = 16;//数据传输量
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设数据长度:16位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//存储器数据长度:16位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;// 使用循环模式 //双缓冲模式时此位无效
DMA_InitStructure.DMA_Priority = DMA_Priority_High;//高优先级
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //不使用FIFO模式
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
//
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//外设突发单次传输
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//存储器突发单次传输
//
DMA_Init(DMA1_Stream4, &DMA_InitStructure);//初始化DMA Stream
//
DMA_ITConfig(DMA1_Stream4,DMA_IT_TC,DISABLE);
}
I2S配置
void init_i2s_transmission(void)
{
I2S_InitTypeDef m_iis_para;
//
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
//
I2S_Cmd(SPI2,DISABLE);
//
m_iis_para.I2S_Mode = I2S_Mode_MasterTx;
m_iis_para.I2S_DataFormat = I2S_DataFormat_16b;
m_iis_para.I2S_Standard = I2S_Standard_MSB;
m_iis_para.I2S_MCLKOutput = I2S_MCLKOutput_Enable;
m_iis_para.I2S_AudioFreq = I2S_AudioFreq_8k;
m_iis_para.I2S_CPOL = I2S_CPOL_Low;
//
I2S_Init(SPI2,&m_iis_para);
//
I2S_Cmd(SPI2, ENABLE);
}
//
void init_i2s_receiver(void)
{
I2S_InitTypeDef m_iis_para;
//
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
//
I2S_Cmd(I2S2ext,DISABLE);
//
m_iis_para.I2S_Mode = I2S_Mode_SlaveRx;
m_iis_para.I2S_DataFormat = I2S_DataFormat_16b;
m_iis_para.I2S_Standard = I2S_Standard_MSB;
m_iis_para.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
m_iis_para.I2S_AudioFreq = I2S_AudioFreq_8k;
m_iis_para.I2S_CPOL = I2S_CPOL_Low;
//
I2S_FullDuplexConfig(I2S2ext,&m_iis_para);
//
I2S_Cmd(I2S2ext, ENABLE);
}
时钟配置,固定采样率时钟保持输出并且不变
void init_i2s_pm(void)
{
I2S_Cmd(SPI2,DISABLE);
RCC->CR &= ~(1 << 26); //停止I2S时钟
/* Fvco = 12.288 * (300 / 10) -> 368.64MHZ */
/* Fpll = 368.64 / 6 -> 61.44MHZ */
//RCC_PLLI2SConfig(240,6);
RCC->PLLI2SCFGR = (6 << 28) | (300 << 6); //PLLI2S时钟61.44MHZ
RCC->CR |= 1 << 26; //开启I2S时钟
while((RCC->CR&1<<27)==0); //等待I2S时钟开启成功.
/* bit9: I2S MCK ENABLE,bit8 : ODD 0: div * 2,1: div * 2 + 1*/
SPI2->I2SPR = (1 << 9) | 15; //61.44MHZ总线频率,分频到2.048MHZ | (1 << 8)
//SPI_I2SCFGR bit11:I2S mode/ bit10:enable/ bit9-8:master send/receive slave s/r
//bit7:PCM frame sync bit6:receive bit5-4:I2S stanted selection bit3:COPL
//bit2-1:data len 00 16bit bit0:channel len
//这个寄存器在配置发射和接受时再配,这里不需要开出来
//SPI2->I2SCFGR = (1 << 11) | (2 << 8) | (0 << 4) | (0 << 3); //I2S模式,主发,MSB对齐,16bit,通道16位
//I2S_Cmd(SPI2,ENABLE);
} |
|