当前位置: 首页 > news >正文

STM32 AD单通道与多通道实战指南

文章目录

    • AD单通道(实验)
      • 有关配置的库函数
      • AD单通道部分主要代码
    • AD多通道实现
      • 多通道采集实现思路探讨
      • 单次转换非扫描模式实现AD多通道
      • AD多通道部分代码

学习建议:推荐搭配 江协科技 AD单通道 AD多通道一起食用!!!!
【STM32入门教程-2023版 细致讲解 中文字幕】https://www.bilibili.com/video/BV1th411z7sn?p=22&vd_source=66c03c3ecc640bbe982dc3d48bfd8841

AD单通道(实验)

在这里插入图片描述
在这里插入图片描述

  1. 初始化流程
    开启时钟 → 配置 GPIO 为模拟输入 → 配置规则组通道 → 初始化 ADC 结构体 → 开启 ADC 电源 → 校准 ADC。
  2. 单次转换流程
    软件触发转换 → 等待 EOC 标志位 → 读取转换结果。

有关配置的库函数

1. RCC_ADCCLKConfig

  • 功能:配置 ADC 的时钟分频器,确定 ADC 工作时钟(ADCCLK)。
  • 参数:可选分频系数为 2、4、6、8,输入时钟为 APB2 的 72MHz 时钟。
    • 示例:若选择 6 分频,ADCCLK = 72MHz / 6 = 12MHz。
  • 作用:确保 ADC 工作在合适的时钟频率下,保证转换精度和稳定性。
  • 在RCC库函数中,配置ADC工作时钟。

2.电源与校准函数

  • ADC_Cmd
    • 功能:开启或关闭 ADC 电源。
    • 参数ENABLE 启动 ADC,DISABLE 关闭。
  • 校准函数组(需按顺序调用):
    • ADC_ResetCalibration:复位校准寄存器。
    • ADC_GetResetCalibrationStatus:等待复位校准完成(通过循环检测标志位)。
    • ADC_StartCalibration:启动校准。
    • ADC_GetCalibrationStatus:等待校准完成(通过循环检测标志位)。
    • 作用:减小 ADC 转换误差,需在初始化后调用。

3.中断与 DMA 相关函数

  • ITConfig:开启或关闭 ADC 中断(如模拟看门狗中断)。
  • NVIC_Init:配置中断优先级(需结合 ITConfig 使用)。
  • DMA_Cmd:开启 DMA 传输(用于多通道数据搬运,会议中未深入讲解)。

4.触发与转换控制函数

  • ADC_SoftwareStartConvCmd
    • 功能:软件触发 ADC 开始转换(适用于单次转换模式)。
    • 参数ENABLE 触发转换,DISABLE 关闭。
  • ADC_GetSoftwareStartConvStatus
    • 不能获取软件触发转换状态,因为当有软件触发标志时,一旦开始转化就会将软件触发标志位清零,不会通过该函数获得是否转化完成。
  • ADC_GetFlagStatus
    • 功能:获取转换状态标志位。
    • 关键参数
      • ADC_FLAG_EOC:规则组转换完成标志位(转换结束后硬件置 1)。
    • 用途:通过检测 EOC 标志位判断转换是否完成,而非使用 ADC_GetSoftwareStartConvStatus(该函数仅返回触发状态,与转换完成无关)。

5.配置间断模式函数

  • ADC_DiscModeChannelCountConfig
    • 每隔几个通道间断一次
  • ADC_DiscModeCmd
    • 是否开启间断模式

6.规则组通道配置

  • ADC_RegularChannelConfig
    • 功能:配置规则组通道参数,如通道号、序列位置、采样时间。
    • 参数
      • ADCx:ADC 外设(如 ADC1)。
      • ADC_Channel:通道编号(如 PA0 对应 ADC_Channel_0)。
      • Rank:序列位置(1~16,非扫描模式下仅需设为 1)。
      • ADC_SampleTime:采样时间(影响转换速度和稳定性,可选短 / 中 / 长周期)。

