学习链接:【HAL库详解】STM32 ADC HAL库使用_哔哩哔哩_bilibili
目录
一、概念
1、ADC介绍
12位ADC是一种逐次逼近型模拟数字转换器。它有多达18个通道,可测量16个外部和2个内部
信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。 ADC的结果可以左对齐或右
对齐方式存储在16位数据寄存器中。
2、ADC主要特征
12位分辨率
● 转换结束、注入转换结束和发生模拟看门狗事件时产生中断
● 单次和连续转换模式
● 从通道0到通道n的自动扫描模式
● 自校准
● 带内嵌数据一致性的数据对齐
● 采样间隔可以按通道分别编程
● 规则转换和注入转换均有外部触发选项
● 间断模式
● 双重模式(带2个或以上ADC的器件)
● ADC转换时间:
─ STM32F103xx增强型产品:时钟为56MHz时为1μs(时钟为72MHz为1.17μs)
● ADC供电要求: 2.4V到3.6V
● ADC输入范围: VREF- ≤ VIN ≤ VREF+
● 规则通道转换期间有DMA请求产生。
二、ADC模式
1、查询(阻塞)模式
1.1 单通道采集软件配置
1.1.1 只需选择接口就行
1.1.2 打开串口用于打印数据
1.2 查询模式步奏
1.3 查询模式主要函数
①HAL_ADC_Start(&hadc1);
启动ADC及ADC转换
②HAL_ADC_Stop(&hadc1);
关闭ADC
③HAL_ADC_PollForConversion(&hadc1, 100);//阻塞判断是否转换完成
轮询检查ADC转换是否完成,转换完成会返回一个状态
④HAL_ADC_PollForEvent();
等待指定ADC事件发生,并返回一个状态,可以用于等待某个特定的事件发生然后执行相关代码。
//ADC_PollForEvent`函数用于轮询检查ADC事件是否发生。
// 假设使用了ADC1进行操作
ADC_HandleTypeDef hadc1; // 声明一个 ADC_HandleTypeDef 结构体变量
// 在适当的地方对ADC1进行初始化配置
// 等待ADC转换完成的函数
void wait_for_adc_event() {
// 在这里进行ADC转换启动等操作(例如设置通道、采样时间等)
// 轮询检查特定的ADC事件,例如转换完成事件
while (HAL_ADC_PollForEvent(&hadc1, ADC_EOC_SINGLE_CONV) != HAL_OK) {
// 可以添加一些等待的代码,或者执行其他操作
}
// 如果到达这里,表示已经检测到了特定的ADC事件(例如转换完成事件)
// 可以继续执行其他代码,例如获取ADC转换值等
}
//使用ADC_PollForEvent函数等待特定的 ADC 事件(单次转换完成事件 ADC_EOC_SINGLE_CONV)
//然后在事件发生后执行相应的操作。在实际应用中,根据需求可能需要进行相应的配置和处理。
1.4 单通道采集主要代码
#include <stdio.h>
#include <string.h>
//ADC采集值获取
int16_t get_adc_value(void)
{
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 100);//阻塞判断是否转换完成
if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1),HAL_ADC_STATE_REG_EOC))
{
return HAL_ADC_GetValue(&hadc1);
}
return -1;
}
//main函数主循环代码如下
/* USER CODE BEGIN WHILE */
int16_t value=0;
char buff[30];
while (1)
{
value=get_adc_value();
if(value==-1)
{
HAL_UART_Transmit(&huart2, (uint8_t*)"GetADCValue Faild !! \r\n", 25, 50);
}
else
{
sprintf(buff, "value:%d \r\n",value);
HAL_UART_Transmit(&huart2, (uint8_t*)buff, strlen(buff), 50);
}
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
1.5 多通道采集
2、中断模式
3、DMA模式
三、多通道采集
2.1 软件配置
2.2 主要代码
while (1)
{
get_adc_value(DMARes);
sprintf(buff, "value:%d,%d,%d \r\n",DMARes[0],DMARes[1],DMARes[2]);
HAL_UART_Transmit(&huart2, (uint8_t*)buff, strlen(buff), 50);
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
void get_adc_value(int* DMARes)
{
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 100);//阻塞判断是否转换完成
DMARes[0]= HAL_ADC_GetValue(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 100);//阻塞判断是否转换完成
DMARes[1]= HAL_ADC_GetValue(&hadc1);
HAL_ADC_PollForConversion(&hadc1, 100);//阻塞判断是否转换完成
DMARes[2]= HAL_ADC_GetValue(&hadc1);
HAL_ADC_Stop(&hadc1);
}