STM32 CubeMX学习:7. ADC模数转化

STM32中ADC在cubemx基础配置界面介绍 一般情况下不需要使用注入通道,可以将注入通道认为是ADC中断,即打断规则通道的采样进程执行注入通道的采样。Timer X Trigger Out event 定时器通道输出触发 需要设置相应的定时器设置。Timer X Trigger Out event 定时器通道输出触发 需要设置相应的定时器设置。#当有多个通道需要采集信号时必须开启扫描模式,此时ADC将会按设定的顺序轮流采集各通道信号。单次转换模式ADC只采集一次数据就停止采集,使用单次转换模式需要转换通道数大于1。 阅读详情

STM32 CubeMX学习:7. ADC模数转化

系列文章目录
  1. 前期的准备
  2. 点亮 LED
  3. 闪烁 LED
  4. 定时器闪烁LED
  5. PWM控制LED亮度
  6. 常见的PWM设备
  7. 按键的外部中断
  8. ADC模数转换
  9. 串口收发
  10. 串口打印遥控器数据
  11. 未完待续…


0 前言

我们已经知道,在单片机中传输的信号均为数字信号,通过离散的高低电平表示数字逻辑的1和0,但是在现实的物理世界中,只存在模拟信号,即连续变化的信号,将这些连续变化的信号——比如热,光,声音,速度通过各种传感器转化成连续的电信号,再通过ADC功能将连续的模拟信号转化成离散的数字信号给单片机进行处理。

1. 基础知识学习

1.1 ADC原理介绍

一般ADC的工作流程为采样,比较,转换。

  • 采样:是指对某一时刻的模拟电压进行采集,
  • 比较:是指将采样的电压在比较电路中进行比较,
  • 转换:是指将比较电路中结果转换成数字量。
    在我们这里,使用的STM32f4采用12位逐次逼近型ADC(SAR-ADC)。现在,以下图为例,介绍3位ADC的比较过程:
    ADC原理
    不同的位数分别赋予1/2,1/4,1/8的权值,模拟信号的采样值为Vin,
    1)与1/2Vref进行比较,Vin大于1/2Vref,则将第一位标记为1,
    2)与3/4Vref进行比较,Vin小于3/4Vref,则将第二位标记为0,
    3)与5/8Vref进行比较,Vin小于5/8Vref,则将第三位标记为0。
    图中的Vin通过这个三位的ADC后输出的结果为100。转换的结果为1/2Vref,通过这样逐次比较过程,将采样取得的模拟电压和内部参考电压Vref的加权值进行比较,不同的位数赋予不同的权值。
    但是,如果我们输入为一个未知的电压,完整的比较流程图如下:
    ADC采样流程
    STM32支持最高12位ADC,一般ADC的位数越多则转换精度越高,但与此同时转换的速度也会变慢。
    此外,STM32内部有一个校准电压VREFINT,电压为1.2V,当供电电压不为3.3V,可以使用内部的vrefint通道采集1.2V电压作为Vref,以提高精度。

1.2 STM32F4x ADC介绍

  1. STM32F4x ADC特点
    stm32特点
  2. STM32F40x系列ADC外部通道和引脚对应关系
    对应关系

2. 程序学习

2.1 ADC在CubeMX的配置

这次我们使用引脚PF10作为电源ADC引脚,使用ADC3的通道8,STM32内部的1.2V校准电压Vrefint在ADC1中。所以我们需要按如下方式在CubeMX里进行配置。

  1. 开启ADC1和ADC3分别用于内部1.2V的Vrefint通道读取和电池电压ADC3的通道8读取。
  2. 在cubeMX中开启ADC1,在设置中将Vrefint Channel勾选,用于读取内部参考电压。ADC在cubeMX中的设置如图采样频率设置为PCLK2/4,采样位数为12位,数据设置为右对齐,其余均保持默认。其中Vrefine在stm32内部完成,没有对应引脚。
    ADC1配置
    最终ADC配置如图所示。
    ADC1详细配置
    《补充》:但是,这里还是把其中参数的具体含义给大家科普一下吧
