细说STM32F407单片机2个ADC使用DMA同步采集各自的1个输入通道的方法

news/2025/2/24 9:40:29

目录

一、示例说明

二、工程配置

1、RCC、DEBUG、CodeGenerator

2、USART6

3、TIM3 

(1)Mode

(2)参数设置

(3) TRGO

(4)ADC1_IN0

1)ADCs_Common_Settings

2) ADC_Settings

3)ADC_Regular_ConversionMode

(5)ADC2_IN1

1)ADCs_Common_Settings

2) ADC_Settings

3)ADC_Regular_ConversionMode

(6)DMA

(7)NVIC

二、软件设计

三、运行与调试


        本文将通过一个实例测试 STM32F407ZGT6使用2个ADC模块并通过DMA模式同步采集各自的1个通道的方法。

       当一个ADC只有一个输入通道,在转换结束后可以及时读出结果数据寄存器的内容。

       当一个ADC规则转换组有多个通道时,应该使用扫描转换模式(Scan Conversion Mode),ADC在转换完一个通道后立刻转换下一个通道,直到规则组内的通道序列转换完。并启用DMA模式。

       当多个ADC规则转换组各有一个(多个)通道时,应选择诸如Dual regular simultaneous mode only的选项,并开启DMA模式。如果某个ADC规则转换组只有一个通道,无须开启Scan Conversion Mode,如果某个ADC规则转换组不只有一个通道,还须同时开启Scan Conversion Mode。

一、示例说明

        本文将继续使用旺宝红龙开发板STM32F407ZGT6 KIT V1.0。开发板1个可调电位器的模拟信号输入到PF8引脚,该管脚复选为ADC3_IN6。但是STM32F407**Datasheet规定,只允许ADC1和ADC2可以组合成二重ADC功能。否则,比如,如果设置了ADC1和ADC3,或者ADC2和ADC3,那么在ADCs_Common_Settings组里根本看不到诸如Dual regular simultaneous mode only这样的选项。

        只能配置ADC1和ADC2完成二重ADC同步采集功能,这里配置为ADC1_IN0(PA0)和ADC2_IN1(PA1),为了在开发板上获得ADC通道的数据输入,可以用导线把PF8依次连接到PA0和PA1上,这样,就使得ADC1_IN0和ADC2_IN1通道有了数据输入。当然也可以配置ADC1和ADC2采集片内内部参考信号。

        使用ADC1和ADC2同步采集两个通道的信号,双重ADC同步采集时(Dual regular simultaneous mode only),不能采集同一个通道;但如果ADC1和ADC2复选到同一个管脚上,并采集相同通道数据,则应选择仅双正交交织模式(Dual regular interleaved mode only)。

        多重ADC模式只能采用DMA方式传输数据。

二、工程配置

1、RCC、DEBUG、CodeGenerator

  • RCC:外部晶振25MHz,HCLK=168MHz,PCLK1=42MHz,PCLK2=84MHz;
  • DEBUG:Serial Wire;
  • CodeGenerator:勾选☑Generate peripheral initialization as a pair of '.c/.h' files per peripheral

2、USART6

        配置PG9、PG14为USART6,全部参数默认;

3、TIM3 

(1)Mode

        选择internal clock。

(2)参数设置

  • 预分频因子:49999。
  • 计数器方向:Up.
  • 计数器周期:499.
  • 内部时钟分频:No.
  • 自动重装载:启用。

(3) TRGO

  • MSM bit:Disable。
  • Trigger Event:Update Envent。

(4)ADC1_IN0

1)ADCs_Common_Settings
  • Mode:选择Dual regular simultaneous mode only
  • DMA Access Mode:DMA access mode
  • Delay between 2 sampling phases:25Cycles
2) ADC_Settings
  • Clock Prescaler:PCLK2 divided by 4
  • Resolution:12 bits(15 ADC Clock cycles)
  • Data Alignment:Right alignment
  • Scan Conversion Mode:Disable
  • Continuous Conversion Mode:Disabled. 启用连续转换模式后,ADC结束一个转换后立即启动一个新的转换。启用后数据更新的频率会快很多。
  • Discontinuous Conversion Mode:Disabled. 这种模式一般用于外部触发时,将一组输入通道分为多个短的序列,分批次转换。
  • DMA Continuous Requests:Enabled
  • End Of Conversion Selection:EOC flag at the end of single channel conversion
