(STM32)ADC驱动配置

embedded/2024/11/30 3:06:10/

1.ADC驱动(STM32)

ADC模块中,**常规模式(Regular Mode)和注入模式(Injected Mode)**是两种不同的ADC工作模式

常规模式:用于普通的ADC转换,是默认的ADC工作模式。

注入模式:用于对特定通道进行高优先级的ADC采样。

特性

常规模式(Regular Mode)

注入模式(Injected Mode)

优先级

采样通道

支持多通道,按顺序扫描

支持多通道,但专用优先处理

DMA的兼容性

支持,适合连续采样传输

通常不使用 DMA

场景

采集温度、湿度等非关键的环境传感器数据

采集电流、电压等高优先级的实时数据

1.1 常规模式

  1. 转换触发方式:软件启动或者外部硬件触发(比如使用函数开启读取数据这种)

  2. 数据转换完存储在ADC的数据寄存器(ADC_DR)中(这个知道就行,平常也用不到)

  3. 支持、适合使用DMA进行连续数据传输

  4. 可配置扫描模式,对多个通道依次采样

  5. 转换通道数可以通过 NbrOfConversion 配置

1.1.1 初始化代码

下面的代码按照:配置ADC参数、初始化ADC、启动校准、配置常规模式的参数、写入常规通道顺序写的

int32_t stm32_adc_init(void)
{// 定义ADC配置结构体(常规模式)ADC_ChannelConfTypeDef sConfig = {0};// 初始化ADC3的实例hadc3.Instance = ADC3;// 配置ADC的初始化参数hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;          // 异步时钟分频因子设为4hadc3.Init.Resolution = ADC_RESOLUTION_12B;               // 分辨率为12位hadc3.Init.DataAlign = ADC3_DATAALIGN_RIGHT;              // 数据右对齐hadc3.Init.ScanConvMode = ADC_SCAN_ENABLE;                // 启用扫描模式hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV;            // 每次单次转换结束触发EOChadc3.Init.LowPowerAutoWait = DISABLE;                    // 禁用低功耗模式hadc3.Init.ContinuousConvMode = DISABLE;                  // 禁用连续转换模式(单次模式)hadc3.Init.NbrOfConversion = 2;                           // 常规模式中转换2个通道hadc3.Init.DiscontinuousConvMode = DISABLE;               // 禁用不连续模式hadc3.Init.DMAContinuousRequests = ENABLE;                // 启用DMA连续请求hadc3.Init.SamplingMode = ADC_SAMPLING_MODE_NORMAL;        // 使用普通采样模式hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR; // 数据直接存储到数据寄存器hadc3.Init.Overrun = ADC_OVR_DATA_PRESERVED;              // 数据溢出时保持旧数据hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;          // 禁用左移位操作hadc3.Init.OversamplingMode = DISABLE;                    // 禁用过采样// 初始化ADC,检查初始化是否成功if (HAL_ADC_Init(&hadc3) != HAL_OK){Error_Handler();  // 如果失败,调用错误处理函数}// 启动ADC校准HAL_ADCEx_Calibration_Start(&hadc3, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);// 配置第1个通道:通道0sConfig.Channel = ADC_CHANNEL_0;                          // 通道0sConfig.Rank = ADC_REGULAR_RANK_1;                        // 常规序列中的第1个通道sConfig.SamplingTime = ADC_SAMPLETIME_810CYCLES_5;         // 采样时间为810.5周期sConfig.SingleDiff = ADC_SINGLE_ENDED;                    // 单端输入模式sConfig.OffsetNumber = ADC_OFFSET_NONE;                   // 不使用偏移校正sConfig.Offset = 0;                                       // 偏移量为0if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK){Error_Handler();  // 如果配置失败,调用错误处理函数}// 配置第2个通道:通道1sConfig.Channel = ADC_CHANNEL_1;                          // 通道1sConfig.Rank = ADC_REGULAR_RANK_2;                        // 常规序列中的第2个通道if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK){Error_Handler();  // 如果配置失败,调用错误处理函数}// 开启ADC转换,通常在主程序中启动HAL_ADC_Start(&hadc3);return 0;  // 返回0表示初始化成功
}

1.2 注入模式

  1. 转换触发方式:常规一样,但是独立于常规模式的触发,可以在任意时间插入采样

  2. 注入模式启动,会中断常规模式转换,优先完成注入模式的采样

  3. 通常不使用 DMA

  4. 转换结果存储在专用的注入数据寄存器(ADC_JDRx)中

  5. 每次触发可以采样一个或多个通道(InjectedNbrOfConversion 用于配置注入通道数)。

1.2.1 CUBEMX中的配置(参考)

