Send data to serial port via DMA

 
 
 
 
//DMA --- Directional Memory Access, direct memory access is used to provide high-speed data transfer between peripherals and memory or between memory and memory. Without CPU intervention, data can be moved quickly through DMA, which saves CPU resources for other operations
// serial port initialization
void USART1_Init(u32 baud)
{
    GPIO_InitTypeDef GPIO_Initstructure;
    USART_InitTypeDef USART_Initstructure;
    NVIC_InitTypeDef NVIC_Initstructure;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE); //Enable the clock of PA and USART1
    //USART1_TX  PA9
    GPIO_Initstructure.GPIO_Mode = GPIO_Mode_AF_PP; //Push-pull multiplexing output
    GPIO_Initstructure.GPIO_Pin = GPIO_Pin_9;								//PA9
    GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;				//50MHz
    GPIO_Init(GPIOA, &GPIO_Initstructure); //Initialization
    //USART1_RX  PA10
    GPIO_Initstructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //Floating input
    GPIO_Initstructure.GPIO_Pin = GPIO_Pin_10;							//PA10
    GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;				//50MHz
    GPIO_Init(GPIOA, &GPIO_Initstructure);

    USART_DeInit (USART1);

    
    NVIC_Initstructure.NVIC_IRQChannel = USART1_IRQn;						//串口1
    NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority = 3; //Preempt priority 3
    NVIC_Initstructure.NVIC_IRQChannelSubPriority = 0; //Sub priority 3
    NVIC_Initstructure.NVIC_IRQChannelCmd = ENABLE; //Enable interrupt
    NVIC_Init(&NVIC_Initstructure);
    
    USART_Initstructure.USART_BaudRate = baud; //Baud rate
    USART_Initstructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //No hardware data flow control
    USART_Initstructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; // Development model
    USART_Initstructure.USART_Parity = USART_Parity_No; //No parity bit
    USART_Initstructure.USART_StopBits = USART_StopBits_1; //One stop bit
    USART_Initstructure.USART_WordLength = USART_WordLength_8b; //8 data bits
    
    USART_Init(USART1, &USART_Initstructure); //Initialization

    USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
    DMA1_Channel4_UseForUSART1_Config();

    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //Open serial port to accept interrupt
    USART_Cmd(USART1, ENABLE); //Enable serial port 1
}
void DMA1_Channel4_UseForUSART1_Config(void)
{
    DMA_InitTypeDef DMA_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_Init(&NVIC_InitStructure);
    
    DMA_DeInit(DMA1_Channel4); //Reset DMA channel register to default value
    DMA_InitStructure.DMA_BufferSize = 0; //The DMA buffer size is temporarily set to 6 bytes
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //Peripheral as destination
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //Not set to memory to memory
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff; //The memory address is temporarily set to 0, and the specific location is specified when the transfer is started
    DMA_InitStructure.DMA_MemoryDataSize = SENDBUFF_SIZE;					
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //The memory address is incremented
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //Normal mode does not cycle
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR; //Peripheral address
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //Peripheral size is one byte
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //The peripheral address does not increase automatically
    DMA_InitStructure.DMA_Priority = DMA_Priority_High; //High priority
    
    DMA_Init(DMA1_Channel4, &DMA_InitStructure);
    DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE); //Enable transfer completion interrupt
}
//Send data to serial port via DMA
FlagStatus FlagStatus_DMA1_Channel4_Busy; //DMA1_Channel4 busy flag
ErrorStatus USART1_SendDataByDMA(u32 memoryaddr, u16 buffersize)
{
    if(FlagStatus_DMA1_Channel4_Busy != SET) //Channel is idle
    {
        LED_TX_Onepulse();
        FlagStatus_DMA1_Channel4_Busy = SET; //Set the channel busy flag
        DMA_Cmd(DMA1_Channel4, DISABLE);
        DMA_SetCurrDataCounter(DMA1_Channel4, buffersize); //Buffer size
        DMA1_Channel4->CMAR = memoryaddr; //memory address
        DMA_Cmd(DMA1_Channel4, ENABLE); //Start transmission
        return SUCCESS;
    }
    else //The channel is busy
    {
        return ERROR;
    }
}

//Channel 4 interrupt function, used to clear the busy flag
void DMA1_Channel4_IRQHandler(void)
{
    if(DMA_GetITStatus(DMA1_IT_GL4) != RESET)
    {
        if(DMA_GetITStatus(DMA1_IT_TC4) != RESET)
        {
            FlagStatus_DMA1_Channel4_Busy = RESET; //Clear the busy flag
            DMA_ClearITPendingBit(DMA1_IT_TC4);
        }
        DMA_ClearITPendingBit(DMA1_IT_GL4);
    }
}



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325648179&siteId=291194637