1.DMA重要知识点
单次模式时:当传输计数器减到0就停止了;还想再次启动,得先失能装载计数器的值再使能 循环模式:当减到0时会重新加载
2.STM32使用串口工具高波特率发送多数据的时候,使用DMA能减少MCU的负担,并进行快速搬运数据,此代码是非中断接收不定长数据的.
#include "usart.h" void Usart_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; /* Enable GPIO clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); /* Configure USARTy Rx as input floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure USARTy Tx as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx |USART_Mode_Tx; /* Configure USARTy */ USART_Init(USART1, &USART_InitStructure); /* Enable USARTy DMA TX request */ USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); /* Enable USARTz */ USART_Cmd(USART1, ENABLE); } void Usart_send(uint8_t ch) { /* Place your implementation of fputc here */ /* e.g. write a character to the USART */ USART_SendData(USART1, (uint8_t) ch); /* Loop until the end of transmission */ while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) {} } void Usart_sendBuff(uint8_t *buf,uint32_t size) { for(uint32_t i=0;i<size;i++) { Usart_send(buf[i]); } } #include "dma.h" #include "string.h" //M to M /*定义数组作为DMA传输数据源 *使用const关键字修饰,使其定义为常量类型,表示数据存储在内部的FLASH中 */ const uint32_t DMA_S_Const_Buffer[BufferSIze]={ 0x12345678,0x12345679,0x1234567A, 0x1234567B,0x1234567C,0x1234567D,0x1234567E}; //定义DMA传输目标存储器,存储在内部的SRAM中 uint32_t DMA_D_Buffer[BufferSIze]; uint8_t DMA_D_Buffer_RX[BufferSIze]; void Dma_Config() { DMA_InitTypeDef dma_InitStruct; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); dma_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;//当内存传内存时可看作数据的源 dma_InitStruct.DMA_MemoryBaseAddr = (uint32_t)DMA_D_Buffer_RX; dma_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC; dma_InitStruct.DMA_BufferSize = BufferSIze; //传输数目 dma_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址增量模式 dma_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; dma_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; dma_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; dma_InitStruct.DMA_Mode = DMA_Mode_Normal; dma_InitStruct.DMA_M2M = DMA_M2M_Disable; dma_InitStruct.DMA_Priority = DMA_Priority_High ; DMA_Init(DMA1_Channel5,&dma_InitStruct); DMA_Cmd(DMA1_Channel5, ENABLE); } uint16_t Get_Revbuf(uint8_t *buf,uint32_t size) { uint16_t count=0,len=0; memset(buf,0,size); if(DMA1_Channel5->CNDTR < BufferSIze) { count = DMA1_Channel5->CNDTR ; delay_ms(30); if(count==DMA1_Channel5->CNDTR) { len = BufferSIze-count; for(int i=0;i<len;i++) { buf[i]=DMA_D_Buffer_RX[i]; } return len; } } return 0; }

微信扫码关注
更新实时通知