手把手教你如何使用DMA转运ADC多通道数据


目录

前言

一、介绍DMA

(1)概念

(2)硬件资源

(3)整体框图

二、代码实现

(1)DMA初始化

(2)使能通道

(3)定义存放数组

(4)主函数 

 三、应用实现

(1)硬件连接

(2)实验目的 

(3)实验现象

 ​编辑

(4)实验结果

总结

前言

上文讲述了使用非扫描模式配置ADC多通道,但是为了提高效率,本文会用扫描模式配置多通道。

但是规则组的数据寄存器只能放得下一个通道的转换结果,后来的数据会将已在的数据进行覆盖,为避免出现这种情况,本文会使用DMA将每个通道的数据进行搬运,以此实现扫描模式配置ADC多通道。


提示:以下是本篇文章正文内容,下面案例可供参考

一、介绍DMA

(1)概念

DMA的全称是Direct Memory Access,意为直接存储器存取。

DMA用于外设和存储器以及存储器和存储器之间的高速数据传输,并且这个传输过程无需CPU干涉,节省了CPU的资源。

(2)硬件资源

对于大容量的STM32芯片,一般都有两个DMA外设。分别是DMA1(7个通道),DMA2(5个通道)

每个通道都支持软件触发和特定的硬件触发。

硬件触发一般用于外设和存储器之间,软件触发用于存储器和存储器之间。

(3)整体框图

上图为DMA的整体框图,从图中我们可得以下几点信息

  1. DMA仲裁器配置通道优先级。在总线矩阵中也有仲裁器,当DMA和CPU同时向同一个数据发送请求时,会暂停CPU的请求,但也会有一半的带宽留给CPU。
  2. 外设和存储器以及存储器和存储器之间可互相进行数据传输。
  3. 必须配置传输计数器,来确定传输的次数,次数必须要大于0
  4. 通过配置自动重装器,来确定是否需要不停地连续传输。
  5. DMA传输必须要有触发信号
  6. DMA传输必须要使能DMA通道和对应外设的DMA使能

二、代码实现

(1)DMA初始化

代码如下:

	DMA_InitTypeDef DMA_InitStructure;
	DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1->DR; //起点地址为ADC1的DR寄存器
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //传输的数据宽度为半字
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //因为起点地址固定,所以失能地址自增模式
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)AD_Value; //因为地址是32位的 所以强转为32位
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//传输的数据宽度为半字
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;//因为终点地址固定,所以失能地址自增模式
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //设置DMA通道优先级为中等
	DMA_InitStructure.DMA_BufferSize = 3;//因为有三个数值要传输,所以将传输计数器的值设为3
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//从ADC外设传输到SRAM存储器,所以ADC寄存器地址为源地址
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //是否开启软件触发:否  因为ADC属于硬件触发源
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //开启DMA循环转运模式
	DMA_Init(DMA1_Channel1, &DMA_InitStructure);

DMA结构体的参数较多,所以配置时应当细心。 

(2)使能通道

代码如下:

DMA_Cmd(DMA1_Channel1,ENABLE);		//使能DMA1的通道1
ADC_DMACmd(ADC1, ENABLE);           //使能ADC1触发DMA1的信号
ADC_Cmd(ADC1, ENABLE);				//使能ADC1,ADC开始运行

(3)定义存放数组

定义一个SRAM数组,用于存放ADC转换后的值。

uint16_t AD_Value[3];

(4)主函数 

int main(void)
{
	
	ADC1_DMA_Init();

	OLED_Init();

	OLED_ShowString(0, 0, "AD0:", OLED_8X16);
	OLED_ShowString(0, 16, "AD1:", OLED_8X16);
	OLED_ShowString(0, 32, "AD2:", OLED_8X16);
	
	while (1)
	{	
		OLED_ShowNum(32,  0, AD_Value[0], 4, OLED_8X16);//DMA搬运后的数据
		OLED_ShowNum(32,  16, AD_Value[1], 4, OLED_8X16);
		OLED_ShowNum(32,  32, AD_Value[2], 4, OLED_8X16);
		
		Delay_ms(100);
		OLED_Update();
	}
}

 三、应用实现

(1)硬件连接

光敏传感器------AOPA0
热敏传感器----- AOPA1
对射式红外传感器---AOPA2

(2)实验目的 

利用DMA搬运ADC扫描模式下转换完成的多通道AD数据至SRAM数组

熟练掌握DMA搬运原理以及ADC多通道配置

(3)实验现象

 

(4)实验结果

DMA搬运正常,实验完成。 


总结

本文实现了外设与外设之间的互相合作,但这仅仅只是基础实现,希望各位读者可以不断继续学习进步。

  • 11
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值