STM32 单片机 - ADC

一、ADC 介绍

ADC (analog-to-digital converter):模数转换器 - 将模拟信号转换为数字信号

模拟信号 :连续周期变化的信号,在时间和数值上都是连续变化的物理量。

数字信号 :以离散的 0 和 1 组成的信号,在时间和数值上都是离散的物理量。
图 1 模拟信号和数字信号


ADC 一般使用在电路中电流和电压的检测,以及传感器中数据的转换

STM32U575RIT6 可以使用 ADC1 和 ADC4 两个外设控制器进行模数转换


二、ADC1 和 ADC4

2.1 模数转换原理

图 2 ADC1 和 ADC4

ADC 的采样位数:本质是采样精度,是将模拟信号转化为数字信号后的位数;

ADC1 转化后的数字信号是 14 位,ADC4 转化后的数字信号是 12 位

数据寄存器:存储转换后的数字信号
图 3 逐次逼近法原理图
图 4 逐次逼近法原理

ADC 转化使用的是 逐次逼近法

逐次逼近法:循环使用二分查找(折半查找)

AD4 的转化数字信号时 12 位,转换后的数字信号范围时 0 ~ 2¹²-1

2.2 模数转换公式

以 电压模拟信号转换 -> 电压数字信号 为例,使用 12 位的 ADC4

cpp 复制代码
ADC转换后的数字信号 = 4096 / 3.3v * 1.2v

4096:采样位数的 ADC 最大转化范围(2¹²=4096,2¹⁴=16384)

3.3v:参考电压 / 供电电压

1.2v:待测电压

cpp 复制代码
待测电压的数字信号 = (2^(ADC的采样位数) / 参考电压) * 待测电压的模拟信号

2.3 采样时机和偏移补偿

图 5 采样时机和偏移补偿图示

采样时机指的是ADC的采样保持电路在何时对模拟输入信号进行"采样"(捕获瞬时电压值)的精确时间点。

偏移补偿,也称为失调电压校准,目的是消除ADC输出代码中存在的固定的、系统的直流偏差。如果ADC采样发生偏移,此时采样得到的数据可能不是很准确,就需要使用硬件提供的偏移补偿机制(校准机制)初始化采样时机。


三、ADC 采样模式

3.1 ADC1 的内部框图

图 6 ADC1 连接图
图 7 ADC1 描述

3.2 ADC4 内部框图

图 8 ADC4 连接图
图 9 ADC4 描述

3.3 ADC 的转化模式(采样模式)

图 10 ADC 的五种采样模式

单通道单次转化模式

只使用 ADC 模数转换器中的一个独立通道,将输入到通道中的模拟信号转换为数字信号,并只转换一次就结束。


单通道连续转换模式

只使用 ADC 模数转换器中的一个独立通道,将输入到通道中的模拟信号转换为数字信号,结束一次后,自动进行下一次转化。


单通道连续转化模式 = while(1) + 单通道单次转化模式


多通道单次转化模式

使用 ADC 模数转换器的多个通道,并都输入模拟信号,ADC 转换器根据通道的顺序,依次转换为数字信号,每个通道只转换一次。


多通道连续转换模式

使用 ADC 模数转换器的多个通道,并都输入模拟信号,ADC 转换器根据通道的顺序,依次转换为数字信号,所有通道转化完后,回到初始通道重新依次转换。


多通道连续转化模式 = while(1) + 多通道单次转化模式


间隔转化模式(间隔触发模式)

给对应通道一个触发信号(触发源)后,ADC 模数转换器开始一次对通道中的模拟信号转换为数字信号。


ADC的转化模式:独立模式(单通道模式)、扫描模式(多通道模式)、触发模式


四、分析电路图

图 11 电路图分析

拓展板电压检测引脚:PB1


五、CubeMX 配置