可以通过配置CUBEMX中的配置进行参考,这里也使用的是注入模式的三个通道,IN0 1 和Temperature,这个当作参考,代码我删了一个通道。

其中IN1的single-ended表示的是:ADC 只采集输入信号相对于地的电压值(单端输入),比如VCC是3.3V,GND是0V,那么输入信号0V--->ADC读取0,输入信号3.3V--->ADC读取4095(分辨率12位)。看配置模块的要求,信号直接连接。

还有一个是differential模式(差分模式):采取差分信号进行读取数据,抗干扰能力强。这个除非使用的是差分信号接口才选择这个

 

1.2.2 初始化代码

下面的代码按照:配置ADC参数、初始化ADC、启动校准、配置注入模式的参数、写入注入通道顺序写的

int32_t stm32_adc_init(void)
{// 定义并初始化一个注入模式配置结构体变量ADC_InjectionConfTypeDef sConfigInjected = {0};// 初始化ADC3的实例hadc3.Instance = ADC3;// 配置ADC的初始化参数hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;          // 异步时钟分频因子设为4hadc3.Init.Resolution = ADC_RESOLUTION_12B;               // 分辨率为12位hadc3.Init.DataAlign = ADC3_DATAALIGN_RIGHT;              // 数据右对齐hadc3.Init.ScanConvMode = ADC_SCAN_ENABLE;                // 启用扫描模式hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV;            // 每次单次转换结束触发EOChadc3.Init.LowPowerAutoWait = DISABLE;                    // 禁用低功耗模式hadc3.Init.ContinuousConvMode = DISABLE;                  // 禁用连续转换模式hadc3.Init.NbrOfConversion = 1;                           // 常规模式中转换数量为1hadc3.Init.DiscontinuousConvMode = DISABLE;               // 禁用不连续模式hadc3.Init.DMAContinuousRequests = DISABLE;               // 禁用DMA连续请求hadc3.Init.SamplingMode = ADC_SAMPLING_MODE_NORMAL;        // 使用普通采样模式hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR; // 数据直接存储到数据寄存器hadc3.Init.Overrun = ADC_OVR_DATA_PRESERVED;              // 数据溢出时保持旧数据hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;          // 禁用左移位操作hadc3.Init.OversamplingMode = DISABLE;                    // 禁用过采样// 初始化ADC,检查初始化是否成功if (HAL_ADC_Init(&hadc3) != HAL_OK){Error_Handler();  // 如果失败,调用错误处理函数}// 启动ADC校准,使用偏移校准和单端模式HAL_ADCEx_Calibration_Start(&hadc3, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED);// 配置注入通道的第一个通道:通道0sConfigInjected.InjectedChannel = ADC_CHANNEL_0;                  // 注入通道为0sConfigInjected.InjectedRank = ADC_REGULAR_RANK_1;                // 注入序列中的第1个通道sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_810CYCLES_5; // 采样时间为810.5周期sConfigInjected.InjectedSingleDiff = ADC_SINGLE_ENDED;            // 单端输入模式sConfigInjected.InjectedOffsetNumber = ADC_OFFSET_NONE;           // 不使用偏移校正sConfigInjected.InjectedOffset = 0;                               // 偏移量为0sConfigInjected.InjectedNbrOfConversion = 2;                      // 注入模式中有2个通道sConfigInjected.InjectedDiscontinuousConvMode = DISABLE;          // 禁用注入的不连续模式sConfigInjected.AutoInjectedConv = DISABLE;                       // 禁用自动注入sConfigInjected.QueueInjectedContext = DISABLE;                   // 禁用注入上下文队列sConfigInjected.ExternalTrigInjecConv = ADC_INJECTED_SOFTWARE_START; // 使用软件触发注入模式sConfigInjected.ExternalTrigInjecConvEdge = ADC_EXTERNALTRIGINJECCONV_EDGE_NONE; // 无触发边沿sConfigInjected.InjecOversamplingMode = DISABLE;                  // 禁用注入模式的过采样// 配置第一个注入通道if (HAL_ADCEx_InjectedConfigChannel(&hadc3, &sConfigInjected) != HAL_OK){Error_Handler();  // 如果配置失败,调用错误处理函数}// 配置第二个注入通道:通道1sConfigInjected.InjectedChannel = ADC_CHANNEL_1;          // 注入通道为1sConfigInjected.InjectedRank = ADC_INJECTED_RANK_2;       // 注入序列中的第2个通道if (HAL_ADCEx_InjectedConfigChannel(&hadc3, &sConfigInjected) != HAL_OK){Error_Handler();  // 如果配置失败,调用错误处理函数}// 开始注入模式的转换HAL_ADCEx_InjectedStart(&hadc3);return 0;  // 返回0表示初始化成功
}

