STM32CubeMX学习笔记8 -ADC

news2024/12/23 4:40:52

1. ADC简介

        ADC 是Analog-to-Digital Converter的缩写。指模/数转换器或者模拟/数字转换器。是指将连续变量的模拟信号转换为离散的数字信号的器件。典型的模拟数字转换器将模拟信号转换为表示一定比例电压值的数字信号。简单地说就是将模拟电压值,转换成对应的肉眼可读数值

        12位ADC是一种逐次逼近型模拟数字转换器。它有,3个ADC控制器,多达18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。

        12位模拟数字转换器就是ADC的数字存储是12位的 也就是说转换器通过采集转换所得到的最大值是4095 “111111111111”=4095 二进制的12位可表示0-4095个数, 对应着所测电压的实际值,转换的电压范围是0v-3.3v的话,转换器就会把0v-3.3v平均分成4096份。设转换器所得到的值为x,所求电压值为y。

同理,可以理解8位精度和10位精度

具体的转压范围下面我们会讲

3个ADC控制器
就是说STM32一共有3个ADC ADC1,ADC2,ADC3

18个通道
STM32 的ADC 多达18 个通道,
16个外部通道和2个内部信号源 具体是哪一个IO 口可以从手册查询到

STM32F10x系列芯片ADC通道和引脚对应关系 :
16个外部通道:芯片上有16个引脚是可以接到模拟电压上进行电压值检测的

2个内部信号源 : 一个是内部温度传感器,一个是内部参考电压

一共支持23个引脚支持ADC,包括21个外部和2个内部信号源

ADC的转换模式 (重要,请务必看懂)
1 单次转换模式:ADC只执行一次转换;

2 连续转换模式:转换结束之后马上开始新的转换;

3 扫描模式:ADC扫描被规则通道和注入通道选中的所有通道,在每个组的每个通道上执行单次转换。在每个转换结束时,这一组的下一个通道被自动转换。如果设置了CONT位(开启了连续 转换模式),转换不会在选择组的最后一个通道上停止,而是再次从选择组的第一个通道继续转换。

4 间断模式:触发一次,转换一个通道,在触发,在转换。在所选转换通道循环,由触发信号启动新一轮的转换,直到转换完成为止。

扫描模式简单的说是一次对所有所选中的通道进行转换,比如开了ch0,ch1,ch4,ch5。  ch0转换完以后就会自动转换通道1,4,5直到转换完这个过程不能被打断。如果开启了连续转换模式,则会在转换完ch5之后开始新一轮的转换。

这就引入了间断模式,可以说是对扫描模式的一种补充。它可以把0,1,4,5这四个通道进行分组。可以分成0,1一组,4,5一组。也可以每个通道单独配置为一组。这样每一组转换之前都需要先触发一次。

ADC单通道:

只进行一次ADC转换:配置为“单次转换模式”,扫描模式关闭。ADC通道转换一次后,就停止转换。等待再次使能后才会重新转换

进行连续ADC转换:配置为“连续转换模式”,扫描模式关闭。ADC通道转换一次后,接着进行下一次转换,不断连续。

ADC多通道:

只进行一次ADC转换:配置为“单次转换模式”,扫描模式使能。ADC的多个通道,按照配置的顺序依次转换一次后,就停止转换。等待再次使能后才会重新转换

进行连续ADC转换:配置为“连续转换模式”,扫描模式使能。ADC的多个通道,按照配置的顺序依次转换一次后,接着进行下一次转换,不断连续。

也就是:多通道必须使能扫描模式

上面转换模式介绍一部分为转自他人

左对齐或右对齐
因为ADC得到的数据是12位精度的,但是数据存储在 16 位数据寄存器中,所以ADC的存储结果可以分为左对齐或右对齐方式(12位)


ADC的工作框图


图:stm32f103参考手册
接下来我们介绍下ADC的工作框图,让您有个更直白地了解,涉及到寄存器的一些部分不再详细讲解,

1、电压输入范围

ADC一般用于采集小电压,其输入值不能超过VDDA,即ADC输入范围:VREF- ≤ VIN ≤ VREF+。具体的定义见上图。
一般把VSSA和VREF- 接地, VREF+ 和 VDDA接3V3,那么ADC的输入范围是0~3.3V。

2、ADC输入通道
ADCx_INT0-ADCx_INT15 对应三个ADC的16个外部通道,进行模拟信号转换 此外,还有两个内部通道:温度检测或者内部电压检测
选择对应通道之后,便会选择对应GPIO引脚,相关的引脚定义和描述可在开发板的数据手册里找

