STM32G474采用“多个单通道ADC转换”读取3个ADC引脚的电压

2024-08-28 05:52

本文主要是介绍STM32G474采用“多个单通道ADC转换”读取3个ADC引脚的电压,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

STM32G474采用“多个单通道ADC转换”读取3个ADC引脚的电压:PC0、PA1和PA2。本测试将ADC1_IN6映射到PC0引脚,ADC12_IN2映射到PA1引脚,ADC1_IN3映射到PA2引脚。

 1、ADC输入

ADC输入电压范围:Vref– ≤ VIN ≤ Vref+


ADC支持“单端输入”:
在“单端输入模式”下,“通道i”的模拟电压等于VINP[i]和VREF-之间的差值


ADC支持“差动输入”:
在“差动输入模式”下,“通道i”的模拟电压等于VINP[i]和VINN[i]之间的差值
1)、当VINP[i]等于VREF-时,VINN[i]等于VREF+,最大负输入差分电压(VREF-)对应于0x000 ADC输出;
2)、当VINP[i]等于VREF+时,VINN[i]等于VREF-,最大正输入差分电压(VREF+)对应于0xFFF ADC输出;
3)、当VINP[i]和VINN[i]连接在一起时,零输入差分电压对应于0x800 ADC输出;

2、测试程序

ADC_HandleTypeDef   hadc1;
__IO uint16_t ADC1_RESULT[3];

void ADC1_Init(void);
void Read_ADC_Value_Use_SoftwareTriger(void);

void ADC1_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* Peripheral clock enable */
  __HAL_RCC_ADC12_CLK_ENABLE(); //使能“ADC1和ADC2时钟”
    __HAL_RCC_GPIOC_CLK_ENABLE(); //使能“PC口时钟”

  GPIO_InitStruct.Pin = GPIO_PIN_0;        //选择编号为0的引脚
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; //模拟模式
  GPIO_InitStruct.Pull = GPIO_NOPULL;      //引脚上拉和下拉都没有被激活
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    //根据GPIO_InitStruct结构变量指定的参数初始化GPIOC的外设寄存器
    //将ADC1_IN6映射到PC0引脚

    __HAL_RCC_GPIOA_CLK_ENABLE();              //使能“PA口时钟”
  GPIO_InitStruct.Pin=GPIO_PIN_1|GPIO_PIN_2; //选择编号为1和2的引脚
  GPIO_InitStruct.Mode=GPIO_MODE_ANALOG;          //模拟模式
  GPIO_InitStruct.Pull=GPIO_NOPULL;                  //引脚上拉和下拉都没有被激活
  HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);
    //根据GPIO_InitStruct结构变量指定的参数初始化GPIOA的外设寄存器
    //将ADC12_IN2映射到PA1引脚,将ADC1_IN3映射到PA2引脚