名称功能
Clock Prescaler设置采样时钟频率
Resolution设置采样精度
Data Alignment设置数据对齐方式
Scan Conversion Mode扫描转换模式开启/关闭
Continuous Conversion Mode连续转换模式开启/关闭
Discontinuous Conversion Mode非连续转换模式开启/关闭
DMA Continuous RequestsDMA连续启动开启/关闭
End of Conversion Selection每个通道转换结束后发送EOC标志/所有通道转换结束后发送EOC标志
  1. 在CubeMX中开启ADC3,并打开其IN8用于电池电压的读取,其设置和ADC1一致。可以看到引脚图像中ADC3对应的PF10变绿。
    ADC3
    ADC3详细配置

  2. 这里我们需要把PC0,PC1,PC2引脚设置为输入模式,且这三个引脚拉为高电平,如图所示
    其它引脚设置

  3. 点击GENERATE CODE生成代码

2.2 内部VREFINT电压的使用

VREFINT 即 ADC的内部参照电压1.2V。通过将采样内部参照电压1.2V的 ADC 值和 Vref 的加权值进行比较,进而得到 ADC 的输出值。一般来说STM32的 ADC 采用 Vcc 作为 Vref ,但为了防止 Vcc 存在波动较大导致Vref不稳定,进而导致采样值的比较结果不准确,STM32可以通过内部已有的参照电压VREFINT来进行校准,接着以VREFINT为参照来比较ADC的采样值,从而获得比较高的精度,VREFINT的电压为1.2V。
通过一个函数对1.2V的电压进行多次采样,并计算其平均值,接着将其与ADC采出的数据值做对比,得到单位数字电压对应的模拟电压值voltage_vrefint_proportion,其计算公式如下,设采样得到的数字值为average_adc:

a v e r a g e _ a d c = t o t a l _ d a c 200 average\_adc=\frac{total\_dac}{200} average_adc=200total_dac​

v o l t a g e _ v r e f i n t _ p r o p o r t i o n = 1.2 v a v e r a g e _ a d c = 200 ∗ 1.2 t o t a l _ a d c voltage\_vrefint\_proportion=\frac{1.2v}{average\_adc}=\frac{200 ∗ 1.2}{total\_adc} voltage_vrefint_proportion=average_adc1.2v​=total_adc200∗1.2​
其代码如下所示

void init_vrefint_reciprocal(void) 
{ 
	uint8_t i = 0; 
	uint32_t total_adc = 0; 
	for(i = 0; i < 200; i++)
	 {
	 	 total_adc += adcx_get_chx_value(&hadc1, ADC_CHANNEL_VREFINT);
	  } 
	  voltage_vrefint_proportion = 200 * 1.2f / total_adc;
}

2.3 相关函数介绍

Hal库提供了以下很多有关ADC的函数

  1. ADC通道设置函数
HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig)
函数作用设置ADC通道的各个属性值,包括转换通道,序列排序,采样时间等
返回值HAL_StatusTypeDef,HAL库定义的几种状态,如果成功使ADC开始工作,则返回HAL_OK
参数1TIM_HandleTypeDef * hadc即ADC的句柄指针,如果是adc1就输入&hadc1,adc2就输入&adc2
参数2ADC_ChannelConfTypeDef* sConfig即指向ADC设置的结构体指针。我们先对sConfig结构体进行赋值,然后再将其指针作为参数输入函数
  1. ADC开启采样函数
HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc)
函数作用开启ADC的采样
返回值HAL_StatusTypeDef,HAL库定义的几种状态,如果成功使ADC开始工作,则返回HAL_OK
参数TIM_HandleTypeDef * hadc即ADC的句柄指针,如果是adc1就输入&hadc1,adc2就输入&adc2
  1. 等待ADC转换结束函数
HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout)
函数作用等待ADC转换结束
返回值HAL_StatusTypeDef,HAL库定义的几种状态,如果成功使ADC开始工作,则返回HAL_OK
参数1TIM_HandleTypeDef * hadc即ADC的句柄指针,如果是adc1就输入&hadc1,adc2就输入&adc2
参数2HAL_StatusTypeDef,HAL库定义的几种状态,如果成功使ADC开始工作,则返回HAL_OK
  1. 获取ADC函数
uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc)
函数作用获取ADC值
返回值HAL_StatusTypeDef,HAL库定义的几种状态,如果成功使ADC开始工作,则返回HAL_OK
参数TIM_HandleTypeDef * hadc即ADC的句柄指针,如果是adc1就输入&hadc1,adc2就输入&adc2

2.4 程序执行流程

本程序中,首先对内部参考电压电压VREFINT进行adc采样将其作为校准值,在init_vrefint_reciprocal中,对VREFINT电压进行200次的采样,接着求其均值后使用VREFINT的电压值1.2V去除以该ADC采样得到的均值,算出voltage_vrefint_proportion,后续ADC中采样到的电压值与voltage_vrefint_proportion相乘就可以计算出以内部参考电压做过校准的ADC值了。

void init_vrefint_reciprocal(void) 
{ 
	uint8_t i = 0; uint32_t total_adc = 0; 
	
	for(i = 0; i < 200; i++) 
	{ 
		total_adc += adcx_get_chx_value(&hadc1, ADC_CHANNEL_VREFINT); 
	} 
	
	voltage_vrefint_proportion = 200 * 1.2f / total_adc; 
}

接着通过ADC对经过了分压电路的电池电压值进行采样,将该采样结果与voltage_vrefint_proportion相乘,就得到了取值范围在0-3.3V之间的ADC采样值,由于这个采样值是分压后的结果,需要反向计算出电压的值。分压的电阻值为200KΩ和22KΩ,由于 (22K Ω + 200K Ω) / 22K Ω = 10.09,乘以这个值之后就可以得到电池的电压值。
(注意,这里我们是根据一个具体的分压电路给出的计算公式,当我们实际使用时,要根据自己所使用的具体电路修改对应的计算方法,)

fp32 get_battery_voltage(void) 
{ 
	fp32 voltage; 
	uint16_t adcx = 0; 
	adcx = adcx_get_chx_value(&hadc3, ADC_CHANNEL_8);
	
	//(22K Ω + 200K Ω) / 22K Ω = 10.090909090909090909090909090909 
	voltage = (fp32)adcx * voltage_vrefint_proportion * 10.090909090909090909090909090909f; 
	return voltage; 
}

其实,我们还可以通过ADC获得板载的温度传感器的温度值,同样是先经过ADC值进行采样,采样结束后,将ADC采样结果adc带入公式temperate = (adc - 0.76f) * 400.0f + 25.0f,从而计算出温度值。

fp32 get_temprate(void) 
{ 
	uint16_t adcx = 0; 
	fp32 temperate; 
	
	adcx = adcx_get_chx_value(&hadc1, ADC_CHANNEL_TEMPSENSOR);
	
	temperate = (fp32)adcx * voltage_vrefint_proportion;
	temperate = (temperate - 0.76f) * 400.0f + 25.0f;
	 
	return temperate; 
}

在我们完成代码时,还需要像以前一样自己新建一个Boards目录,在里面新建一个bsp_adc.c文件

#include "bsp_adc.h"
#include "main.h"
extern ADC_HandleTypeDef hadc1;
extern ADC_HandleTypeDef hadc3;


volatile fp32 voltage_vrefint_proportion = 8.0586080586080586080586080586081e-4f;

