串口DMA

static void Usart1Init(int iBaudRate)
{
    #if (TX_USE_MODE == USE_MODE_DMA) || (RX_USE_MODE == USE_MODE_DMA)
    DMA_InitTypeDef DMA_InitStructure;
    #endif
    GPIO_InitTypeDef GPIO_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBENR_DMA1EN | RCC_AHBENR_DMA2EN, ENABLE);

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  //TX
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //RX
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    Usart1BaseInit(iBaudRate);
    #if (TX_USE_MODE != USE_MODE_POL)
    FifoInit(&gsstUsart1TxFifo, gsucUsart1TxBuf, sizeof(gsucUsart1TxBuf), Usart1TxCrtCtrl, FALSE);
    #endif
    #if (RX_USE_MODE != USE_MODE_POL)
    FifoInit(&gsstUsart1RxFifo, gsucUsart1RxBuf, sizeof(gsucUsart1RxBuf), Usart1RxCrtCtrl, TRUE);
    #endif
    
    #if (TX_USE_MODE == USE_MODE_DMA)
    DMA_InitStructure.DMA_BufferSize = sizeof(gsucUsart1TxBuf);//DMA通道的DMA缓存的大小
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//数据传输方向,从内存读取发送到外设
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输
		//内存
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(gsucUsart1TxBuf); //DMA内存基地址
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//数据宽度为8位
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址寄存器递增
		
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//工作在正常缓存模式
		//外设
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DR);//DMA外设USART1基地址
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据宽度为8位
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址寄存器不变
		
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA通道 x拥有高优先级 
    DMA_Cmd(DMA1_Channel4, DISABLE); //!!!! DISABLE STATE CNDTR REGISTER CAN BE UPDATE 
    DMA_Init(DMA1_Channel4, &DMA_InitStructure);//根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器
    DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);//=====================DMA_IT_TC定义为传输数据给外设地址满了才发生
    DMA_Cmd(DMA1_Channel4, DISABLE); //DISABLE   
    
    USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
    #endif

    #if (RX_USE_MODE == USE_MODE_DMA)
    DMA_InitStructure.DMA_BufferSize = sizeof(gsucUsart1RxBuf);
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//数据传输方向,从外设读取到内存[外设是数据源]
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(gsucUsart1RxBuf);
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//这句是设置 DMA 的传输模式:连续不断的循环模式,若只想访问一次后就不要访问了(或按指令操作来反问,也就是想要它访问的时候就访问,不要它访问的时候就停止),可以设置成通用模式:DMA_Mode_Normal。
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DR);
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;//
    DMA_Cmd(DMA1_Channel5, DISABLE); //!!!! DISABLE STATE CNDTR REGISTER CAN BE UPDATE 
    DMA_Init(DMA1_Channel5, &DMA_InitStructure);
    DMA_Cmd(DMA1_Channel5, ENABLE);
    
    USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);  
    USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
    #elif (RX_USE_MODE == USE_MODE_INT)
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  
    #endif
    
    USART_Cmd(USART1, ENABLE);  

    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    #if (TX_USE_MODE == USE_MODE_DMA)
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn; //TX DMA
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    #endif
}

  

/*****************************************************************
 函数名称:USART1_IRQHandler
 函数描述:
 输入参数:
 输出参数:
 返回说明:
 其它说明:
 *****************************************************************/
void USART1_IRQHandler(void)
{
    #if (RX_USE_MODE == USE_MODE_INT)
    if((USART1->CR1 & USART_FLAG_RXNE) && (USART1->SR & USART_FLAG_RXNE))
	{
		u8 ucData = USART1->DR;
        UsartRxCheckSymbol(&gsstCnter1, ucData);
        FifoPushByte(&gsstUsart1RxFifo, ucData);
	}
    #endif
    #if (TX_USE_MODE == USE_MODE_INT)
    if((USART1->CR1 & USART_FLAG_TXE) && (USART1->SR & USART_FLAG_TXE))
    {
        int iData = FifoPopByte(&gsstUsart1TxFifo);
        if(iData >= 0)
        {
			USART1->DR = (u8)(iData);
        }
		else
		{
			USART1->CR1 &= ~USART_FLAG_TXE;
		}
    }
    #endif
    #if (RX_USE_MODE == USE_MODE_DMA)
    if((USART1->CR1 & USART_FLAG_IDLE) && (USART1->SR & USART_FLAG_IDLE)) //空闲才中断
    {
        int iInPoint = USART1->SR;
        iInPoint = USART1->DR;
        iInPoint = sizeof(gsucUsart1RxBuf) - DMA1_Channel5->CNDTR;
        UsartRxDMACheckReset(&gsstUsart1RxFifo, &gsstCnter1, iInPoint);
        FifoPushSetPoint(&gsstUsart1RxFifo, iInPoint);
    }
    #endif
}