3)ADC_Regular_ConversionMode
  • Number Of Conversion:1
  • External Trigger Conversion Source:Timer 3 Trigger Out event
  • External Trigger Conversion Edge:Trigger detecton on the rising edge
  • Rank1:通道0,采样周期15个周期;

(5)ADC2_IN1

1)ADCs_Common_Settings
  • Mode:选择Dual regular simultaneous mode only
  • DMA Access Mode:DMA access mode
  • Delay between 2 sampling phases:25Cycles
2) ADC_Settings
  • Clock Prescaler:PCLK2 divided by 4
  • Resolution:12 bits(15 ADC Clock cycles)
  • Data Alignment:Right alignment
  • Scan Conversion Mode:Disable
  • Continuous Conversion Mode:Disabled.
  • Discontinuous Conversion Mode:Disabled. 
  • DMA Continuous Requests:Enabled
  • End Of Conversion Selection:EOC flag at the end of single channel conversion
3)ADC_Regular_ConversionMode
  • Number Of Conversion:1
  • External Trigger Conversion Source:没有这个选择项了
  • External Trigger Conversion Edge:没有这个选择项了
  • Rank1:通道1,采样周期15个周期;

(6)DMA

         启用ADC1和ADC2。设置为Circular模式,数据长度设置为word。

(7)NVIC

        设置USART6全局中断,抢占式优先级为1。因为文章中使用了其中断功能;

        默认设置 DMA2 Stream0和 DMA2 Stream2全局中断,抢占式优先级为1。

        设置ADC123的全局中断,抢占式优先级为1。

        TIM3的全局中断开不开启都可以,无关紧要,因为程序中使用的时计数器的Update Envent,而这个事件的产生并不依赖于TIM3的全局中断。

二、软件设计

        使用STM32CubeIDE建立本实例的软件工程,只需要修改main.c。其余的程序IDE自动生成。

/* USER CODE BEGIN Includes */
#include <stdio.h>
/* USER CODE END Includes */
/* USER CODE BEGIN PV */
#define BATCH_DATA_LEN 1				// Dual ADC captures 32-bit data stored at once
uint32_t dmaDataBuffer[BATCH_DATA_LEN];	// DMA Buffer
/* USER CODE END PV */
/* USER CODE BEGIN 2 */
  //菜单设计
  uint8_t hello1[] = "Demo14_4_DualADC:测试二重ADC同步采集\r\n";
  HAL_UART_Transmit(&huart6,hello1,sizeof(hello1),500);	//阻塞模式
  HAL_Delay(10);
  uint8_t hello2[] = "多ADC同步采集需启用DMA模式。\r\n";
  HAL_UART_Transmit_IT(&huart6,hello2,sizeof(hello2));	//非阻塞模式
  HAL_Delay(10);

  printf("对于STM32F407,只可以ADC1和ADC2组合为二重ADC,并应该启用使用DMA模式。\r\n");
  printf("当规则转换组有多个通道时,还应该使用扫描转换模式(Scan Conversion Mode),\r\n");
  printf("MCU管脚PF8,是外部模拟量输入通道,接可调电阻产生的可变电压。\r\n");
  printf("ADC1_IN0对应MCU管脚PA0,用导线把PA0连接PF8。\r\n");
  printf("ADC2_IN1对应MCU管脚PA1,用导线把PA1连接PF8。\r\n\r\n");

  HAL_ADCEx_MultiModeStart_DMA(&hadc1, dmaDataBuffer, BATCH_DATA_LEN);	// Start ADC1
  HAL_ADCEx_MultiModeStart_DMA(&hadc2, dmaDataBuffer, BATCH_DATA_LEN);	// Start ADC2
  HAL_TIM_Base_Start(&htim3);											// Start TIM3
  /* USER CODE END 2 */