static uint16_t adcx_get_chx_value(ADC_HandleTypeDef *ADCx, uint32_t ch)
{
    static ADC_ChannelConfTypeDef sConfig = {0};
    sConfig.Channel = ch;
    sConfig.Rank = 1;
    sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;//ADC_SAMPLETIME_3CYCLES;

    if (HAL_ADC_ConfigChannel(ADCx, &sConfig) != HAL_OK)
    {
        Error_Handler();
    }

    HAL_ADC_Start(ADCx);

    HAL_ADC_PollForConversion(ADCx, 10);
    return (uint16_t)HAL_ADC_GetValue(ADCx);

}
void init_vrefint_reciprocal(void)
{
    uint8_t i = 0;
    uint32_t total_adc = 0;
    for(i = 0; i < 200; i++)
    {
        total_adc += adcx_get_chx_value(&hadc1, ADC_CHANNEL_VREFINT);
    }

    voltage_vrefint_proportion = 200 * 1.2f / total_adc;
}
fp32 get_temprate(void)
{
    uint16_t adcx = 0;
    fp32 temperate;

    adcx = adcx_get_chx_value(&hadc1, ADC_CHANNEL_TEMPSENSOR);
    temperate = (fp32)adcx * voltage_vrefint_proportion;
    temperate = (temperate - 0.76f) * 400.0f + 25.0f;

    return temperate;
}


fp32 get_battery_voltage(void)
{
    fp32 voltage;
    uint16_t adcx = 0;

    adcx = adcx_get_chx_value(&hadc3, ADC_CHANNEL_8);
    //(22K Ω + 200K Ω)  / 22K Ω = 10.090909090909090909090909090909
    voltage =  (fp32)adcx * voltage_vrefint_proportion * 10.090909090909090909090909090909f;

    return voltage;
}

uint8_t get_hardware_version(void)
{
    uint8_t hardware_version;
    hardware_version = HAL_GPIO_ReadPin(HW0_GPIO_Port, HW0_Pin)
                                | (HAL_GPIO_ReadPin(HW1_GPIO_Port, HW1_Pin)<<1)
                                | (HAL_GPIO_ReadPin(HW2_GPIO_Port, HW2_Pin)<<2);



    return hardware_version;
}


接着新建一个对应的bsp_adc.h文件放置于对应目录之下

#ifndef BSP_ADC_H
#define BSP_ADC_H
#include "#ifndef BSP_ADC_H
#define BSP_ADC_H
#include "struct_typedef.h"

extern void init_vrefint_reciprocal(void);
extern fp32 get_temprate(void);
extern fp32 get_battery_voltage(void);
extern uint8_t get_hardware_version(void);
#endif
"

extern void init_vrefint_reciprocal(void);
extern fp32 get_temprate(void);
extern fp32 get_battery_voltage(void);
extern uint8_t get_hardware_version(void);
#endif

在这个文件中,我们还用到了一个定义结构体的头文件:struct_typedef.h

#ifndef STRUCT_TYPEDEF_H
#define STRUCT_TYPEDEF_H


typedef signed char int8_t;
typedef signed short int int16_t;
typedef signed int int32_t;
typedef signed long long int64_t;

/* exact-width unsigned integer types */
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef unsigned char bool_t;
typedef float fp32;
typedef double fp64;


#endif