/***********************************************/
    hadc1.Instance = ADC1;   //选择ADC1
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
    //分频系数:4分频,ADCCLK=PCLK2/4=170/4=42.5MHZ
    //设置ADCx_CCR寄存器bit17:16(CKMODE[1:0]]),CKMODE[1:0]=11,adc_hclk/4

  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
    //分辨率:12位模式
    //设置ADC_CFGR寄存器bit4:3(RES[1:0]),令RES[1:0]=00b,AD转换结果为12位

  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    //对齐方式:右对齐
    //设置ADC_CFGR寄存器bit15(ALIGN位),令ALIGN=0,AD转换结果为“右对齐”

  hadc1.Init.GainCompensation = 0;
    //ADC增益设置为0
    //设置ADC_CFGR2寄存器bit16(GCOMP),令GCOMP=0,常规ADC工作模式

  hadc1.Init.NbrOfConversion = 1;
    //“正则通道序列长度”为1,只有有1个AD转换
    //设置ADC_SQR1寄存器的bit3:0(L[3:0]),令L[3:0]=1-1,表示“正则通道序列长度”为1,有1个AD转换

    hadc1.Init.NbrOfDiscConversion=0;//不连续采样通道数为0
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
    //因为hadc1.Init.NbrOfConversion = 1,所以要使用“单通道转换”
    //如果是单通道转换使用ADC_SCAN_DISABLE
    //如果是多通道转换使用ADC_SCAN_ENABLE。

  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
    //ADC触发源选择“软件触发AD转换”
    //设置HRTIM->ADC1R寄存器bit5(ADC1EEV1位),ADC1EEV1=0,使用“内部软件”触发一次ADC转换

  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
    //上升沿触发
    //设置ADC->CFGR寄存器bit11:10(EXTEN[1:0]),EXTEN[1:0]=01b,硬件触发检测为上升沿

  hadc1.Init.ContinuousConvMode = DISABLE;
    //因为要采用“软件触发AD转换”,所以要用“单次转换”
    //使用ENABLE配置为使能自动连续转换;
    //使用DISABLE配置为单次转换,转换一次后停止,需要手动控制才重新启动转换
    //设置ADC_CFGR寄存器bit13(CONT位),令CONT=1,ADC采用“连续转换模式”

    hadc1.Init.SamplingMode=ADC_SAMPLING_MODE_NORMAL;
    //设置ADC_CFGR2寄存器bit27(SMPTRIG),令SMPTRIG=0,禁用“ADC轮询采样模式”
    //ADC转换采样相位持续时间

  hadc1.Init.DiscontinuousConvMode = DISABLE;
    //设置ADC_CFGR寄存器bit16(DISCEN位),令DISCEN=0,对于常规通道,禁止“不连续采样模式”

  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
    //ADC_EOC_SINGLE_CONV和 ADC_EOC_SEQ_CONV,指定转换结束时是否产生EOS中断或事件标志
    //配置ADC_IER寄存器bit2(EOCIE位),EOCIE=1,使能ADC转换完成产生中断

  hadc1.Init.LowPowerAutoWait = DISABLE;
    //配置是否使用低功耗自动延迟等待模式:关闭低功耗模式
    //配置ADC_CR寄存器bit29(DEEPPWD位),令DEEPPWD=0,ADC not in Deep-power down
    //可选参数为 ENABLE 和DISABLE,当使能时,仅当一组内所有之前的数据已处理完毕时
    //才开始新的转换,适用于低频应用。该模式仅用于 ADC 的轮询模式,不可用于 DMA 以及中断

  hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
    //数据溢出覆盖;当过载发生时,使用ADC_DR的新值覆盖
    //设置ADC_CFGR寄存器bit12(OVRMOD),令OVRMOD=1,当检测到溢出时,将用最后一个转换结果覆盖ADC_DR寄存器

  hadc1.Init.OversamplingMode = DISABLE;
    //设置ADC_CFGR2寄存器bit27(SMPTRIG),令SMPTRIG=1,启用过采样功能
    //这里需要设置为DISABLE,否则数据会发生错误,不清楚HAL库这么做,有什么用

  hadc1.Init.DMAContinuousRequests = DISABLE;
    //不开启DMA请求连续模式或者单独模式
    //设置ADC_CFGR寄存器bit0(DMAEN),令DMAEN=0,不使能DMA

    HAL_ADC_Init(&hadc1);
}