/* USER CODE BEGIN 4 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
	uint32_t Volt;
	uint32_t adcValue=dmaDataBuffer[0];			// Data for ADC2 and ADC1

	uint32_t ADC1_val = adcValue & 0x0000FFFF;	// The lower 16 bits are the data of ADC1
	Volt=3300*ADC1_val;
	Volt=Volt>>12;
	printf("ADC1 = %ld\r\n",Volt );

	uint32_t ADC2_val = adcValue & 0xFFFF0000;	// The higher 16 bits are the data of ADC2
	ADC2_val = ADC2_val>>16;
	Volt=3300*ADC2_val;							// mV unit
	Volt=Volt>>12;								// divided by 2^12
	printf("ADC2 = %ld\r\n",Volt );
}

//串口打印
int __io_putchar(int ch)
{
	HAL_UART_Transmit(&huart6, (uint8_t*)&ch, 1, 0xFFFF);
	return ch;
}
/* USER CODE END 4 */

三、运行与调试

        首次下载或运行,最先显示在串口助手上的是程序的菜单设计:

        之后,连续显示ADC1_IN0和ADC2_IN1采集到的数据,因为二重ADC的各自的数据通道采用默认设置的相同的触发信号,因此是同步采集。


http://www.niftyadmin.cn/n/5864191.html

相关文章

nextjs项目搭建——头部导航

Header.tsx 在src/app/component路径下&#xff0c;创建Header.tsx use client;import Link from next/link; import { usePathname } from next/navigation; import Logo from ./Logo;const Header () > {const pathname usePathname();const navItems [{ label: 首页…

本地部署Qwen2.5-VL-7B-Instruct多模态视觉大模型(Windows篇)

本文已首发于 秋码记录 如果你也想搭建一个与秋码记录一样的网站&#xff0c;可以浏览我的这篇 国内 gitee.com Pages 下线了&#xff0c;致使众多站长纷纷改用 github、gitlab Pages 托管平台 秋码记录网站使用的主题是开源的&#xff0c;目前只在github.com开源。 hugo-the…

Windows PyCharm的python项目移动存储位置后需要做的变更

项目使用的venv虚拟环境&#xff0c;因此项目移动存储位置后需要重新配置python解释器的位置&#xff0c;否则无法识别&#xff0c;若非虚拟环境中运行&#xff0c;则直接移动后打开即可&#xff0c;无需任何配置。 PyCharm版本为2021.3.3 (Professional Edition)&#xff0c;其…

选择排序和计数排序

选择排序和计数排序 选择排序 定义 选择排序是一种简单直观的排序算法。它的基本思想是在每一趟遍历中找到未排序部分中的最小元素&#xff0c;并将其放到正确的位置上。 操作步骤 初始化&#xff1a;设数组长度为 n。外层循环&#xff1a;控制需要选择的位置 i&#xff0c;从 …

java实现多图合并加字和画框等

java实现多图合并加字和画框等 在wutool中&#xff0c;封装了图片处理工具类&#xff0c;基于java自带的BufferedImage类&#xff0c;实现多图合并和加字、图片画框等。 关于wutool wutool是一个java代码片段收集库&#xff0c;针对特定场景提供轻量解决方案&#xff0c;只要…

系统讨论Qt的并发编程——逻辑上下文的分类

目录 前言 首先&#xff0c;讨论Qt里常见的三种上下文 同一线程的串行执行 同一线程的异步执行 多线程的执行 moveToThread办法 前言 笔者最近看了一个具备一定启发性质的Qt教程&#xff0c;在这里&#xff0c;笔者打算整理一下自己的笔记。分享在这里. 首先&#xff0c…

福昕阅读器方便快捷方法技巧

标题 福昕阅读器方便快捷 1 快捷键设置&#xff1a; 常用有&#xff1a;高亮、绘图矩形、打字机等

Visual Studio更新说明(关注:.NET+AI生产力)

Ver V0.0&#xff1a;Visual Studio 2022 v17.12更新:.NET9AI生产力 AI插件推荐 &#xff08;1&#xff09;腾讯云AI代码手&#xff08;内含了DeepSeek-R1&#xff09;&#xff0c;目前免费&#xff0c;但收费我也可能会买。 AI插件!推荐 &#xff08;1&#xff09;百度的…