最终的main.c文件如下所示

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "bsp_adc.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
fp32 voltage;
fp32 temperature;
uint8_t handware_version;
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_ADC3_Init();
  /* USER CODE BEGIN 2 */
	
	//use vrefint voltage to calibrate
  //使用基准电压来校准
  init_vrefint_reciprocal();
		
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		
				//get battery voltage
        //获取电源电压
        voltage = get_battery_voltage();
        //get chip temperate
        //获取片内温度
        temperature = get_temprate();
        //get handware version
        //获取硬件版本
        handware_version = get_hardware_version();
        HAL_Delay(100);
		
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage 
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 6;
  RCC_OscInitStruct.PLL.PLLN = 168;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */

  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{ 
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

3. 进阶学习

逐次型ADC是通过一位位进行比较得出转换值,其原理图如下所示。
原理图
如图所示,我们发现整个电路由比较器、D/A转换器、缓冲寄存器和若干控制逻辑电路构成。作用如下所示:

  • 比较器:用于输入电压值D/A转换器输出电压进行比较,当输入电压大于D/A转换器电压时,输出为1,反之输出为0;
  • D/A转换器:ADC的逆向过程,将缓冲寄存器的记录数字量转换成模拟量。
  • 缓冲寄存器:记录当前转换的数字量。

整个过程如下:

  1. 将缓冲寄存器清零;
  2. 将逐次逼近寄存器 最高位 置1;
  3. 把数字值送入D/A转换器,经D/A转换后的模拟量送入比较器,称为 Vo;
  4. Vo与比较器的待转换的模拟量Vi 比较,若Vo<Vi,该位被保留,否则被清0。
  5. 再置 寄存器 次高位为1,将寄存器中新的数字量送D/A转换器,
  6. 输出的 Vo再与Vi比较,若Vo<Vi,该位被保留,否则被清0。
  7. 循环此过程,直到寄存器最低位,得到数字量的输出。
    在这个过程中,D/A转换器使用的电压为STM32的电源电压Vref+和Vref-,如图所示:
    电路原理
    STM32的标准电压为 3.3V。例如第一次转换时,输出为 1/2Vre电压,即1.65V。但由于外部供电电压不一定为 3.3V。故而为了在这种情况提高ADC精度,STM32内部有VERFINT1.2V稳定电压,可以使用ADC采样该电压来提高ADC的精度。

代码我已经放到了我的GitHub仓库,如有需要可以下载使用:
CubeMX学习


总结

这次的博客,我们重点学习了ADC的相关知识,ADC是模拟量变成数字量的过程,单片机获取电压,电流传感器等模拟量的方法。通过ADC功能,我们能够获取各种传感器的模拟值,并将其转化为单片机可以处理的数字量,也可以获取电池的电压值,并将其通过电量形式显示出来。
stm32ADC的使用说明 mcu型号:stm32l0系列, 采样通道:采样ADC_CHANNEL_1和ADC_CHANNEL_VREFINT多个通道,后者在电源电压变化时,比如电池供电,准确测量当前采样通道ADC_CHANNEL_xxx电压时会用到。 1.初始化配置项说明: ADC_ChannelConfTypeDef sConfig = {0}; 以下列代码为例进行说明: /**Configure the global features of the ADC (Clock, Resolution, Data Ali.. 阅读详情

相关推荐

STM32Cubemx ADC配置详解

标题STM32Cubemx ADC配置详解 ADC独立模式 所谓独立模式,在一个管脚上只有一个ADC采集该管脚的电压。 ADC双重模式 所谓两重模式,就是ADC1_IN0,ADC2_IN0在同一管脚上,采集的是同一管脚上的电压。 ADC三重模式 所谓三重模式,ADC1_IN0,ADC2_IN0,ADC3_IN0在同一管脚上,采集的是同一管脚上的电压。 Parameter Setti...

qq_43225938的博客 5万+

STM32L031 ADC管脚电压采样

STM32L031 ADC管脚电压采样 为了更精确的体现ADC对管脚采样的电压值,需要对当前的供电电压的变化也进行参考计算,涉及到STM32 Internal voltage reference (VREFINT) 即内部电压参考的应用。 VREFINT内部连接到ADC_IN17输入通道,VREFINT实际上是一个内部稳压低电压值,也就是芯片供电在一定范围(譬如1.65V~3.6V)应用时,这个电...

Pegasus的软件博客 4392

STM32CubeMX+Keil+Proteus仿真ADC采集

本文说明 相关原理摘自小蜜蜂笔记 链接: www.xmf393.com. 模数转换器(ADC)概述 ADC:Analog-to-Digital Converter 将时间和幅值连续的模拟量转化为时间和幅值离散的数字量 A/D转换一般要经过采样、保持、量化和编码4个过程 ADC转化过程 ADC性能指标 量程:指ADC所能输入模拟信号的类型和电压范围,即参考电压。信号类型包括单极性和双极性。 转换位数:量化过程中的量化位数n。 A/D转换后的输出结果用n位二进制数来表示。 【例】:10位ADC的输出值就是0~

爱学习的诸葛铁锤的博客 1万+

STM32采用内部参考电压Vrefint Channel校准ADC采样数据

项目前期,硬件攻城狮就不断强调,你要用STM32采用内部参考电压Vrefint Channel校准ADC采样数据。项目一直很忙,校准后肯定可以提升精度,但是ADC精度不只是通过这个方式可以提升精度。软件攻城狮就开始给硬件攻城狮上课,嘟嘟嘟。。。。。。。如下文所示,对着硬件攻城狮说,看看,提升ADC精度的关键还是得靠硬件。下面插播ADC精度提升方法:...言归正传,本文还是要详解STM32采用内部参考电压Vrefint Channel校准ADC采样数据,并使用STM32CubeIDE完成了工程搭建测试

大牛攻城狮的专栏 4187

STM32CUBEMX配置ADC(多通道轮询)(STM32H7)--保姆级教程

⏩ 大家好哇!我是小光,嵌入式爱好者,一个想要成为系统架构师的大三学生。⏩最近在开发一个STM32H723ZGT6的板子,使用STM32CUBEMX做了很多驱动,包括ADC、UART、RS485、EEPROM(IIC)、FLASH(SPI)等等。⏩本篇文章对STM32CUBEMX配置多通道ADC做一个详细的使用教程。

qq_52608074的博客 1万+

STM32CubeMX——ADC模数转换器开发基础(HAL 库)

一、模数转换器(ADC)概述:

莘莘的博客 3817

STM32CubeMX配置ADC采样(轮询、中断、DMA)

STM32CubeMX能够极大减小STM32外设配置的工作量,本文介绍如何利用STM32CubeMX配置ADC采样,记录了作者学习过程中遇到的问题及解决办法

weixin_46461874的博客 3万+

STM32(CubeMax)基础配置

对于刚刚接触HAL库的小伙伴来说,每次对于基础部分都需要查阅视频去进行操作,本文就是通过STM32F103C8T6模块进行基础配置,其他单片机基本与之一致。

weixin_44597885的博客 5435

STM32H743-梳理ADC模数转换器在CubeMX上的配置

文章目录一、前言二、Cloack Configuration三、ADC1 Mode and Configuration四、Configuration4.1、ADC_Setting4.1.1、Clock Prescaler(时钟预分频)4.1.2、Resolution(分辨率)4.1.3、Scan Conversion Mode(扫描模式)4.1.4、Continuous Conversion Mode(连续转换模式)4.1.5、Discontinuous Conversion Mode(不连续序列转换模式)

wallace89的博客 2万+

STM32采用内部参考电压Vrefint Channel校准ADC采样数据含:STM32CubeIDE例程RM0038,详解文档

参考博客:https://blog.csdn.net/li171049/article/details/143058165 博客针对提升ADC精度,做了阐述,然后详解了STM32采用内部参考电压Vrefint Channel校准ADC采样数据。 资源提供该博客的STM32CubeIDE例程:主要参考RM0038文档P286页对Temperature sensor and internal reference voltage使用说明,实现内部参考电压Vrefint Channel校准ADC采样数据 资源提供详解文档:阐述STM32的内部参照电压VREFINT和ADCx_IN17相连接,它的作用是相当于一个标准电压测量点,内部参照电压VREFINT只能出现在主ADC1中使用。针对校准电压,翻看了很多资料,网上也有一些帖子,都是这些把校准电压设置了1.2v,这里有问题的。这个校准电压应该从MCU的出厂设置地址中读取。 资源提供RM0038文档,加速面临同样问题小伙伴的开发速度。

Vivado与Vscode无缝集成:高效Verilog开发环境搭建指南

本文详细介绍了如何将Vivado与Vscode无缝集成,打造高效的Verilog开发环境。通过替换Vivado默认编辑器为Vscode,配置必备插件和语法检查工具,开发者可以大幅提升FPGA项目的编码效率。文章还提供了代码片段、Testbench自动生成等高级技巧,帮助开发者快速上手这一集成方案。

weixin_33737774的博客 493

STM32CubeMX学习六 之ADC配置

记录一下STM32CubeMX的学习笔记,这里主要讲解了ADC转换,和ADC的DMA模式。同时分享给初学的小白,希望一起进步。

weixin_42648781的博客 1万+

Android编译系统——Android.bp语法介绍(十五)

Android.bp 是 Android 构建系统(Android Build System)中的配置文件,用于描述如何编译和打包项目中的模块。它是用 Blueprint 编写的,其语法类似于 JSON,但专为 Android 编译系统设计,提供了更高效、灵活的模块化管理。

小旭的专栏 939

STM32CubeMX教程14 ADC - 多通道DMA转换

使用STM32CubeMX软件配置STM32F407开发板的ADC实现ADC多通道DMA采集,具体为使用ADC_IN5/6/7三个通道进行DMA连续ADC转换

lc_guo的博客 1万+

QGIS将经纬度坐标转成点

QGIS绘制一张地图

weixin_46713695的博客 6056

vscode中运行gcc -v命令失败了,提示:gcc不是内部或外部命令...如何解决?

🏆本文收录于 《全栈Bug调优(实战版)》 专栏,该专栏专注于分享我在真实项目开发中遇到的各类疑难Bug及其深层成因,并系统提供高效、可复现的解决思路和实操方案。无论你是刚入行的新手开发者,还是拥有多年项目经验的资深工程师,本专栏都将为你提供一条系统化、高质量的问题排查与优化路径,助力你加速成长,攻克技术壁垒,迈向技术价值最大化与职业发展的更高峰🚀!

**My Coding Family** 975

STM32CubeMX学习笔记(8)——ADC接口使用

一、ADC简介 ADC(Analog-to-Digital Converter),即模拟-数字转换器,可以将连续变化的模拟信号转换为离散的数字信号,进而使用数字电路进行处理,称之为数字信号处理。 STM32f103 系列有 3 个 ADC,精度为 12 位,每个 ADC 最多有 16 个外部通道。其中 ADC1 和 ADC2 都有 16 个外部通道,ADC3 根据 CPU 引脚的不同通道数也不同,一般都有 8 个外部通道。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右对齐

Leung的博客 3万+

ABAP CDS HAVING 全解析:聚合之后的精准过滤、最佳实践与可运行示例

摘要: 本文针对具备ABAP与CDS基础的开发者,详解HAVING在ABAP CDS中的核心用法。HAVING专用于过滤GROUP BY后的聚合结果(如SUM、COUNT),与WHERE的分工明确:前者处理聚合值,后者过滤原始记录。通过销售额阈值、质量分析、财务对账三类典型场景,结合性能优化建议(如优先使用WHERE索引过滤),说明实际应用。文中提供经典CDS View与View Entity两种实现代码,并附Open SQL消费示例,帮助开发者快速落地。常见误区(如聚合条件误写至WHERE)与规避方法亦被

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 219

STM32 HAL库 STM32CubeMX -- ADC

STM32 HAlL库 STM32Cube MX配置 ADC 数据采集 ADC功能框图 ADC数据采集六个例子:单通道数据采集、多通道间断模式轮询采集、多通道中断采集、多通道定时器中断采集、多通道DMA采集、多通道定时器MDA采集

Dir_x的博客 1万+

假期搞定!2026国社科申报AI全攻略指南:从选题到创新,7大核心要点手把手教你!

最后给大家推荐的400多所高校教师都在用的AI平台——高级学术版专业应用平台,集成了国际主流学术应用,以及ChatGPT、Claude、Gemini、Grok等Al大模型的高级版本平台,还有,可以辅助大家高效完成科研和学术写作任务,当然撰写硕博论文,课题、职称论文、国社科、国自然基金本子也是手拿把掐。你的任务是:用高度凝练的方式说明在(某一明确国家战略 / 政策方向,如:中国式现代化、共同富裕、基层治理现代化、数字中国、文化强国、国家安全等)背景下,我究竟要研究一个什么“具体而可操作的问题”。

智能AI让学术科研更容易 623

YOLOv11【第一章:零基础入门篇·第1节】YOLOv11核心架构深度解析与环境配置,一文搞定!

🏆 本文收录于专栏 《YOLOv11实战:从入门到深度优化》。 本专栏围绕 YOLOv11 的改进、训练、部署与工程优化 展开,系统梳理并复现当前主流的 YOLOv11 实战案例与优化方案,内容目前已覆盖 分类、检测、分割、追踪、关键点、OBB 检测 等多个方向。

**My Coding Family** 5507

STM32CubeMX教程15 ADC - 多重ADC转换

使用STM32CubeMX软件配置STM32F407开发板的ADC实现多重ADC采集

lc_guo的博客 5341

uniapp - 使用web-view加载本地网页vue页面,用webview导入本地网页,uniAPP中使用web-view加载的本地及远程vue页面+双向通讯功能(兼容微信小程序、安卓苹果APP)

uniapp的App端web-view加载本地html,uniapp微信小程序webview加载本地HTML文件,在uniAPP中使用web-view加载的本地及远程vue页面且进行双向通讯,uni-app的web-view组件,支持加载远程网页,在app环境下,还支持加载本地HTML页面。uniapp WebView组件实现本地网页加载与通讯传值,uniAPP如何内嵌webView引入本地的vue网页示例代码,uniapp在web-view加载的本地及远程HTML中调用uni的API及网页和vue页面跳转

🏆 前端领域优质创作者 5226

让STM32CubeMX带你飞,菜鸟秒变STM32高手

让STM32CubeMX带你飞,菜鸟秒变STM32高手

安迪西_嵌入式攻城狮 8627

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

[STM32CubeMX]学习笔记5:ADC模数转换电压至串口输出

使用标准库实现本次功能的源代码已上传: https://github.com/yzmj0986/STM32_Std.lib_ADC_Voltage.git MCU:STM32F103ZET6 IDE: MDK-ARM V5 +STM32CubeMX5.0.0 串口调试助手:SSCOM3.2 功能描述:通过ADC1通道1采样外部电压值,将采样的AD值和转换后的电压值通过串口打印...

zytjasper的博客 1万+

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

【stm32】HAL库开发——CubeMX配置ADC

本文详细介绍了STM32的ADC模块配置与使用方式。主要内容包括:1. ADC转换模式解析,包括扫描模式、单次/连续转换、间断模式的区别;2. CubeMX配置要点,如规则通道与注入通道的差异、触发方式选择;3. 6种典型应用场景的实现方法:单次非扫描、连续非扫描、扫描连续/非连续模式(DMA/非DMA方式)、定时器触发ADC;4. 关键代码示例,如HAL库函数调用、DMA配置、结果读取等。特别强调多通道转换时DMA的必要性,以及不同模式下数据读取的注意事项,为STM32 ADC开发提供了实用指导。

2301_80366509的博客 7573

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

上一篇: STM32 CubeMX学习:6. 按键的外部中断
下一篇: STM32 CubeMX学习:8. 串口收发
北冥航
博客等级 码龄7年 232粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值