void Read_ADC_Value_Use_SoftwareTriger(void)
{
    float f;
    ADC_ChannelConfTypeDef sConfig = {0};

    LED1_Toggle();

  sConfig.Channel = ADC_CHANNEL_6;//ADC通道6,前面已将ADC1_IN6映射到PC0引脚
  sConfig.Rank = ADC_REGULAR_RANK_1;
    //设置ADC_SQR1寄存器bit10:6(SQ1[4:0]),SQ1[4:0]=6,即AD通道6的序号为1
    //AD转换顺序排列:配置通道3位于“第1个序列”

  sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
    //采样时间
    //设置ADC_SMPR1寄存器bit8:6(SMP2[2:0]),SMP2[2:0]=000b,2.5 ADC clock cycles

  sConfig.SingleDiff = ADC_SINGLE_ENDED;
    //配置ADC通道输入为“单端模式”,非“差动输入模式”
  sConfig.OffsetNumber = ADC_OFFSET_NONE;//无偏移数量
  sConfig.Offset = 0;//偏移量=0
    HAL_ADC_ConfigChannel(&hadc1, &sConfig);//配置AD通道6的序号为1
    HAL_ADC_Start(&hadc1);//启动一次AD转换
    HAL_ADC_PollForConversion(&hadc1,10);
    //等待“常规组”转换完成
    //Wait for regular group conversion to be completed

  ADC1_RESULT[0]=HAL_ADC_GetValue(&hadc1);
    //获取ADC“常规组”转换结果
    //Get ADC regular group conversion result.
//    HAL_ADC_Stop(&hadc1);
    //停止常规组的ADC转换,禁用ADC外设。
    //Stop ADC conversion of regular group,disable ADC peripheral.


  sConfig.Channel = ADC_CHANNEL_2;//ADC通道6,前面已将ADC12_IN2映射到PA1引脚
  sConfig.Rank = ADC_REGULAR_RANK_1;
    //设置ADC_SQR1寄存器bit10:6(SQ1[4:0]),SQ1[4:0]=2,即AD通道2的序号为2
    //AD转换顺序排列:配置通道3位于“第1个序列”

  sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
    //采样时间
    //设置ADC_SMPR1寄存器bit8:6(SMP2[2:0]),SMP2[2:0]=000b,2.5 ADC clock cycles

  sConfig.SingleDiff = ADC_SINGLE_ENDED;
    //配置ADC通道输入为“单端模式”,非“差动输入模式”
  sConfig.OffsetNumber = ADC_OFFSET_NONE;//无偏移数量
  sConfig.Offset = 0;//偏移量=0
    HAL_ADC_ConfigChannel(&hadc1, &sConfig);//配置AD通道2的序号为2
    HAL_ADC_Start(&hadc1);//启动一次AD转换
    HAL_ADC_PollForConversion(&hadc1,10);
    //等待“常规组”转换完成
    //Wait for regular group conversion to be completed

  ADC1_RESULT[1]=HAL_ADC_GetValue(&hadc1);
    //获取ADC“常规组”转换结果
    //Get ADC regular group conversion result.


  sConfig.Channel = ADC_CHANNEL_3;//ADC通道3,前面已将ADC1_IN3映射到PA2引脚
  sConfig.Rank = ADC_REGULAR_RANK_1;
    //设置ADC_SQR1寄存器bit10:6(SQ1[4:0]),SQ1[4:0]=3,即AD通道3的序号为3
    //AD转换顺序排列:配置通道3位于“第1个序列”

  sConfig.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
    //采样时间
    //设置ADC_SMPR1寄存器bit8:6(SMP2[2:0]),SMP2[2:0]=000b,2.5 ADC clock cycles

  sConfig.SingleDiff = ADC_SINGLE_ENDED;
    //配置ADC通道输入为“单端模式”,非“差动输入模式”
  sConfig.OffsetNumber = ADC_OFFSET_NONE;//无偏移数量
  sConfig.Offset = 0;//偏移量=0
    HAL_ADC_ConfigChannel(&hadc1, &sConfig);//配置AD通道3的序号为3
  HAL_ADC_Start(&hadc1);//启动一次AD转换
    HAL_ADC_PollForConversion(&hadc1,10);
    //等待“常规组”转换完成
    //Wait for regular group conversion to be completed

  ADC1_RESULT[2]=HAL_ADC_GetValue(&hadc1);
    //获取ADC“常规组”转换结果
    //Get ADC regular group conversion result.

    printf("ADC1_RESULT[0]=0x%X\r\n",ADC1_RESULT[0]);
    printf("ADC1_RESULT[1]=0x%X\r\n",ADC1_RESULT[1]);
    printf("ADC1_RESULT[2]=0x%X\r\n",ADC1_RESULT[2]);

    f=ADC1_RESULT[0];f=f/4096;f=f*3300;
    printf("PC0=%0.1fmV\r\n",f);

    f=ADC1_RESULT[1];f=f/4096;f=f*3300;
    printf("PA1=%0.1fmV\r\n",f);

    f=ADC1_RESULT[2];f=f/4096;f=f*3300;
    printf("PA2=%0.1fmV\r\n",f);
}