3、注入通道,规则通道
我们看到,在选择了ADC的相关通道引脚之后,在模拟至数字转换器中有两个通道,注入通道,规则通道,规则通道至多16个,注入通道至多4个

规则通道:

规则通道相当于你正常运行的程序,看它的名字就可以知道,很规矩,就是正常执行程序
注入通道:
注入通道可以打断规则通道,听它的名字就知道不安分,如果在规则通道转换过程中,有注入通道进行转换,那么就
要先转换完注入通道,等注入通道转换完成后,再回到规则通道的转换流程


图:正点原子
你可以通过上图有一个更直观的认识,可以简单地把注入通道理解为中断形式,可以更好理解

4、ADC时钟
        ADC预分频器的ADCCLK是ADC模块的时钟来源。通常,由时钟控制器提供的ADCCLK时钟和PCLK2(APB2时钟)同步。RCC控制器为ADC时钟提供一个专用的可编程预分频器。 分频因子由RCC_CFGR的ADCPRE[1:0]配置,可配置2/4/6/8分频

STM32的ADC最大的转换速率为1MHz,也就是说最快转换时间为1us,为了保证ADC转换结果的准确性,ADC的时钟最好不超过14M

T = 采样时间 + 12.5个周期,其中1周期为1/ADCCLK

例如,当 ADCCLK=14Mhz 的时候,并设置 1.5 个周期的采样时间,则得到: Tcovn=1.5+12.5=14 个周期=1us。

5、外部触发转换
ADC 转换可以由ADC 控制寄存器2: ADC_CR2 的ADON 这个位来控制,写1 的时候开始转换,写0 的时候停止转换

当然,除了ADC_CR2寄存器的ADON位控制转换的开始与停止,还可以支持外部事件触发转换(比如定时器捕捉、EXTI线)

包括内部定时器触发和外部IO触发。具体的触发源由ADC_CR2的EXTSEL[2:0]位(规则通道触发源 )和 JEXTSEL[2:0]位(注入通道触发源)控制。

同时ADC3的触发源与ADC1/2的触发源有所不同,上图已经给出,

具体查看第五部分框图即可理解

6、中断
中断触发条件有三个,规则通道转换结束,注入通道转换结束,或者模拟看门狗状态位被设置时都能产生中断,


转换结束中断就是正常的ADC完成一次转换,进入中断,这个很好理解

模拟看门狗中断,当被ADC转换的模拟电压值低于低阈值或高于高阈值时,便会产生中断。阈值的高低值由ADC_LTR和ADC_HTR配置
模拟看门狗,听他的名字就知道,在ADC的应用中是为了防止读取到的电压值超量程或者低于量程

DMA
同时ADC还支持DMA触发,规则和注入通道转换结束后会产生DMA请求,用于将转换好的数据传输到内存。

注意,只有ADC1和ADC3可以产生DMA请求

因为涉及到DMA传输,所以这里我们不再详细介绍,之后几节会更新DMA,一般我们在使用ADC 的时候都会开启DMA 传输。

ADC的主要特征
STM32F10x ADC特点
12位逐次逼近型的模拟数字转换器。
最多带3个ADC控制器
最多支持18个通道,可最多测量16个外部和2个内部信号源。
支持单次和连续转换模式
转换结束,注入转换结束,和发生模拟看门狗事件时产生中断。
通道0到通道n的自动扫描模式 自动校准
采样间隔可以按通道编程
规则通道和注入通道均有外部触发选项
转换结果支持左对齐或右对齐方式存储在16位数据寄存器
ADC转换时间:最大转换速率 1us。(最大转换速度为1MHz,在ADCCLK=14M,采样周期为1.5个ADC时钟下得到。)
ADC供电要求:2.4V-3.6V
ADC输入范围:VREF- ≤ VIN ≤ VREF+


STM32F4x ADC特点

注: 上部分来自正点原子

F1与F4区别
F4的ADC支持12位,10位,8位和6位精度,F1只支持12位

F1和F4都具有3个ADC,F1可提供21个输入通道,F4可以提供24个输入通道。

F1的ADC最大采样频率为1Msps,2路交替采样可到2Msps(F1不支持3路交替采样)。F4的ADC最大采样频率为2.4Msps,3路交替采样可到7.2Msps。
 以上简介转载于:https://blog.csdn.net/as480133937/article/details/99627062

2、硬件设计

由于板子上并无适合做ADC的外设,但是STM32F1有一个内部的温度传感器,可以用来测量CPU及周围的温度。该温度传感器在内部和ADCx_IN16输入通道相连接,此通道把传感器输出的电压转换成数字值,温度传感器模拟输入推荐采样时间是17.1us,通过读取ADC通道16的值,通过如下计算公式即可算出当前温度:

 本章将通过ADC1通道16采集芯片内部温度,将采样的AD值和转换后的温度值通过USART1串口打印出来,同时LED3指示灯闪烁,提示系统正常运行