图 12 配置 PB1 引脚为 ADC4_IN19
图 13 参数设置

  • ADCs_Common_Settings(ADC 通用设置)
    • Mode(模式):Independent mode(独立模式(每个通道都是独立的))
  • ADC_Settings(ADC 设置)
    • Clock Prescaler(时钟分频):Asynchronous clock mode divided by 1(时钟分频(时钟频率 -> 影响 ADC 模数转化的速率))
    • Resolution(采样精度):ADC 12 - bit resolution(采样精度(转化后的数字信号的位数):12 位)
    • Data Alignment(数据对齐方式):Right alignment(数据对齐方式:右对齐)
    • Sequencer(序列器):Sequencer set to not fully configurable
    • Scan Conversion Mode(输入转化模式):Forward(输入转化模式:标准模式(标准转化速率模式))
    • Continuous Conversion Mode(连续转化模式):Disabled
    • Discontinuous Conversion Mode(不连续转化模式):Disabled
    • DMA Continuous Requests(DMA 连续请求):Disabled
    • End Of Conversion Selection(转换结束选择):End of single conversion
    • Overrun behaviour(数据保存的机制):Overrun data preserved(数据保存的机制:转化后的数字信号被存储到数据寄存器中可以使用追加 / 覆盖的方式)
    • Low Power Auto Wait(低功耗自动等待):Disabled
    • Low Power Auto Off(低功耗自动关闭):Low power disabled and auto off disabled
    • SamplingTime Common 1(通用采样时间 1):1.5 Cycles(通用的采样时间:1.5 轮转化一次,轮的具体时间需要根据时钟频率来计算 理论上,采样时间越长,采样得到的数据越准确)
    • SamplingTime Common 2(通用采样时间 2):1.5 Cycles
    • Trigger Frequency(触发频率):Low frequency
    • External Trigger Conversion Source(外部触发转换源):Regular Conversion launched by software(使用间隔触发模式时,需要设置)
    • External Trigger Conversion Edge(外部触发转换沿):None
    • Oversampling Mode(过采样模式):Disabled
    • Sampling Time(采样时间):Sampling time common 1(使用采样时间 1)

六、API 接口

ADC 采样和转化流程:

  1. 开启 ADC 采样校准模式
  2. 开启 ADC 采样转化功能
  3. 等待采样+转化结束,数字信号被存放到数据寄存器中
  4. 从数据寄存器中读取数字信号
  5. 通过模数转化公式,将数字信号转换为模拟信号,并在串口终端打印

注意:ADC 的校准采样必须在开启采样前或者关闭采样后

6.1 HAL_ADC_Start 函数

cpp 复制代码
HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef *hadc)

功能:

HAL库提供的用于开启ADC采样转化功能的函数

参数

hadc:ADC4外设控制器的句柄

返回值:

函数执行成功,返回HAL_OK

函数执行失败,返回错误码

6.2 HAL_ADC_GetValue 函数

cpp 复制代码
uint32_t HAL_ADC_GetValue(const ADC_HandleTypeDef *hadc)

功能:

HAL库提供的用于获取转化完毕的数字信号的函数

参数:

hadc:ADC4外设控制器的句柄

返回值:

返回成功获取的数字信号

6.3 HAL_ADC_PollForConversion 函数

cpp 复制代码
HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef *hadc, uint32_t Timeout)

功能:

HAL库提供的用于阻塞等待ADC采样+转化完毕,数据被存放到数据寄存器中的函数

参数:

hadc:ADC4外设控制器的句柄 Timeout:超时检测时间,当前函数的最大阻塞时间

返回值:

当ADC采样+转化数据完毕后,表示这个函数执行成功,函数执行成功,返回HAL_OK

当ADC采样+转化数据没结束时,此时这个函数处于阻塞状态

函数执行失败,返回错误码

HAL_MAX_DELAY 宏

cpp 复制代码
#define HAL_MAX_DELAY      0xFFFFFFFFU

6.4 HAL_ADC_Stop 函数

cpp 复制代码
HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef *hadc)

功能:

HAL库提供的用于关闭ADC采样转化功能的函数

参数:

hadc:ADC4外设控制器的句柄

返回值:

函数执行成功,返回HAL_OK

函数执行失败,返回错误码

6.5 HAL_ADCEx_Calibration_Start 校准采样函数

cpp 复制代码
HAL_StatusTypeDef 
HAL_ADCEx_Calibration_Start
(ADC_HandleTypeDef *hadc, uint32_t CalibrationMode, uint32_t SingleDiff)

功能:

HAL库提供的用于校准ADC采样的函数(此函数只需要开启一次即可)

参数:

hadc:ADC4外设控制器的句柄

CalibrationMode:校准模式的设置

ADC_CALIB_OFFSET 偏移量校准方式(最基础的)

ADC_CALIB_OFFSET_LINEARITY 硬件线性化校准(高级的) 线性化校准比偏移量校准更准确,一般使用一些高精度仪器上

SingleDiff:输入的模拟信号的选择