7.其他

  • ADC_ExternalTrigConvCmd

    • 外部触发转换控制 ,就是是否允许外部触发转换
  • ADC_GetConversionValue

    • 功能:读取规则组通道的转换结果(16 位无符号整数)。
    • 返回值:转换后的数字量,需结合参考电压计算实际模拟值。
  • ADC_GetDualModeConversionValue

    • ADC获取双模式转换值,双ADC模式读取转化结果的函数
  • ADC_TempSensorVrefintCmd

    • ADC温度传感器,内部参考电压控制,用来开启内部的两个通道。

8.注入组与模拟看门狗函数

  • 注入组函数:带 Injected 前缀的函数(如 ADC_InjectedChannelConfig),用于配置紧急通道(会议中未使用)。

  • 模拟看门狗函数

    • ADC_AnalogWatchdogCmd:启动模拟看门狗,监测输入电压是否超出阈值。
    • ADC_AnalogWatchdogThresholdsConfig:设置电压阈值(高 / 低阈值)。
  • ADC_AnalogWatchdogSingleChannelConfig

    • 配置看门的通道

AD单通道部分主要代码

// AD.c
#include "stm32f10x.h"                  // Device headervoid AD_Init(void)
{//1.开始时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//2. 配置ADC时钟信号//只能使用6 或者 8 分频,因为有限制RCC_ADCCLKConfig(RCC_PCLK2_Div6);//3.配置gpio口 //初始化gpioinit参数中的结构体GPIO_InitTypeDef GPIO_InitStructure;//将gpio口设置为模拟输入模式,就是io口不起作用不会影响数据转化GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//4.配置规则组通道ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);//5.初始化ADC模块ADC_InitTypeDef ADC_InitStruct;//是否连续转化ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;//对齐方式ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//外部触发方式,使用软件触发,所以配置为ADC_ExternalTrigConv_NoneADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;ADC_InitStruct.ADC_NbrOfChannel = 1;//配置连续扫描ADC_InitStruct.ADC_ScanConvMode = DISABLE;ADC_Init(ADC1, &ADC_InitStruct);//6. 开启ADC总开关ADC_Cmd(ADC1, ENABLE);//7.校准ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1) == SET);ADC_StartCalibration(ADC1);while(ADC_GetCalibrationStatus(ADC1) == SET);}
//启动转换,获取结果函数
uint16_t AD_GetValve(void)
{//内部软件启动转换ADC_SoftwareStartConvCmd(ADC1, ENABLE);//查看是否转化完成//查看标志位,转化完成会将EOC标志位置一while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);//读取数据return ADC_GetConversionValue(ADC1);
}

AD多通道实现

多通道采集实现思路探讨

  • 扫描模式结合 DMA :利用列表填充四个通道触发转换可实现多通道,但存在数据覆盖问题,最好配合 DMA 实现,讲完 DMA 后再尝试。
  • 手动转运数据问题 :扫描模式下单个通道转换完成无标志位和中断,只有整个列表转换完才有 EOC 标志位和中断,易造成数据覆盖丢失;且 AD 转换快,手动转运数据对程序要求高,操作困难。
  • 间断模式手动转运 :可使用间断模式,每转换一个通道暂停,手动转运数据后再继续,但因无标志位需靠 delay 延时保证转换完成,不省心且效率低,暂不推荐。

单次转换非扫描模式实现AD多通道

  • 具体实现方式 :每次触发转换前手动更改列表第一个位置的通道,如依次写入通道 0、1、2、3 等,触发转换等待读值,就能实现多通道转换。

AD多通道部分代码

//AD.c
#include "stm32f10x.h"                  // Device headervoid AD_Init(void)
{//1.开始时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//2. 配置ADC时钟信号//只能使用6 或者 8 分频,因为有限制RCC_ADCCLKConfig(RCC_PCLK2_Div6);//3.配置gpio口  //初始化gpioinit参数中的结构体GPIO_InitTypeDef GPIO_InitStructure;//将gpio口设置为模拟输入模式,就是io口不起作用不会影响数据转化GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//5.初始化ADC模块ADC_InitTypeDef ADC_InitStruct;//是否连续转化ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;//对齐方式ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//外部触发方式,使用软件触发,所以配置为ADC_ExternalTrigConv_NoneADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;ADC_InitStruct.ADC_NbrOfChannel = 1;//配置连续扫描ADC_InitStruct.ADC_ScanConvMode = DISABLE;ADC_Init(ADC1, &ADC_InitStruct);//6. 开启ADC总开关ADC_Cmd(ADC1, ENABLE);//7.校准ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1) == SET);ADC_StartCalibration(ADC1);while(ADC_GetCalibrationStatus(ADC1) == SET);}
//使用单次转化,非扫描模式实现AD多通道
//启动转换,获取结果函数
uint16_t AD_GetValve(uint8_t ADC_Channel)
{//配置规则组通道ADC_RegularChannelConfig(ADC1, ADC_Channel, 1, ADC_SampleTime_55Cycles5);//内部软件启动转换ADC_SoftwareStartConvCmd(ADC1, ENABLE);//查看是否转化完成//查看标志位,转化完成会将EOC标志位置一while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);//读取数据return ADC_GetConversionValue(ADC1);
}
//main.c#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "AD.h"
uint16_t value0;
uint16_t value1;
uint16_t value2;
uint16_t value3;int main(void)
{OLED_Init();AD_Init();OLED_ShowString(1, 1, "V0:");OLED_ShowString(2, 1, "V1:");OLED_ShowString(3, 1, "V2:");OLED_ShowString(4, 1, "V3:");while(1){value0 = AD_GetValve(ADC_Channel_0);value1 = AD_GetValve(ADC_Channel_1);value2 = AD_GetValve(ADC_Channel_2);value3 = AD_GetValve(ADC_Channel_3);OLED_ShowNum(1, 4, value0, 4);OLED_ShowNum(2, 4, value1, 4);OLED_ShowNum(3, 4, value2, 4);OLED_ShowNum(4, 4, value3, 4);Delay_ms(100);}
}

http://www.xdnf.cn/news/711271.html

相关文章:

  • 【QT】理解QT的“元对象系统”
  • 【Tips】关于PCI和PCIe的配置空间差异和io/memory io读写
  • 【CF】Day69——⭐Codeforces Round 897 (Div. 2) D (图论 | 思维 | DFS | 环)
  • Redis--基础知识点--28--慢查询相关
  • 【ConvLSTM第二期】模拟视频帧的时序建模(Python代码实现)
  • CppCon 2014 学习第4天:Transactional Language Constructs for C++ TS(未进入到标准)
  • RDS PostgreSQL手动删除副本集群副本的步骤
  • 58同城C++开发面试题及参考答案
  • OpenCV CUDA模块结构分析与形状描述符------计算指定阶数的矩(Moments)所需的总数量函数:numMoments
  • json转成yolo用的txt(json中没有宽高,需要自设宽高的)
  • Mysql数据库 索引,事务
  • 数据库 | 时序数据库选型
  • 物联网常用协议Modbus、CAN、BACnet介绍
  • UniApp X:鸿蒙原生开发的机会与DCloud的崛起之路·优雅草卓伊凡
  • EasyVoice:开源的文本转语音工具,让文字“开口说话“
  • C语言学习笔记四---V
  • Spring官方的在线教程也可以用中文观看了
  • js如何把json对象格式数据快速字符串
  • 长安链合约操作 查询合约命令解析
  • 基于 GitLab CI + Inno Setup 实现 Windows 程序自动化打包发布方案
  • 2025年- H57-Lc165--994.腐烂的橘子(图论,广搜)--Java版
  • GPIO模拟串口通信
  • DeepSeek - 尝试一下GitHub Models中的DeepSeek
  • Vue2部分知识点和注意项
  • SAP销售订单批导创建
  • C/C++ OpenCV 矩阵运算
  • CentOS:企业级Linux的社区力量与未来演进
  • vue-seamless-scroll 结束从头开始,加延时后滚动
  • Windows 11 全角半角切换方法
  • 极坐标系下的极径 r 表示点到原点的距离 大于等于0