3. STM32CubeMX设置

  • RCC设置外接HSE,时钟设置为72M,ADC预分频因子设置为6,ADC_CLK为12MHz
  • PC0设置为GPIO推挽输出模式、上拉、高速、默认输出电平为高电平
  • USART1选择为异步通讯方式,波特率设置为115200Bits/s,传输数据长度为8Bit,无奇偶校验,1位停止位
  • 激活ADC1温度传感器通道,设置右对齐,关闭扫描、连续及间断模式,使能regular conversion,设置软件触发、设置采样时间239.5个周期(19.96us)

设定ADC的触发方式

Regular Conversion launched by software 规则的软件触发 调用函数触发即可

Timer X Capture Compare X event 外部引脚触发,

Timer X Trigger Out event 定时器通道输出触发 需要设置相应的定时器设置

这个具体在上方ADC框图的5部分有讲解

Rank          转换顺序


这个只修改通道采样时间即可 默认为1.5个周期

多个通道时会有多个Rank,可以设定每个通道的转换顺序
ADC总转换时间如下计算:

TCONV = 采样时间+ 12.5个周期

当ADCCLK=14MHz(最大),采样时间为1.5周期(最快)时,TCONV =1.5+12.5=14周期=1μs。

因此,ADC的最小采样时间1us(ADC时钟=14MHz,采样周期为1.5周期下得到) 这个上方也有讲解

注入通道设置
也就是注入通道的设置,和转换通道没啥太大区别,这里不再详解


WahchDog
Enable Analog WatchDog Mode(使能模拟看门狗中断)

这个上方有讲解,本质也测量值就是超出测量范围或者低于最低范围,启动看门狗

  • 开启了ADC之后需要重新配置一下时钟分频,将ADC的分频设置成12MHZ

4、程序编程

在adc.c文件中可以看到ADC初始化函数

void MX_ADC1_Init(void)
{

  /* USER CODE BEGIN ADC1_Init 0 */

  /* USER CODE END ADC1_Init 0 */

  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC1_Init 1 */

  /* USER CODE END ADC1_Init 1 */

  /** Common config
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */

  /* USER CODE END ADC1_Init 2 */

}

void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{

  if(adcHandle->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspInit 0 */

  /* USER CODE END ADC1_MspInit 0 */
    /* ADC1 clock enable */
    __HAL_RCC_ADC1_CLK_ENABLE();
  /* USER CODE BEGIN ADC1_MspInit 1 */

  /* USER CODE END ADC1_MspInit 1 */
  }
}

void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
{

  if(adcHandle->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspDeInit 0 */

  /* USER CODE END ADC1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_ADC1_CLK_DISABLE();
  /* USER CODE BEGIN ADC1_MspDeInit 1 */

  /* USER CODE END ADC1_MspDeInit 1 */
  }
}

 在主函数while循环中添加如下测试程序


	uint16_t AD_Value;
	float Vol_Value,Temperature;
  while (1)
  {
		
	HAL_ADC_Start(&hadc1);  //启动ADC转换
    HAL_ADC_PollForConversion(&hadc1,10);   //等待转换完成,10ms表示超时时间
    AD_Value = HAL_ADC_GetValue(&hadc1);    //读取ADC转换数据(12位数据)
    printf1("ADC1_IN16 ADC value: %d\r\n",AD_Value);
    Vol_Value = AD_Value*(3.3/4096);    //AD值乘以分辨率即为电压值
    printf1("ADC1_IN16 VOL value: %.2fV\r\n",Vol_Value);
    Temperature = (1.43 - Vol_Value)/0.0043 + 25;   //根据公式算出温度值
    printf1("MCU Internal Temperature: %.2f℃\r\n",Temperature);
    printf1("\r\n");

    HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);
	HAL_Delay(1000);
}

程序编译无误后下载到板子上进行验证

5、下载验证

可以看到串口接收到原始是12位AD值,根据公式转换为电压值和温度值即可获得单片机内部的温度。

6、程序扩展

中断读取:

如果使能了ADC转换结束中断,并且使能了定时器中断,可以这样写:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)    //定时器中断回调
{
    HAL_ADC_Start_IT(&hadc1); //定时器中断里面开启ADC中断转换,1ms开启一次采集    
}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)    //ADC转换完成回调
{
    HAL_ADC_Stop_IT(&hadc1);        //关闭ADC
    HAL_TIM_Base_Stop_IT(&htim3);    //关闭定时器
    AD_Value=HAL_ADC_GetValue(&hadc1);  //获取ADC转换的值

    printf("ADC1 Reading : %d \r\n",AD_Value);
    printf("%.4f V\r\n",(AD_Value*3.3/4096));     //串口打印电压信息
    HAL_TIM_Base_Start_IT(&htim3);       //开启定时器
}


函数讲解:

开启ADC 3种模式 ( 轮询模式 中断模式 DMA模式 )

• HAL_ADC_Start(&hadcx);       //轮询模式开启ADC
• HAL_ADC_Start_IT(&hadcx);       //中断轮询模式开启ADC
• HAL_ADC_Start_DMA(&hadcx);       //DMA模式开启ADC

关闭ADC 3种模式 ( 轮询模式 中断模式 DMA模式 )

• HAL_ADC_Stop()
• HAL_ADC_Stop_IT()
• HAL_ADC_Stop_DMA()

ADC校准函数 :

• HAL_ADCEx_Calibration_Start(&hadcx);      

F4系列不支持

读取ADC转换值

• HAL_ADC_GetValue()

等待转换结束函数

• HAL_ADC_PollForConversion(&hadc1, 50);

第一个参数为那个ADC,第二个参数为最大等待时间

ADC中断回调函数
• HAL_ADC_ConvCpltCallback()

转换完成后回调,DMA模式下DMA传输完成后调用

规则通道及看门狗配置

• HAL_ADC_ConfigChannel() 配置规则组通道
• HAL_ADC_AnalogWDGConfig()

 7、参考文献

【STM32】HAL库 STM32CubeMX教程九---ADC_cubemx adc-CSDN博客

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

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

相关文章

完结撒花~Matlab论文插图绘制模板第139期—罗盘图

2021年2月2日,Matlab论文插图绘制模板第1期,启动。 三年后…… 2024年3月4日,Matlab论文插图绘制模板第139期,完结。 别的也不多说了,《Matlab论文插图绘制模板》1-139期精修合集,正加速整理制作中&…

7款炫酷的前端动画特效分享(三)(附效果图及在线演示)

分享7款好玩的前端动画特效 其中有CSS动画、SVG动画、js小游戏等等 下方效果图可能不是特别的生动 那么你可以点击在线预览进行查看相应的动画特效 同时也是可以下载该资源的 CSS3模仿四季交替动画 基于HTML5CSS3实现的卡通风格一年四季交替动画特效 以下效果图只能体现框架的…

mac下终端命令提示补全

欢迎来到我的博客,代码的世界里,每一行都是一个故事 mac下终端命令提示补全 前言Zsh-autosuggestions原理解析:智能提示的工作方式1. 命令历史分析:2. 智能提示生成:3. 用户交互和选择:4. 配置和个性化&…

Java集合框架-Collection和Map

文章目录 Collection-单列集合特点ListArrayListLinkedListVecter SetHashSetTreeSet Map-键值对集合特点Map常用APIput添加细节remove Map的三种遍历方式1.通过键找值2.通过"键值对"3.Lambda表达式foreach源码 HashMap需求 为什么要使用泛型 泛型的优点1.集合中存储…

《精益DevOps》译者序

计算机网络的发展导致了IT领域中的两个重要发展——虚拟化和分布式计算,云服务是虚拟化的一个直接体现,而微服务架构则是分布式计算的一个重要应用领域。不论是虚拟化还是分布式计算,都对软件工程中的研发效能提出了新的问题和挑战&#xff0…

Linux x86平台获取sys_call_table

文章目录 前言一、根据call *sys_call_table来获取二、使用dump_stack三、根据MSR_LSTAR寄存器四、使用sys_close参考资料 前言 Linux 3.10.0 – x86_64 最简单获取sys_call_table符号的方法: # cat /proc/kallsyms | grep sys_call_table ffffffff816beee0 R sy…

实名制交友-智能匹配-仿二狗交友系统-TP6+uni-APP小程序H5公众号-源码交付-支持二开!

一、代码风格 通常不同的开发者具备不同的代码风格,但为了保证语音交友系统开发质量,在编码前需要进行代码风格的统一,通过制定一定的规则,约束开发者的行为。具有统一风格的代码才能更清晰、更完整、更容易理解、更方便后期维护…

互联网加竞赛 车道线检测(自动驾驶 机器视觉)

0 前言 无人驾驶技术是机器学习为主的一门前沿领域,在无人驾驶领域中机器学习的各种算法随处可见,今天学长给大家介绍无人驾驶技术中的车道线检测。 1 车道线检测 在无人驾驶领域每一个任务都是相当复杂,看上去无从下手。那么面对这样极其…