1.3 使用

配置完初始化之后,可以通过以下方式调用读取:这里用的是轮询模式,即阻塞模式读取;还可以用DMA(配置有一点区别,函数中调用不同的函数开启,适合连续采样)、和中断方式(实时处理采样数据,转换完成时触发中断,将采集的函数放在中断回调函数里面,通常用这个)。

#include "main.h"int main(void)
{HAL_Init();                  // 初始化HAL库SystemClock_Config();        // 配置系统时钟stm32_adc_init();           // 初始化ADC注入模式uint32_t values[3]; // 用于存储3个注入通道的ADC值while (1){/*注入模式:// 触发注入模式转换(软件触发)HAL_ADCEx_InjectedStart(&hadc3);// 等待转换完成(注入模式支持轮询方式)if (HAL_ADCEx_PollForInjectedConversion(&hadc3, HAL_MAX_DELAY) == HAL_OK){// 从注入数据寄存器中读取结果values[0] = HAL_ADCEx_InjectedGetValue(&hadc3, ADC_INJECTED_RANK_1);values[1] = HAL_ADCEx_InjectedGetValue(&hadc3, ADC_INJECTED_RANK_2);}*//*常规模式:// 启动ADCHAL_ADC_Start(&hadc3);// 等待转换完成(轮询模式)for (uint32_t i = 0; i < 2; i++){// 等待当前通道转换完成if (HAL_ADC_PollForConversion(&hadc3, HAL_MAX_DELAY) == HAL_OK){// 读取当前通道的转换值adc_values[i] = HAL_ADC_GetValue(&hadc3);}}HAL_ADC_Stop(&hadc3); // 停止ADC转换*/}
}


http://www.ppmy.cn/embedded/141636.html

相关文章

windows C#-迭代器(下)

对泛型列表使用迭代器 在以下示例中&#xff0c;Stack<T> 泛型类实现 IEnumerable<T> 泛型接口。 Push 方法将值分配给类型为 T 的数组。 GetEnumerator 方法通过使用 yield return 语句返回数组值。 除了泛型 GetEnumerator 方法&#xff0c;还必须实现非泛型 G…

std库锁机制的使用

在多线程编程中,关键资源的读写访问是程序员需要非常重视的部分。而控制好读写主要靠的就是锁机制,在各个编程框架中都提供了锁的实现机制。这一篇就简单列举一下std标准库中提供的一些锁机制。 锁是干什么用的 这里稍微啰嗦一句,用通俗的话解释一下锁是干什么用的。其实我…

2024年第十三届”认证杯“数学中国数学建模国际赛(小美赛)

↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓

【JavaEE初阶 — 网络编程】TCP流套接字编程

TCP流套接字编程 1. TCP &#xff06; UDP 的区别 TCP 的核心特点是面向字节流&#xff0c;读写数据的基本单位是字节 byte 2 API介绍 2.1 ServerSocket 定义 ServerSocket 是创建 TCP 服务端 Socket 的API。 构造方法 方法签名 方法说明 ServerS…

Mybatis集成篇(一)

Spring 框架集成Mybatis 目前主流Spring框架体系中&#xff0c;可以集成很多第三方框架&#xff0c;方便开发者利用Spring框架机制使用第三方框架的功能。就例如本篇Spring集成Mybatis 简单集成案例&#xff1a; Config配置&#xff1a; Configuration MapperScan(basePack…

Git远程仓库过大导致clone失败的解决方法

方法1. 升级为git 最新版本 方法2&#xff1a; 浅层clone 首先clone一层&#xff1a; 1$ git clone --depth1 http://xxx.git浅层clone成功后&#xff0c;再完整拉取&#xff1a; 1 2 3$ git fetch --unshallow # 拉取完整当前分支 $ git remote set-branches origin * # 追…

架构第十八章:jenkins

CI&CD: 持续集成注重将各个开发者的工作集合到一个代码仓库中&#xff0c;通常每天会进行几次&#xff0c; 主要目的是尽早发现集成错误&#xff0c;使团队更加紧密结合&#xff0c;更好地协作。 持续交付的目的是最小化部署或发布过程中团队固有的摩擦&#xff0c; 它的实…

iphone小程序设置burpsuite代理抓包

1、iphone、burpsuite链接同一wifi 2、burpsuite设置代理 3、iphone配置代理 4、浏览器访问“http://burp”&#xff0c;下载证书&#xff0c;安装证书 5、前往“设置”>“通用”>“关于本机”>“证书信任设置”。 在“针对根证书启用完全信任”下&#xff0c;开启对…