今天调USART,数据在芯片内部用DMA传到串口缓存,发现DMA真的很好,很快,而且不消耗系统资源。只是在传输完的时候中断的标志置位。下面解释一下程序。
void DMA_Configuration(void)
{
DMA_InitTypeDef DMA_InitStructure;
//DMA设置:
//设置DMA源:内存地址&串口数据寄存器地址
//方向:内存-->外设
//每次传输位:8bit
//传输大小DMA_BufferSize=SENDBUFF_SIZE
//地址自增模式:外设地址不增,内存地址自增1
//DMA模式:一次传输,非循环
//优先级:中
DMA_DeInit(DMA1_Channel4); //功能描述: 将DMA的通道x 寄存器重设为缺省值. 输入参数: DMA Channelx :x 可以是1 2…,或者 7 来选择DMA通道x
DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base; //该参数用以定义DMA外设基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff; //该参数用以定义DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //DMA_DIR 规定了外设是作为数据传输的目的地还是来源。
DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE; //DMA_BufferSize用以定义指定 DMA通道的DMA缓存的大小,单位为数据单位。根据传输方向,数据单位等于结构中参数DMA_PeripheralDataSize 或者参数 DMA_MemoryDataSize 的值。
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //DMA_PeripheralInc用来设定外设地址寄存器递增与否。
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //DMA_MemoryInc 用来设定内存地址寄存器递增与否。
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //DMA_PeripheralDataSize 设定了外设数据宽度。Byte 8位。HalfWord 16位。Word 32位。
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //DMA_MemoryDataSize 设定了外设数据宽度。
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // DMA_Mode设置了CAN的工作模式,Circular 工作在循环缓存模式,Normal 工作在正常缓存模式
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA_Priority 设定DMA通道x 的软件优先级。VeryHigh,High,Medium ,Low
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA_M2M使能DMA通道的内存到内存传输。
DMA_Init(DMA1_Channel4, &DMA_InitStructure); //
}
再弄几个重要的语句。
//这里是开始DMA传输前的一些准备工作,将USART1模块设置成DMA方式工作
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
//开始一次DMA传输!
DMA_Cmd(DMA1_Channel4, ENABLE);
在串口配置的时候需要打开串口接收中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
相应的NVIC
/设置NVIC优先级分组为Group2:0-3抢占式优先级,0-3的响应式优先级
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//串口接收中断打开
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//启动DMA时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);