AURIX CSA(上下文存储)介绍(续写中...)

1.CSA概述 CSA(Context Save Areas)上下文存储区域,每次函数调用、进入中断、进入Trap都会存CSA对象,便于退出时候恢复。每个CSA对象的大小为固定的64字节。最大可以支持分配为2^164M。 2.GPRs寄存器 32个通用寄存器(GPRs) 16个…

Redis缓存【重点】

参考链接 https://xiaolincoding.com/redis/cluster/cache_problem.html#%E7%BC%93%E5%AD%98%E9%9B%AA%E5%B4%A9 目录 缓存雪崩大量数据同时过期Redis 故障宕机 缓存击穿第一种方案,非法请求的限制第二种方案,缓存空值或者默认值第三种方案,使…

回溯算法套路②组合型回溯+剪枝【基础算法精讲 15】

学习地址 : 回溯算法套路②组合型回溯剪枝【基础算法精讲 15】_哔哩哔哩_bilibili 回顾 : 从n 个数中选出k个数的组合 , 可以看成是长度固定的子集 ; 剪枝技巧 : 77 . 组合 链接 : . - 力扣(LeetCode) 枚举下一个元素选…

嵌入式中volatile关键字的使用方法

Hi,大家好! 今天我们来学习一下volatile关键字,volatile关键字想必大家在平时编程中都见过或用过。可是小伙伴们有没有想过什么时候需要使用volatile关键字吗? 在C语言中,volatile是一个关键字,用于告诉编译器不要优化…

【MATLAB第97期】基于MATLAB的贝叶斯Bayes算法优化BiGRU双向门控循环单元的多输入单输出回归预测模型,含GRU与BiGRU多层结构优化选择

【MATLAB第97期】基于MATLAB的贝叶斯Bayes算法优化BiGRU双向门控循环单元的多输入单输出回归预测模型,含GRU与BiGRU结构层数优化 前言 前面在【MATLAB第10期】讲解了基于贝叶斯Bayes算法优化LSTM长短期记忆网络的多输入单输出回归预测模型。 本次模型难点包括&am…

ChatGPT数据分析应用——热力图分析

ChatGPT数据分析应用——热力图分析 ​ 热力图分析既可以算作一种可视化方法,也可以算作一种分析方法,主要用于直观地展示数据的分布情况。接下来我们让ChatGPT解释这个方法的概念并提供相应的案例。发送如下内容给ChatGPT。 ​ ChatGPT收到上述内容后&…

[linux]shell脚本语言:变量、测试、控制语句以及函数的全面详解

一、shell的概述 1、shell本质是脚本文件:完成批处理。 shell脚本是一种脚本语言,我们只需使用任意文本编辑器,按照语法编写相应程序,增加可执行权限,即可在安装shell命令解释器的环境下执行。shell 脚本主要用于帮助开…

鸿蒙Harmony应用开发—ArkTS声明式开发(通用属性:无障碍属性)

组件可以设置相应的无障碍属性和事件来更好地使用无障碍能力。 说明: 从API Version 10 开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 accessibilityGroup accessibilityGroup(value: boolean) 无障碍组。 系统能力&#…

机器学习:主成分分析笔记

主成分分析(Principal Component Analysis,PCA)是一种无监督的机器学习算法,通常用于高维数据的降维、提取主要特征、数据降噪和可视化。PCA的基本思想是将原始数据的多个变量转换为少数几个相互独立的变量(即主成分&a…

【Web前端入门学习】——HTML

目录 HTML简介HTML文件结构常用文本标签标题标签段落标签有序列表和无序列表表格标签 HTML属性a标签—超链接标签图片标签 HTML区块块元素与行内元素 HTML表单 HTML简介 HTML全称是Hypertext Markup Language超文本标记语言。 HTML的作用: 为网页提供结构&#xff…

Stream流(Java)

目录 一、介绍 二、Stream流的使用步骤 三、Stream流常见的中间方法 四、Stream流常见的终结方法 一、介绍 Stream也叫Stream流,是JDK8开始新增的一套API,可以用于操作集合或者数组的数据。 优势:Stream流大量的结合了Lambda的语法风格来…

SpringCloud远程调用为啥要采用HTTP

关于SpringCloud远程调用采用HTTP而非RPC。 首先SpringCloud开启Web服务依赖于内部封装的Tomcat容器,而今信息飞速发展,适应大流量的微服务,采用Tomcat处理HTTP请求,开发者编写Json作为资源传输,服务器做出相应的响应&…