直接内存(DMA)存储为了提高速度在外设和内存和内存于内存之间,数据能够快速应对没有CPU行动,让CPU执行其他操作。
每一个DMA有8个数据流,每一个流有8个轨道。
双主线架构,一直支持外设,另一个支持内存。
FIFI有4个字的缓冲区,可以选择FIFI模式或直接模式,FIFI模式可以通过软件选择最高缓冲区有1/4, 1/2 or 3/4 of the FIFO size,直接模式只要外设要求接受数据,就立刻发送。
优先级可以编程,优先级相同,有硬件决定。
多少流发送,通过DR寄存器编程
发送和接受一般收发宽度,不同就应该收包和解包操作,不同宽度如下
外设 内存
8 8 传输不丢失
16 8 传输丢失, 传输前8位,外设 浪费1字节
8 16 传输不丢失16内存要浪费1字节
(1)
源和目得地址在传输是地址是否增加,有SR寄存器MINC:和PINC:控制。
支持突发传输4, 8 or 16 beats,有SR寄存器MBURST::和PBURST:控制,每一节拍是多少字节
FIFI 的最大值和突发配置
突发大小的倍数,不超过FIFI level
每一节拍(beats)就是说MSIZE的大小
e.g MSIZE 等于byte,FIFI一共有4个字,一共字32位,1/4FIF表示一个字,INCR4 的4个节拍(一个字)刚好突发。
1/2FIF表示一个2字,INCR4 的4个节拍两次突发(2字)刚好突发。INCR88次突发一次64位刚好,
从数据手册看:DMA1外设用(1)哪个流(2)哪个不同道
DMA2
- @brief USART1 TX DMA 配置,内存到外设(USART1->DR) 数据流7 4通道
- @param 无
- @retval 无
*/
void USART_DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;//DMA结构
/开启DMA时钟/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
/* 复位初始化DMA数据流 */
DMA_DeInit(DMA2_Stream7);
/* 确保DMA数据流复位完成 */
while (DMA_GetCmdStatus(DMA2_Stream7) != DISABLE){
}
/*usart1 tx对应dma2,通道4,数据流7*/
DMA_InitStructure.DMA_Channel = DMA_Channel_4;
/设置DMA源:串口数据寄存器地址/
DMA_InitStructure.DMA_PeripheralBaseAddr = (USART1_BASE+0x04);
/内存地址(要传输的变量的指针)/
DMA_InitStructure.DMA_Memory0BaseAddr = (u32)SendBuff;//是一数组
/方向:从内存到外设/
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
/传输大小DMA_BufferSize=SENDBUFF_SIZE/
DMA_InitStructure.DMA_BufferSize = 5000;
/外设地址不增/
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
/内存地址自增/
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
/外设数据单位/
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
/内存数据单位 8bit/
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
/DMA模式:不断循环/
//DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
/优先级:中/
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
/禁用FIFO/
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
/存储器突发传输 1个节拍/
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
/外设突发传输 1个节拍/
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
/配置DMA2的数据流7/
DMA_Init(DEBUG_USART_DMA_STREAM, &DMA_InitStructure);
/*使能DMA*/
DMA_Cmd(DEBUG_USART_DMA_STREAM, ENABLE);//寄存器SR en位为1
/* 等待DMA数据流有效*/
while(DMA_GetCmdStatus(DEBUG_USART_DMA_STREAM) != ENABLE)//检查寄存器SR en位为1
{
}
}
//效果以上电,就数组数据就往串口1发送数据
。