#if (TX_USE_MODE == USE_MODE_DMA)
/*****************************************************************
 函数名称:DMA1_Channel4_IRQHandler
 函数描述:
 输入参数:
 输出参数:
 返回说明:
 其它说明:
 *****************************************************************/
void DMA1_Channel4_IRQHandler(void)
{
    stUsartDmaOperationArgs_t stArgs = {FALSE, 256, DMA1_Channel4}; //FALSE 不检查
    DMA_ClearITPendingBit(DMA1_IT_TC4);
    FifoSafeOperation(&gsstUsart1TxFifo, UsartTxDMAOperation, &stArgs);
}

  

static void Usart1Init(int iBaudRate){    #if (TX_USE_MODE == USE_MODE_DMA) || (RX_USE_MODE == USE_MODE_DMA)    DMA_InitTypeDef DMA_InitStructure;    #endif    GPIO_InitTypeDef GPIO_InitStructure;    NVIC_InitTypeDef NVIC_InitStructure;        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO, ENABLE);    RCC_AHBPeriphClockCmd(RCC_AHBENR_DMA1EN | RCC_AHBENR_DMA2EN, ENABLE);
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  //TX    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     GPIO_Init(GPIOA, &GPIO_InitStructure);        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //RX    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;    GPIO_Init(GPIOA, &GPIO_InitStructure);
    Usart1BaseInit(iBaudRate);    #if (TX_USE_MODE != USE_MODE_POL)    FifoInit(&gsstUsart1TxFifo, gsucUsart1TxBuf, sizeof(gsucUsart1TxBuf), Usart1TxCrtCtrl, FALSE);    #endif    #if (RX_USE_MODE != USE_MODE_POL)    FifoInit(&gsstUsart1RxFifo, gsucUsart1RxBuf, sizeof(gsucUsart1RxBuf), Usart1RxCrtCtrl, TRUE);    #endif        #if (TX_USE_MODE == USE_MODE_DMA)    DMA_InitStructure.DMA_BufferSize = sizeof(gsucUsart1TxBuf);//DMA通道的DMA缓存的大小    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//数据传输方向,从内存读取发送到外设    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输//内存    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(gsucUsart1TxBuf); //DMA内存基地址    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//数据宽度为8位    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址寄存器递增    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//工作在正常缓存模式//外设    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DR);//DMA外设USART1基地址    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据宽度为8位    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址寄存器不变    DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA通道 x拥有高优先级     DMA_Cmd(DMA1_Channel4, DISABLE); //!!!! DISABLE STATE CNDTR REGISTER CAN BE UPDATE     DMA_Init(DMA1_Channel4, &DMA_InitStructure);//根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器    DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);//=====================DMA_IT_TC定义为传输数据给外设地址满了才发生    DMA_Cmd(DMA1_Channel4, DISABLE); //DISABLE           USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);    #endif
    #if (RX_USE_MODE == USE_MODE_DMA)    DMA_InitStructure.DMA_BufferSize = sizeof(gsucUsart1RxBuf);    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//数据传输方向,从外设读取到内存[外设是数据源]    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(gsucUsart1RxBuf);    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//这句是设置 DMA 的传输模式:连续不断的循环模式,若只想访问一次后就不要访问了(或按指令操作来反问,也就是想要它访问的时候就访问,不要它访问的时候就停止),可以设置成通用模式:DMA_Mode_Normal。    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DR);    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;//    DMA_Cmd(DMA1_Channel5, DISABLE); //!!!! DISABLE STATE CNDTR REGISTER CAN BE UPDATE     DMA_Init(DMA1_Channel5, &DMA_InitStructure);    DMA_Cmd(DMA1_Channel5, ENABLE);        USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);      USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);    #elif (RX_USE_MODE == USE_MODE_INT)    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);      #endif        USART_Cmd(USART1, ENABLE);  
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;    NVIC_Init(&NVIC_InitStructure);
    #if (TX_USE_MODE == USE_MODE_DMA)    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn; //TX DMA    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;    NVIC_Init(&NVIC_InitStructure);    #endif}

猜你喜欢

转载自www.cnblogs.com/icaowu/p/12537024.html