STM32 寄存器配置笔记——USART DMA发送

一、DMA介绍

直接存储器存取(DMA)用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传 输。无须CPU干预,数据可以通过DMA快速地移动,这就节省了CPU的资源来做其他操作。当产品对于时序要求较严格时,外设使用DMA的方式能够减轻CPU负担,从而提高整体效率。本文主要介绍USART1 DMA发送配置,以stm32f10系列为例。DMA每次发送固定字节数据保证主循环每次执行DMA发送是均匀的,避免高负载等特殊情况下处理异常。

二、USART1对应的通道

三、配置流程

1)配置DMA1时钟

复制代码
RCC->AHBENR |= 1 << 0;		//¿ªÆôDMA1ʱÖÓ

2)dma初始化配置

DMA初始化配置如下,串口DMA发送属于存储到外设模型,配置DMA单次模式发送,且每次发送存储地址自增1,这里开启了NVIC中断向量,如果要使用DMA中断的话则需要把下面注释段DMA_CHx->CCR |= 1 << 1;和MY_NVIC_Init(3,3,DMA1_Channel4_IRQn,2);打开。

复制代码
void DMA_Init(void)
{
    DMA_Config(DMA1_Channel4, (u32)&USART1->DR);
}

void DMA_Config(DMA_Channel_TypeDef* DMA_CHx, u32 cpar)
{
	DMA_CHx->CPAR = cpar;                    //cfg periph addr 
	DMA_CHx->CCR |= 3 << 12;                 //cfg channel prio 3
	DMA_CHx->CCR |= 1 << 4;                  //cfg mem to periph
	DMA_CHx->CCR &= ~(1 << 5);               //cfg dma single transfer
	DMA_CHx->CCR |= 1 << 7;                  //cfg mem transfer addr inc
	//DMA_CHx->CCR |= 1 << 1;                //cfg dma ie
	//MY_NVIC_Init(3,3,DMA1_Channel4_IRQn,2);  //cfg dma channel4 enable nvic if enable ie
}

打开后发现能够进入中断函数。这里并没有使用DMA中断方式,使用的轮询查标志。

复制代码
void DMA1_Channel4_IRQHandler(void)
{
	DMA1->IFCR|=1<<13;
}

3)创建dma发送任务

4)dma数据发送流程

基于前面写的博客STM32 寄存器配置笔记------USART配置中断接收乒乓缓存处理基础上加的dma流程设计。代码如下:

复制代码
static u32 dma_tx_single_len = 0;
static u32 dma_tx_total_len = 0;
static u32 dma_mem_offset = 0;
static u8 dma_tx_task = 0;
static u8 *g_pdma_tx_dat = NULL;
static DMA_UART_TX_STATUS dma_tx_status = DMA_UART_CHANNEL_IDLE;

void create_dma_tx_task(u8 *pDat, u32 len)
{
    if (dma_tx_task)
	{
	    printf("dma_tx_task is running\r\n");
	}
	else
	{
	    dma_tx_task = 1;
		g_pdma_tx_dat = pDat;
		dma_tx_total_len = len;
	}
}

void data_dma_tx(void)
{
	switch(dma_tx_status)
	{
		case DMA_UART_CHANNEL_IDLE:
		{
			if (dma_tx_task)
			{
				dma_tx_status = DMA_UART_SENDING;
				dma_mem_offset = 0;
				dma_tx_single_len = ((dma_tx_total_len >= DMA_UART_SINGLE_TX_LEN) ? DMA_UART_SINGLE_TX_LEN : dma_tx_total_len);
				DMA_UART_TX_ENABLE(DMA1_Channel4, (u32)g_pdma_tx_dat, dma_tx_single_len);
			}
		}
		break;
	
		case DMA_UART_SENDING:
		{
		    if (0 == (DMA1->ISR & (1 << 13)))
				return;
			
			DMA1->IFCR |= 1 << 13;
			dma_tx_total_len -= dma_tx_single_len;
			if (dma_tx_total_len)
			{
				dma_mem_offset += dma_tx_single_len;
				dma_tx_single_len = ((dma_tx_total_len >= DMA_UART_SINGLE_TX_LEN) ? DMA_UART_SINGLE_TX_LEN : dma_tx_total_len);
				DMA_UART_TX_ENABLE(DMA1_Channel4, (u32)g_pdma_tx_dat + dma_mem_offset, dma_tx_single_len);
			}
			else
			{
			    dma_tx_status = DMA_UART_SENDED;
			}
		}
		break;
	
		case DMA_UART_SENDED:
		{
		    dma_tx_status = DMA_UART_CHANNEL_IDLE;
			dma_tx_task = 0;
		}
		break;
	
		default:
			break;
	}
}

具体调用如下:

相关推荐
天水幼麟4 小时前
动手学深度学习-学习笔记(总)
笔记·深度学习·学习
小殷学长7 小时前
【单片机毕业设计17-基于stm32c8t6的智能倒车监测系统】
stm32·单片机·课程设计
天水幼麟7 小时前
动手学深度学习-学习笔记【二】(基础知识)
笔记·深度学习·学习
绿皮的猪猪侠7 小时前
算法笔记上机训练实战指南刷题
笔记·算法·pta·上机·浙大
沧海一笑-dj7 小时前
【51单片机】51单片机学习笔记-课程简介
笔记·学习·51单片机·江科大·江科大学习笔记·江科大单片机·江科大51单片机
老虎06278 小时前
JavaWeb(苍穹外卖)--学习笔记04(前端:HTML,CSS,JavaScript)
前端·javascript·css·笔记·学习·html
TESmart碲视8 小时前
HKS201-M24 大师版 8K60Hz USB 3.0 适用于 2 台 PC 1台显示器 无缝切换 KVM 切换器
单片机·嵌入式硬件·物联网·游戏·计算机外设·电脑·智能硬件
大苏打seven8 小时前
Docker学习笔记:Docker网络
笔记·学习·docker
small_wh1te_coder9 小时前
硬件嵌入式学习路线大总结(一):C语言与linux。内功心法——从入门到精通,彻底打通你的任督二脉!
linux·c语言·汇编·嵌入式硬件·算法·c
花落已飘10 小时前
STM32中实现shell控制台(shell窗口输入实现)
stm32·单片机·嵌入式硬件