STM32串口使用说明-DMA方式(代码示例)

STM32串口使用说明-DMA方式

STM32串口DMA方式与普通串口收发方式配置不同之处:

增加串口发送DMA配置,DMA发送函数,DMA发送中断函数;串口接收DMA配置;以及串口中断函数处理有所不同。

1、串口引脚配置、串口参数配置、串口中断优先级

        同前文相同。

2、接收中断函数

void USART6_IRQHandler(void)
//串口6接收中断函数
void USART6_IRQHandler(void)
{
	if(USART_GetITStatus(USART6, USART_IT_IDLE) != RESET) 
	{
		DMA_Cmd(DMA2_Stream1, DISABLE);	//禁止接收
		
        //清除IDLE中断
        (void)USART6->SR;     
        (void)USART6->DR;      
		
		RxBuf_Lenth = DMA_GetCurrDataCounter(DMA2_Stream1);  //获取传输数据长度
		
		RxFinish = TRUE;//接收完成标志
		
		DMA_ClearFlag(DMA2_Stream1,DMA_FLAG_TCIF1 | 
								   DMA_FLAG_FEIF1 | 
								   DMA_FLAG_DMEIF1| 
								   DMA_FLAG_TEIF1 | 
								   DMA_FLAG_HTIF1); 
        DMA_SetCurrDataCounter(DMA2_Stream1, ControlBuf_MAX);   
        DMA_Cmd(DMA2_Stream1, ENABLE);                          
	}	
}

3、串口发送DMA配置

void DMA2_USART6_Tx_Init(void)
//串口6DMA发送配置
void DMA2_USART6_Tx_Init(void)
{
	DMA_InitTypeDef  DMA_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);		使能DMA2时钟
		
	/*DMA2 Stream 6 Channel 5 Usart6_Tx */
	DMA_DeInit(DMA2_Stream6);								//将DMA的发送数据流设置为缺省值
	while (DMA_GetCmdStatus(DMA2_Stream6) != DISABLE);		//等待DMA的发送数据流可配置

	DMA_InitStructure.DMA_Channel = DMA_Channel_5;			//通道选择
	DMA_InitStructure.DMA_PeripheralBaseAddr = (DWORD)&USART6->DR;		//DMA址地设外
	DMA_InitStructure.DMA_Memory0BaseAddr = (u32)SerialBuf.ControlBuf;	//DMA储存器0地址
	DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;				//存储器到外设模式
	DMA_InitStructure.DMA_BufferSize = Buf_MAX;						    //数据传输量
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;	//外设非增量模式
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;					//存储器增量模式
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;	//外设数据长度:8位
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;			//存储器数据长度:8位
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;							//使用普通模式
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;					//中等优先级
	DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         			//FIFO模式
	DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;			//FIFO阈值
	DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;				//存储器突发单次传输
	DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;		//外设突发单次传输
	DMA_Init(DMA2_Stream6, &DMA_InitStructure);	

	NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream6_IRQn;     //DMA发送数据流中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;   //抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;          //子优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);                  
	
    DMA_ITConfig(DMA2_Stream6,DMA_IT_TC,ENABLE);                //使能DMA发送数据流中断
}

4、串口接收DMA配置

void DMA2_USART6_Rx_Init(void)
//串口接收DMA配置
void DMA2_USART6_Rx_Init(void)
{
	DMA_InitTypeDef  DMA_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);		//DMA2时钟使能
    DMA_DeInit(DMA2_Stream1);                                   //
    while (DMA_GetCmdStatus(DMA2_Stream1) != DISABLE);          //等待数据流可设

    DMA_InitStructure.DMA_Channel = DMA_Channel_5;				//通道
    DMA_InitStructure.DMA_PeripheralBaseAddr = (DWORD)&USART6->DR;		//DMA外设地址
    DMA_InitStructure.DMA_Memory0BaseAddr = (u32)SerialBuf.ControlBuf;	//DMA存储0地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ;            //外设到存储器模式
    DMA_InitStructure.DMA_BufferSize = Buf_MAX;                         //数据传输量
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;    //(同DMA发送xxx)
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;             //xxx
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //xxx
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;          //xxx
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                            //xxx
    DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                    //xxx
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;                   //xxx
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;            //xxx
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;              //xxx
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;      //xxx
    DMA_Init(DMA2_Stream1, &DMA_InitStructure);

    USART_DMACmd(USART6,USART_DMAReq_Rx,ENABLE);                       //使能串口DMA接收
    DMA_Cmd(DMA2_Stream1, ENABLE);                                     //开启DMA传输
}

5、DMA发送函数

void DMA2_Usart6_Tx_Enable(WORD Size)  
//串口6 DMA发送使能
void DMA2_Usart6_Tx_Enable(WORD Size)  
{   
	DMA_Cmd(DMA2_Stream6, DISABLE);                         //关闭DMA传输
    while (DMA_GetCmdStatus(DMA2_Stream6) != DISABLE){}		//确保DMA可以被设置
    DMA_SetCurrDataCounter(DMA2_Stream6, Size);				//数据传输量

    DMA_Cmd(DMA2_Stream6, ENABLE);                          //开启DMA传输
}  

6、DMA发送中断函数

void DMA2_Stream6_IRQHandler(void)  
//DMA传输中断函数
void DMA2_Stream6_IRQHandler(void)  
{
    if(DMA_GetFlagStatus(DMA2_Stream6,DMA_FLAG_TCIF6)!=RESET)		//等待传输完成中断标志
    { 
        DMA_ClearFlag(DMA2_Stream6, DMA_FLAG_TCIF6);				//清除中断标志
		
		delay_ms(3);
		
		DMA_Cmd(DMA2_Stream1, ENABLE);                              //打开DMA接收
    }  
} 

明月别枝惊鹊,清风半夜鸣蝉。

                                                                ——《西江月 夜行黄沙道中宋朝·辛弃疾

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吃~鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值