3、测试结果

 

这篇关于STM32G474采用“多个单通道ADC转换”读取3个ADC引脚的电压的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1113914

相关文章

Linux使用dd命令来复制和转换数据的操作方法

《Linux使用dd命令来复制和转换数据的操作方法》Linux中的dd命令是一个功能强大的数据复制和转换实用程序,它以较低级别运行,通常用于创建可启动的USB驱动器、克隆磁盘和生成随机数据等任务,本文... 目录简介功能和能力语法常用选项示例用法基础用法创建可启动www.chinasem.cn的 USB 驱动

使用SQL语言查询多个Excel表格的操作方法

《使用SQL语言查询多个Excel表格的操作方法》本文介绍了如何使用SQL语言查询多个Excel表格,通过将所有Excel表格放入一个.xlsx文件中,并使用pandas和pandasql库进行读取和... 目录如何用SQL语言查询多个Excel表格如何使用sql查询excel内容1. 简介2. 实现思路3

Python 标准库time时间的访问和转换问题小结

《Python标准库time时间的访问和转换问题小结》time模块为Python提供了处理时间和日期的多种功能,适用于多种与时间相关的场景,包括获取当前时间、格式化时间、暂停程序执行、计算程序运行时... 目录模块介绍使用场景主要类主要函数 - time()- sleep()- localtime()- g

Java读取InfluxDB数据库的方法详解

《Java读取InfluxDB数据库的方法详解》本文介绍基于Java语言,读取InfluxDB数据库的方法,包括读取InfluxDB的所有数据库,以及指定数据库中的measurement、field、... 首先,创建一个Java项目,用于撰写代码。接下来,配置所需要的依赖;这里我们就选择可用于与Infl

C#读取本地网络配置信息全攻略分享

《C#读取本地网络配置信息全攻略分享》在当今数字化时代,网络已深度融入我们生活与工作的方方面面,对于软件开发而言,掌握本地计算机的网络配置信息显得尤为关键,而在C#编程的世界里,我们又该如何巧妙地读取... 目录一、引言二、C# 读取本地网络配置信息的基础准备2.1 引入关键命名空间2.2 理解核心类与方法

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

SpringBoot使用Apache POI库读取Excel文件的操作详解

《SpringBoot使用ApachePOI库读取Excel文件的操作详解》在日常开发中,我们经常需要处理Excel文件中的数据,无论是从数据库导入数据、处理数据报表,还是批量生成数据,都可能会遇到... 目录项目背景依赖导入读取Excel模板的实现代码实现代码解析ExcelDemoInfoDTO 数据传输

Python读取TIF文件的两种方法实现

《Python读取TIF文件的两种方法实现》本文主要介绍了Python读取TIF文件的两种方法实现,包括使用tifffile库和Pillow库逐帧读取TIFF文件,具有一定的参考价值,感兴趣的可以了解... 目录方法 1:使用 tifffile 逐帧读取安装 tifffile:逐帧读取代码:方法 2:使用

Java将时间戳转换为Date对象的方法小结

《Java将时间戳转换为Date对象的方法小结》在Java编程中,处理日期和时间是一个常见需求,特别是在处理网络通信或者数据库操作时,本文主要为大家整理了Java中将时间戳转换为Date对象的方法... 目录1. 理解时间戳2. Date 类的构造函数3. 转换示例4. 处理可能的异常5. 考虑时区问题6.

基于C#实现将图片转换为PDF文档

《基于C#实现将图片转换为PDF文档》将图片(JPG、PNG)转换为PDF文件可以帮助我们更好地保存和分享图片,所以本文将介绍如何使用C#将JPG/PNG图片转换为PDF文档,需要的可以参考下... 目录介绍C# 将单张图片转换为PDF文档C# 将多张图片转换到一个PDF文档介绍将图片(JPG、PNG)转