stm32串口

  DMA使用流程:
    1. 配置
        外设端:
            - 串口引脚GPIO配置
            - 串口功能参数配置(数据位格式,波特率等),此处还需要**配置对应的DMA请求允许**。
            - 如果有中断,还需要配置中断优先级
        DMA端:
            - DMA功能配置
                - 初始化DMA通道DMA_Init(DMA1_Channel4,&DMA_InitStructure);
                。 DMA源(Memory)/目的(外设)地址
                。 DMA的传输方向
                。 DMA的buffer size
                。 DMA外设(DISABLE)/Memory(ENABLE)地址自增使能配置
                。 DMA传输字节格式(支持byte,half-word,word)
                。 DMA传输方式(Normal和Circle)
                。 DMA传输优先级(共有四种,)
                。 DMA m2m使能/失能配置(此处不是用于m2m所以配置为DISABLE)
                - 清除中断标志位
                - 此处应DISABLE DMA通道,否则配置完成即会产生DMA数据传输(非期望数据)
                - 使能DMA发送完成中断

            - DMA中断服务函数
                发送数据完成后,即关闭DMA通道,发送信号量到应用程序


             参考代码:实现stm32f103 uart1 dma发送和接收


//#define DMA_USART1_DR_Base      (USART1_BASE + 0x4) //0x40013804
#define DMA_USART1_DR_Base          0x40013804

//1. 串口1端口配置
void uart1_gpio_config(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    //DBTX  PA9  uart1_tx
    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);
    //DBRX  PA10   uart1_rx
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA,&GPIO_InitStructure);

}
//2. 串口功能配置
void uart1_param_config(void)
{
    USART_InitTypeDef  USART_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

    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_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

    USART_Init(USART1,&USART_InitStructure);
    //config uart DMA request
    USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);//enable usart1 dma send request
    USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); //enable usart1 dma recieve request
    USART_ITConfig(USART1,USART_IT_IDLE,ENABLE); //enable usart1 idle interrupt
    USART_Cmd(USART1,ENABLE);
}
//
void uart1_nvic_config(void){
    NVIC_InitTypeDef  NVIC_InitStructure;
    //uart1 interrupt
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    //dma interrupt
    NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;   //
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;     //
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);
}


//DMA config/
//1. uart dma configs
void uart1_dma_init(void){
    DMA_InitTypeDef DMA_InitStructure;

    //Tx DMA CONFIG
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); //enable DMA1 clock
    DMA_Cmd(DMA1_Channel4,DISABLE);                                     //close DMA Channel
    DMA_DeInit(DMA1_Channel4);

    DMA_InitStructure.DMA_PeripheralBaseAddr = DMA_USART1_DR_Base;  //(uint32_t)(&USART1->DR)
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Uart1TxBuf;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = USART1_TX_BUFF_SIZE; 
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; 
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 

    DMA_Init(DMA1_Channel4,&DMA_InitStructure);
    DMA_ClearFlag(DMA1_FLAG_GL4);  // clear all DMA flags
    //DMA_Cmd(DMA1_Channel4,ENABLE); // close DMA Channel
    DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);  //open DMA send inttrupt

    //Rx DMA CONFIG 
    DMA_Cmd(DMA1_Channel5, DISABLE);   //                       
    DMA_DeInit(DMA1_Channel5);  

    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART1->DR);
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Uart1RxBuf;        
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                    
    DMA_InitStructure.DMA_BufferSize = USART1_RX_BUFF_SIZE;                     
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;       
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;        
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                           
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;               
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                           

    DMA_Init(DMA1_Channel5, &DMA_InitStructure);            
    DMA_ClearFlag(DMA1_FLAG_GL5);                              
    DMA_Cmd(DMA1_Channel5, ENABLE);  
}




///uart dma send//
void DMA1_Channel4_IRQHandler(void)
{
    if(DMA_GetITStatus(DMA1_FLAG_TC4)==SET)
    {
            DMA_ClearFlag(DMA1_FLAG_GL4);        
            DMA_Cmd(DMA1_Channel4, DISABLE);  
            OSMboxPost(UartSndMBox, (void*)1); 
    }
}
void uart_dma_send_enable(uint16_t size)
{
    DMA1_Channel4->CNDTR = (uint16_t)size; 
    DMA_Cmd(DMA1_Channel4, ENABLE);       
}


///uart dma recv//
void uart1_dma_recv_data(void)
{
   //INT8U err;
   
   DMA_Cmd(DMA1_Channel5, DISABLE);      
   DMA_ClearFlag(DMA1_FLAG_GL5);          
   //index = USART1_RX_BUFF_SIZE - DMA_GetCurrDataCounter(DMA1_Channel5); 
   DMA1_Channel5->CNDTR = USART1_RX_BUFF_SIZE;   
   DMA_Cmd(DMA1_Channel5, ENABLE);       

   OSMboxPost(UartRevMBox,(void*)1);
}
void USART1_IRQHandler(void)
{
    if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET)  
    {
    	Uart1RevLen = USART1_RX_BUFF_SIZE - DMA_GetCurrDataCounter(DMA1_Channel5); //获得接收到的字节数

		memcpy(Uart1RxBufCpy,Uart1RxBuf,Uart1RevLen);
		
        uart1_dma_recv_data();
        /*
        *  Clear IDLE interrupt flag bit
        *  1. read USART_SR
        *  2. read USART_DR
        */
		USART_ReceiveData( USART1 ); // Clear IDLE interrupt flag bit

		
    }
}







//3. 串口初始化
void uart1_init(void)
{
    uart1_gpio_config();
    uart1_param_config();
    uart1_nvic_config();
	uart1_dma_init();
}

INT16U uart1_send_data( INT8U *pbuff, INT16U size )
{
	INT8U err;
   
	if((NULL == pbuff) || (0==size) )
	{
		return 0;
	}
	if(size > USART1_TX_BUFF_SIZE)
	{
		size = USART1_TX_BUFF_SIZE;
	}
	memcpy(Uart1TxBuf,pbuff,size);
    uart_dma_send_enable(size);
    OSMboxPend(UartSndMBox, 3000, &err);
	if(OS_ERR_NONE != err)
	{
		size = 0;
	}
	return size;
}

INT16U uart1_rev_data( INT8U *pbuff, INT16U size,INT16U TimeOutMs)
{
 
    INT8U err;
   
	if((NULL == pbuff) || (0==size) )
	{
		return 0;
	}
	if(size > USART1_RX_BUFF_SIZE)
	{
		size = USART1_RX_BUFF_SIZE;
	}
	memset(pbuff,0,size);
 
    OSMboxPend(UartRevMBox, TimeOutMs, &err);
	if(OS_ERR_NONE != err)
	{
		size = 0;
	}
	else
	{
		if(Uart1RevLen < size)
		{
			size = Uart1RevLen;
		}
		memcpy(pbuff,Uart1RxBufCpy,size);
	}
	return size;
 
}


void BSP_Init(void)
{ 
	UartSndMBox = OSMboxCreate ((void*)0); 
	UartRevMBox = OSMboxCreate ((void*)0); 
    uart1_init();
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值