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

news2024/9/28 17:34:20

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、测试结果

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2088952.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

雀巢玩了个梗,把打工人快得罪光了……

给打工人做了一款零食,并想着抖个机灵顺便讨好下打工人,但万万没想到,这零食刚到打工人手里还没等下嘴,就把打工人给得罪了…… 这是让浓眉大眼的雀巢最近无比糟心的一件事! 事情大概是这样的,雀巢可能是为…

图论----最小生成树讲解与相关题解

目前已更新系列 当前--图论----最小生成树讲解与相关题解 滑动窗口系列算法总结与题解一 算法系列----并查集总结于相关题解 图论---dfs系列 差分与前缀和总结与对应题解(之前笔试真的很爱考) 数论---质数判断、质因子分解、质数筛(埃氏…

信息学奥赛初赛天天练-79-NOIP2015普及组-基础题4-即时通讯软件、二叉树遍历、前序遍历、中序遍历、后序遍历、算法时间复杂度

NOIP 2015 普及组 基础题4 11 下面哪种软件不属于即时通信软件( ) A QQ B MSN C 微信 D P2P 16 前序遍历序列与中序遍历序列相同的二叉树为( ) A 根结点无左子树 B 根结点无右子树 C 只有根结点的二叉树或非叶子结点只有左子树的二叉树 D 只有根结点的二叉树或非叶子结点只有…

如何使用IDEA远程访问家里或者公司中无公网IP的内网MySQL数据库

文章目录 前言1. 本地连接测试2. Windows安装Cpolar3. 配置Mysql公网地址4. IDEA远程连接Mysql5. 固定连接公网地址6. 固定地址连接测试 前言 本教程主要介绍如何使用Cpolar内网穿透工具实现在IDEA中也可以远程访问家里或者公司的数据库,提高开发效率!无…

在 Debian 上安装 IntelliJ IDEA 笔记(含 JDK 的安装)

在 Debian💩 上安装 IntelliJ IDEA 💡 笔记(含 JDK 的安装) 下载安装 JDKJDK17JDK8 安装 IntelliJ IDEA Community添加桌面启动项(快捷方式) 参考资料 下载 两个包已经下好了,一个JDK17&#x…

OZON新品藏品,OZON收藏品推荐

OZON新品藏品,OZON收藏品推荐Top1 火车模型 Наши поезда №17 - Пассажирский электровоз ЧС2 商品id:1643982093 月销量:266 OZON新品藏品地:m6z.cn/5H6fQR(浏览器复制打开&a…

<数据集>车牌识别数据集<目标检测>

数据集格式:VOCYOLO格式 图片数量:2000张 标注数量(xml文件个数):2000 标注数量(txt文件个数):2000 标注类别数:1 标注类别名称:[License] 序号类别名称图片数框数1License20002965 使用标注工具&am…

嵌入式单片机开发学习路线,从入门到高薪就业,保姆级学习攻略!

嵌入式就业方向及具体细分岗位如下: 方向 岗位 单片机开发 单片机开发工程师(MCU开发工程师) RTOS开发工程师 Linux应用开发 Linux应用工程师 QT开发工程师 Linux多媒体开发工程师 Linux驱动开发 Linux/Android驱动开发工程师 Linux设…

【建议收藏】100个Python精选库

Python为啥这么火,这么多人学,就是因为简单好学,功能强大,整个社区非常活跃,资料很多。而且这语言涉及了方方面面,比如自动化测试,运维,爬虫,数据分析,机器学…

鸿蒙(API 12 Beta3版)【识别图像数据】

基本概念 图像数据识码能力支持对相机预览流数据中的码图进行扫描识别,并获取信息。 场景介绍 图像数据识码能力支持对相机预览流数据中的条形码、二维码、MULTIFUNCTIONAL CODE进行识别,并获得码类型、码值、码位置信息和相机变焦比。该能力可用于一…

马斯克被告“狗狗币传销”!索赔2580亿美元,法官驳回诉讼!马斯克与狗狗币的不解之缘!

在数字货币领域,每一次波动都牵动着全球投资者的神经,而埃隆马斯克(Elon Musk)——这位科技界的传奇人物,更是以其独特的言行不断在加密货币市场上掀起波澜。近期,关于马斯克与狗狗币(Dogecoin&…

【C++STL详解(十三)】unordered系列容器的介绍与使用

目录 前言 一、unordered_map 介绍 使用 构造方式 修改 容量 迭代器 元素访问 查询 桶操作 二、unordered_set 介绍 使用 构造 修改 容量 迭代器(只有单向) 查询 桶操作 三、unordered系列的性能测试 前言 前面提到的map/set是C98提供的关联…

使用手机挖掘IDOR漏洞赚取1500美元赏金

在今天的文章中,笔者将分享如何在手机上发现两个不安全的直接对象引用 (IDOR) 实例,并因此获得 1500 美元的赏金。 信息收集:了解目标 首先,我通常使用 Google dork(谷歌语法:如“site:target.com about”…

斯坦福UE4 C++课学习补充24:伤害数值

创建并调用数值显示UI 显示数值用UMG实现。创建名为DamagePopup_Widget控件蓝图,添加一个数值文本框。设置如下,设置文本框为Is Variable 将场景投射到屏幕Project World Location to Widget Position节点:它的作用是在UE中将一个世界空间中…

智能新未来:2024世界机器人大会全景解析

8月21日至25日,2024世界机器人大会在北京北人亦创国际会展中心盛大举行。本次大会以“共育新质生产力 共享智能新未来”为主题,汇聚了全球近170家机器人企业,展示了超过600款创新产品,其中首发新品达60余款,人形机器人…

晚宴扫码查询座位号

在晚宴活动中,快速准确地查询座位号是提升参与者体验的关键。以下是通过扫码查询系统实现座位号查询的详细步骤。 步骤一:电脑端上传查询信息 1. 访问云分组官网。 2. 使用微信扫码登录系统。 3. 点击菜单“我的查询”。 步骤二:准备查询信…

文心快码帮你解大厂面试题:如何使用shell找到access log,如何找到访问量最多的url?

🎁👉点击进入文心快码 Baidu Comate 官网,体验智能编码之旅,还有超多福利!🎁 【大厂面试真题】系列,带你攻克大厂面试真题,秒变offer收割机! ❓今日问题:在8…

Java框架spring(二)

一、AOP面向切面编程 1、AOP的概念 AOP(AspectOrientedProgramming),意为:面向切面编程,通过 预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。 AOP是OOP的延续,是软件开发中的一个热点&…

URP custompasscustom render objects 下

上文 https://blog.csdn.net/qq_35158695/article/details/141708043?spm1001.2014.3001.5501 上次说了绘制流程,还需要指定FBO 在renderpass的这个configure函数里,设置render target 这里的纹理是从shader里map出来的ID,不过我看他文章没…