使用了两个DMA实现I2S接收24位音频数据、通过串口发送该数据 但是接收和发送的数据都有问题,DMA配置代码如下: /*定义中断和DMA配置变量*/ NVIC_InitTypeDef NVIC_InitStructure; DMA_InitTypeDef DMA_InitStructure; /* Enable DMA clock */ RCC_AHB1PeriphClockCmd(DMA_STREAM_CLOCK, ENABLE); /* Reset DMA Stream registers (for debug purpose) */ DMA_DeInit(DMA_STREAM); /* Check if the DMA Stream is disabled before enabling it.*/ while (DMA_GetCmdStatus(DMA_STREAM) != DISABLE) { } /*清空STREAM上所有中断标志,(见main.h,DMA_STREAM==DMA1_Stream2)*/ DMA_ClearITPendingBit(DMA_STREAM,DMA_IT_FEIF2|DMA_IT_DMEIF2|DMA_IT_TEIF2|DMA_IT_HTIF2|DMA_IT_TCIF2); /* Configure DMA Stream */ DMA_InitStructure.DMA_Channel = DMA_CHANNEL; /*DMA1 数据流2 通道0 SPI3RX*/ DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&I2Sx->DR; /*外设地址是I2S3的数据寄存器*/ DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&buf0; /*存放DMA数据的内存地址*/ DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; /*传输方向外设到存储器*/ DMA_InitStructure.DMA_BufferSize = (uint32_t)BUFFER_SIZE; /*数据传输量*/ DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /*外设非增量模式,即外设地址不会增加*/ DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /*存储器增量模式*/ DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; /*外设数据长度*/ DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; /*存储器数据长度*/ 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_Full; /*设置FIFO阈值,未开启,这里随便设无所谓*/ DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; /*储存器突发传输配置*/ DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_INC4; /*外设突发传输配置*/ DMA_Init(DMA_STREAM, &DMA_InitStructure); /*初始化DMA数据流*/ DMA_DoubleBufferModeConfig(DMA_STREAM,(uint32_t)&buf1,DMA_Memory_0);/*双缓冲模式配置*/ DMA_DoubleBufferModeCmd(DMA_STREAM,ENABLE); /*双缓冲模式开启*/ //串口DMA配置 DMA_InitStructure.DMA_Channel = DMA_Channel_4; /*DMA1 数据流6 通道4 USART2TX*/ DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR; /*外设地址是I2S3的数据寄存器*/ DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&buf0; /*存放DMA数据的内存地址*/ DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; /*传输方向存储器到外设*/ DMA_InitStructure.DMA_BufferSize = (uint32_t)BUFFER_SIZE; /*数据传输量*/ DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /*外设非增量模式,即外设地址不会增加*/ DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /*存储器增量模式*/ DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; /*外设数据长度*/ DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; /*存储器数据长度*/ 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_Full; /*设置FIFO阈值,未开启,这里随便设无所谓*/ DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4; /*储存器突发传输配置*/ DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; /*外设突发传输配置*/ DMA_Init(DMA1_Stream6, &DMA_InitStructure); /*初始化DMA数据流*/ DMA_DoubleBufferModeConfig(DMA1_Stream6,(uint32_t)&buf1,DMA_Memory_0);/*双缓冲模式配置*/ DMA_DoubleBufferModeCmd(DMA1_Stream6,ENABLE); /*双缓冲模式开启*/ 参考手册上关于接收24位I2S数据的说明: 我理解的是I2S数据寄存器只有16位,需要读两次,那在配置DMA的时候外设数据长度PeripheralDataSize和存储器数据长度MemoryDataSize该怎么配置?还有单次传输和突发传输要怎么设置? 我应该怎么检测数据的完整性?原本想在串口DMA发送完成中断的时候通过串口发送数据包的编号,但是好像会产生冲突,数据都发不完。 |
串口的速率和I2S的速率差一两个量级,串口115200bps只相当于10kbyte/s,而如果I2S采样率是44.1k,宽度是24bit,立体声,则数据速率就是44.1k*24/8*2=264.6kbyte/s。你要用串口来发送I2S接收到的数据是不可能的。 |