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;
	}
}

具体调用如下:

相关推荐
深圳市九鼎创展科技43 分钟前
瑞芯微 RK3399 开发板 X3399 评测:高性能 ARM 平台的多面手
linux·arm开发·人工智能·单片机·嵌入式硬件·边缘计算
辰哥单片机设计1 小时前
STM32项目分享:车辆防盗报警系统
stm32·单片机·嵌入式硬件
智者知已应修善业1 小时前
【洛谷P9975奶牛被病毒传染最少数量推导,导出多样例】2025-2-26
c语言·c++·经验分享·笔记·算法·推荐算法
Junlan271 小时前
Cursor使用入门及连接服务器方法(更新中)
服务器·人工智能·笔记
risc1234562 小时前
如何认识结构?结构 = 要素 + 关系 + 动态
笔记
風清掦2 小时前
【江科大STM32学习笔记-05】EXTI外部中断11
笔记·stm32·学习
小龙报2 小时前
【51单片机】从 0 到 1 玩转 51 蜂鸣器:分清有源无源,轻松驱动它奏响新年旋律
c语言·数据结构·c++·stm32·单片机·嵌入式硬件·51单片机
范纹杉想快点毕业2 小时前
嵌入式与单片机开发核心学习指南——从思维转变到第一性原理的深度实践
单片机·嵌入式硬件
Industio_触觉智能2 小时前
瑞芯微RK3566开发板规格书,详细参数配置,型号EVB3566-V1,基于RK3566核心板SOM3566邮票孔封装
嵌入式硬件·开发板·rk3568·rk3566·核心板·瑞芯微
wdfk_prog2 小时前
[Linux]学习笔记系列 -- [drivers][tty]sysrq
linux·笔记·学习