ADC_SINGLE_ENDED:输入单端信号(一个信号就代表一个电信号) ADC_DIFFERENTIAL_ENDED:输入差分信号(两个信号代表一个电信号)

返回值:

函数执行成功,返回HAL_OK

函数执行失败,返回错误码


七、代码编写

7.1 单通道单次转换模式

1)main.c 重写 fputc 函数

cpp 复制代码
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
int fputc(int ch,FILE* stream)
{
	HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,5);
	return ch;
}
/* USER CODE END 0 */

八、DMA 介绍

DMA (General purpose direct memory access controller):通用可编程直接内存访问控制器

内存:广义的内存,包括虚拟内存地址和物理内存地址

DMA 本质是硬件缓冲区(FIFO)


DMA 的作用

减轻 CPU 的压力,将简单的数据存储工作交给 DMA 去做,让 CPU 只负责逻辑处理和数据处理。
图 1 DMA 图示


  1. GPDMA 支持16 个独立通道,每个通道都可以用来独立暂存数据

  2. GPDMA 的通道用于数据的暂存和传输

单通道传输模式:使用一个通道进行数据传输

多通道传输模式:使用多个通道进行数据传输

同一时刻,只能使用一个 DMA 通道进行数据传输

  1. 使用 DMA 通道传输数据前,需要向 DMA 发送使用请求

谁先发送 DMA 通道请求,谁先使用 DMA 通道

  1. DMA 通道具有优先级等级,优先级等级高的 DMA 通道线传输数据,分为 4 个等级:

(1)低优先级

(2)中优先级

(3)高优先级

(4)超高优先级

  1. 使用 DMA 通道传输数据,一端是 Source 源设备(发送端), 一端是 Destination 目标设备(接收端)

  2. 使用 DMA 通道传输数据时,有 4 种数据传输方向:

(1)


十一、代码编写

cpp 复制代码
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t buf[1024];
//中断标志
volatile int flag=0;

int fputc(int ch,FILE* stream)
{
	HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,1);
	return ch;
}
/* USER CODE END 0 */
cpp 复制代码
 /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_GPDMA1_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */
	//开启串口使用DMA通道接收中断
	HAL_UART_Receive_DMA(&huart1,buf,sizeof(buf));
	//开启空闲中断
	__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		if(flag==1)
		{
			printf("buf=%s\n",buf);
			memset(buf,0,sizeof(buf));
			flag=0;
		}
		
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
cpp 复制代码
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
	extern volatile int flag;
	extern uint8_t buf[1024];
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
	if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE))
	{
		__HAL_UART_CLEAR_FLAG(&huart1,UART_CLEAR_IDLEF);
		
		//手动关闭DMA通道
		HAL_UART_DMAStop(&huart1);
		
		//逻辑代码
		flag=1;
		
		//重新开启
		HAL_UART_Receive_DMA(&huart1,buf,sizeof(buf));
	}
  /* USER CODE END USART1_IRQn 1 */
}
相关推荐
wei-dong-183797540083 小时前
嵌入式硬件笔记:三种滤波电路的对比
笔记·嵌入式硬件·算法
点灯小铭4 小时前
基于STM32单片机的OneNet物联网粉尘烟雾检测系统
stm32·单片机·物联网·毕业设计·课程设计
点灯小铭4 小时前
基于51单片机水塔水箱液水位WIFI监控报警设计
单片机·嵌入式硬件·mongodb·毕业设计·51单片机·课程设计
szxinmai主板定制专家5 小时前
基于RK3588与ZYNQ7045的ARM+FPGA+AI实时系统解决方案
arm开发·人工智能·嵌入式硬件·fpga开发
自激振荡器5 小时前
2,GUI Guider的安装与导入STM32裸机工程
stm32·单片机·嵌入式硬件·lvgl·gui guider
<man>6 小时前
STM32_08_中断(☆☆☆)
stm32·单片机·嵌入式硬件
沐欣工作室_lvyiyi6 小时前
基于单片机的智能奶茶机(论文+源码)
单片机·嵌入式硬件·毕业设计·智能奶茶机
俊昭喜喜里6 小时前
stm32中的位带操作的使用意义
stm32·单片机·嵌入式硬件
晶振厂家-晶发电子8 天前
晶振在5G时代的角色:高精度时钟的核心支撑
单片机·嵌入式硬件·5g·晶振·电子元器件·晶振知识