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

 

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

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

相关文章

顺序表和链表知识点

1 顺序表 顺序表是指用一段物理地址连续的空间去存储数据的线性结构。 顺序表有两种:静态顺序表,动态顺序表。 1.1 静态顺序表结构体定义 typedef int ElemDataSL;typedef struct SequeList {ElemDataSL arr[100];int size; }SL; 静态顺序表在创建结构体…

【 html+css 绚丽Loading 】000026 五行吞灵盘

前言:哈喽,大家好,今天给大家分享htmlcss 绚丽Loading!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 &#x1f495…

网络安全领域含金量最高的5大赛事,每个网安人的梦!

做网络安全一定要知道的5大赛事,含金量贼高,如果你能拿奖,国内大厂随你挑,几乎是每个有志网安人的梦! 一、 DEF CON CTF(DEF CON Capture the Flag) DEF CON CTF是DEF CON黑帽大会上的一项著名…

江协科技STM32学习- P7 GPIO输入

🚀write in front🚀 🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝​…

数据结构(树、平衡树、红黑树)

目录 树 树的遍历方式 平衡二叉树 旋转机制 左旋 右旋 旋转实例 左左 左右 右右 右左 总结 红黑树 树 相关概念 节点的内部结构如下 二叉树与二叉查找树的定义如下 树的遍历方式 前序遍历:当前节点,左子节点,右子结点 中序遍…

string的模拟实现与深浅拷贝

在上一章中可以看见,string类函数的基本实现和用法,在本文。来用基础的语言来模拟实现string类,来了解一下他们的基础底层; 在VS中string,我们可以看见,实现VS的类成员很多,很麻烦; …

【STM32】电容触摸按键

电容按键就是酷,但据我使用过电容按键版的洗澡计费机子后,一生黑(湿手优化没做好的电容按键简直稀碎)。 大部分图片来源:正点原子HAL库课程 专栏目录:记录自己的嵌入式学习之路-CSDN博客 目录 1 触摸按…

Zookeeper官网Java示例代码解读(一)

2024-08-22 1. 基本信息 官网地址: https://zookeeper.apache.org/doc/r3.8.4/javaExample.html 示例设计思路 Conventionally, ZooKeeper applications are broken into two units, one which maintains the connection, and the other which monitors data. I…

【C++ Primer Plus习题】7.5

问题: 解答: #include <iostream> using namespace std;int function(int n) {if (n 0)return 1;if (n 1)return 1;return n* function(n - 1); }int main() {int value 0;while (true){cout << "请输入数字:";cin >> value;cout << val…

华为Huawei路由器交换机SSH配置

华为设备的SSH登录配置需要5个步骤&#xff0c;示例如下&#xff1a; 一、配置命令 使能SSH功能 stelnet server enable生成公钥 rsa local-key-pair create 1024配置AAA用户密码及相应授权 aaalocal-user xxx password cipher xxxyyy1234local-user xxx privilege level …

ADB 获取屏幕坐标,并模拟滑动和点击屏幕

本文声明:本文是参考https://blog.csdn.net/beyond702/article/details/69258932编制。同时,补充了在windows系统模式下,详细的获取屏幕坐标的步骤。 1.判断设备与windows电脑USB连接是否正常 在CMD窗口输入命令:ADB devices,按ENTER键,输出如下结果,则表示连接正常。 …

Prometheus+Grafana监控数据可视化

上一篇文章讲了prometheus的简单使用&#xff0c;这一篇就先跳过中间略显枯燥的内容&#xff0c;来到监控数据可视化。 一方面&#xff0c;可视化的界面看着更带劲&#xff0c;另一方面&#xff0c;也更方便我们直观的查看监控数据&#xff0c;方便后面的学习。 Grafana安装与…

DIFFUSION 系列笔记| Latent Diffusion Model、Stable Diffusion基础概念、数学原理、代码分析、案例展示

目录 Latent Diffusion Model LDM 主要思想 LDM使用示例 LDM Pipeline LDM 中的 UNET 准备时间步 time steps 预处理阶段 pre-process 下采样过程 down sampling 中间处理 mid processing 上采样 upsampling 后处理 post-process LDM Super Resolution Pipeline…

Redis基本全局命令

文章目录 get和setkeysexistsdelexpirettltype redis全局命令&#xff1a; redis支持很多种数据结构&#xff0c;整体上来说。redis是键值对结构&#xff0c;key固定就是字符串&#xff0c;value实际上就会有很多种&#xff0c;比如说&#xff1a; 字符串哈希表列表有序集合 …

住宅物业满意度计算方式中满意率和满意度指数的区别

满意率和满意度指数是用于计算住宅物业满意度的两种不同方式&#xff0c;它们的区别如下&#xff1a; 1、满意率&#xff1a;满意率是通过计算满意的居民人数与总参与调查的居民人数之间的比例来衡量满意度。它以百分比形式表示&#xff0c;可以直观地了解居民对物业管理的整体…

集运系统如何多维度展现企业业务情况?

在集运行业&#xff0c;数据是企业决策的重要依据。为了在竞争中保持优势&#xff0c;企业需要一套高效、灵活且可靠的管理工具来应对市场的快速变化。易境通集运系统以其全面而精细的统计报表功能&#xff0c;成为企业决策优化和业务增长的重要助手。 易境通集运系统https://…

使用在AMD GPU上运行的ROCm进行大语言模型的自然语言处理任务

Performing natural language processing tasks with LLMs on ROCm running on AMD GPUs — ROCm Blogs 在这篇博客中&#xff0c;您将学习如何使用在AMD的Instinct GPU上运行的ROCm进行一系列流行且有用的自然语言处理&#xff08;NLP&#xff09;任务&#xff0c;使用不同的大…

新手该如何选择与小程序定位相关的关键词

关键词的优化是提高小程序排名的关键步骤之一&#xff0c;所以如何选择与小程序定位相关的关键词是一个很重要的过程&#xff0c;需要考虑多个因素以确保关键词既符合小程序的业务特性&#xff0c;又能吸引目标用户。以下是一些具体的步骤和建议&#xff1a; 1. 深入了解小程序…

Go发布自定义包

1、初始化go.mod go mod init github.com/xumeng03/images2、编写包内容 这里只是一个简单的压缩jpg/jpeg图片例子&#xff0c;代码参考 https://github.com/disintegration/imaging 2.1、fs.go package imagesimport ("image""io""os""p…

Vue3中的defineExpose的认识

文章目录 defineExpose子组件父组件&#xff1a;总结&#xff1a; defineExpose 使用 <script setup> 的组件是默认关闭的——即通过模板引用或者 $parent 链获取到的组件的公开实例&#xff0c;** 不会 **暴露任何在 <script setup> 中声明的绑定。 可以通过 def…