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

规则组,注入组

在STM32的ADC模块中,通道复用机制通过灵活的规则组和注入组实现多通道采样,下面详细解释其工作原理和配置方法:


1. 分时复用机制

(1)硬件基础
  • 多路开关(MUX):ADC内部有一个电子开关,按顺序将不同通道连接到ADC核心。
  • 单次转换:同一时间仅一个通道被采样,12位逐次逼近转换完成后切换下一通道。
(2)触发方式
  • 软件触发:手动启动转换(ADC_SoftwareStartConvCmd())。
  • 硬件触发:通过定时器、外部中断等自动触发(如PWM同步采样)。

2. 规则组(Regular Group)

(1)功能特点
  • 常规多通道采样:按预设顺序依次转换多个通道(最多16个)。
  • 顺序可控:通过ADC_SQRx寄存器设置通道顺序和总数。
  • 典型应用:周期性采集传感器数据(如温度、电压)。
(2)配置步骤
// 设置规则组通道(3个通道)
ADC_RegularChannelConfig(ADC1, ADC_Channel_0,  1, ADC_SampleTime_55Cycles5);  // 第1个转换:PA0
ADC_RegularChannelConfig(ADC1, ADC_Channel_5,  2, ADC_SampleTime_55Cycles5);  // 第2个转换:PA5
ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 3, ADC_SampleTime_239Cycles5); // 第3个转换:温度传感器// 启用扫描模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_NbrOfChannel = 3;  // 通道数
ADC_Init(ADC1, &ADC_InitStructure);// 启动转换(软件触发)
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
(3)数据读取
  • 单次读取:等待EOC标志后读取ADC_DR(仅最后通道数据)。
  • DMA传输:推荐方式,自动存储所有通道数据到数组。
    uint16_t adcValues[3];  // 存储规则组数据
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)adcValues;
    DMA_InitStructure.DMA_BufferSize = 3;
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);
    ADC_DMACmd(ADC1, ENABLE);
    

3. 注入组(Inject Group)

(1)功能特点
  • 高优先级中断采样:可打断规则组转换,立即执行注入组采样。
  • 独立数据寄存器:结果存储在ADC_JDR1~4(规则组用ADC_DR)。
  • 典型应用:紧急事件检测(如过压、超温)。
(2)配置步骤
// 配置注入组(2个通道)
ADC_InjectedChannelConfig(ADC1, ADC_Channel_1,  1, ADC_SampleTime_55Cycles5);  // 第1注入:PA1
ADC_InjectedChannelConfig(ADC1, ADC_Channel_17, 2, ADC_SampleTime_239Cycles5); // 第2注入:VREFINT// 设置触发方式(外部触发)
ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_Ext_IT15);// 启用注入组中断
ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE);
NVIC_EnableIRQ(ADC1_2_IRQn);
(3)中断服务例程
void ADC1_2_IRQHandler(void) {if (ADC_GetITStatus(ADC1, ADC_IT_JEOC)) {uint16_t inj1 = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_1); // PA1uint16_t inj2 = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_2); // VREFINTADC_ClearITPendingBit(ADC1, ADC_IT_JEOC);}
}

4. 规则组与注入组对比

特性规则组(Regular)注入组(Injected)
通道数量最多16通道最多4通道
触发方式软件/硬件触发软件/硬件触发(可打断规则组)
数据寄存器ADC_DR(需DMA)ADC_JDR1~4(独立存储)
中断标志EOC(转换结束)JEOC(注入组转换结束)
典型应用周期性多通道采样紧急事件的高优先级采样

5. 混合使用示例

// 规则组:循环采样PA0和PA5
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 2, ADC_SampleTime_55Cycles5);
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_NbrOfChannel = 2;
ADC_Init(ADC1, &ADC_InitStructure);// 注入组:外部触发紧急采样PA1
ADC_InjectedChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);
ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_T2_TRGO);// 启动规则组(连续模式)
ADC_ContinuousConvModeCmd(ADC1, ENABLE);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);

6. 关键注意事项

  1. 优先级管理

    • 注入组转换会立即中断规则组,完成后规则组继续。
    • 若规则组使用DMA,注入组数据不会影响DMA传输。
  2. 时序控制

    • 硬件触发时,规则组和注入组的触发源需分开(如定时器不同通道)。
  3. 校准影响

    • ADC校准对所有通道(规则+注入)生效,无需单独校准。

通过合理配置规则组和注入组,可实现复杂的多通道采样策略,兼顾常规监测和紧急响应需求。

以下是一个结合 规则组(Regular Group)注入组(Injected Group) 的实际项目示例,用于 电池电压监测(规则组)过压紧急检测(注入组),包含完整代码和注释。


项目需求

  1. 规则组:循环采集3路外部电压(电池电压、负载电流、温度传感器)。
  2. 注入组:当电池电压超过阈值时,通过外部中断触发紧急采样(高优先级)。
  3. 硬件配置
    • STM32F103RC
    • ADC1规则组:PA0(电池电压)、PA1(负载电流)、PA2(温度传感器)
    • ADC1注入组:PA3(过压检测专用通道)
    • 定时器TIM2触发规则组,外部按键(PA8)触发注入组。

完整代码实现

1. 初始化配置
#include "stm32f10x.h"#define BATTERY_ADC_CHANNEL     ADC_Channel_0  // PA0
#define CURRENT_ADC_CHANNEL     ADC_Channel_1  // PA1
#define TEMP_ADC_CHANNEL        ADC_Channel_2  // PA2
#define OVERVOLTAGE_ADC_CHANNEL ADC_Channel_3  // PA3(注入组)uint16_t regularData[3];  // 存储规则组数据(电池、电流、温度)
uint16_t injectedData;    // 存储注入组数据(过压值)void ADC_Configuration(void) {ADC_InitTypeDef ADC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;// 1. 启用时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);// 2. 配置GPIO为模拟输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOA, &GPIO_InitStructure);// 3. 规则组配置(循环采样PA0/PA1/PA2)ADC_RegularChannelConfig(ADC1, BATTERY_ADC_CHANNEL,  1, ADC_SampleTime_55Cycles5);ADC_RegularChannelConfig(ADC1, CURRENT_ADC_CHANNEL,  2, ADC_SampleTime_55Cycles5);ADC_RegularChannelConfig(ADC1, TEMP_ADC_CHANNEL,     3, ADC_SampleTime_239Cycles5);ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;ADC_InitStructure.ADC_ScanConvMode = ENABLE;        // 扫描模式ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;   // 连续转换ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO; // TIM2触发ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStructure.ADC_NbrOfChannel = 3;ADC_Init(ADC1, &ADC_InitStructure);// 4. 注入组配置(PA3,外部中断触发)ADC_InjectedChannelConfig(ADC1, OVERVOLTAGE_ADC_CHANNEL, 1, ADC_SampleTime_55Cycles5);ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_Ext_IT15); // PA8按键触发ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE);  // 启用注入组中断// 5. 启用DMA传输规则组数据DMA_InitTypeDef DMA_InitStructure;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)regularData;DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;DMA_InitStructure.DMA_BufferSize = 3;DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;DMA_InitStructure.DMA_Priority = DMA_Priority_High;DMA_Init(DMA1_Channel1, &DMA_InitStructure);DMA_Cmd(DMA1_Channel1, ENABLE);ADC_DMACmd(ADC1, ENABLE);// 6. 配置注入组中断NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  // 高优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);// 7. 启动ADC和定时器ADC_Cmd(ADC1, ENABLE);ADC_ResetCalibration(ADC1);while(ADC_GetResetCalibrationStatus(ADC1));ADC_StartCalibration(ADC1);while(ADC_GetCalibrationStatus(ADC1));ADC_SoftwareStartConvCmd(ADC1, ENABLE);// 配置TIM2触发规则组(1kHz采样率)TIM_TimeBaseInitTypeDef TIM_InitStructure;TIM_InitStructure.TIM_Period = 7200 - 1;  // 72MHz/7200 = 10kHzTIM_InitStructure.TIM_Prescaler = 0;TIM_InitStructure.TIM_ClockDivision = 0;TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM2, &TIM_InitStructure);TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);  // 更新事件触发ADCTIM_Cmd(TIM2, ENABLE);
}
2. 注入组中断服务函数
void ADC1_2_IRQHandler(void) {if (ADC_GetITStatus(ADC1, ADC_IT_JEOC)) {injectedData = ADC_GetInjectedConversionValue(ADC1, ADC_InjectedChannel_1);// 过压处理逻辑(例如关闭电源)if (injectedData > 3000) {  // 假设3V为阈值GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_RESET);  // 关闭电源继电器}ADC_ClearITPendingBit(ADC1, ADC_IT_JEOC);}
}
3. 主循环
int main(void) {ADC_Configuration();while (1) {// 规则组数据通过DMA自动更新到regularData数组float batteryVoltage = regularData[0] * 3.3f / 4095;  // 转换为电压值float current = regularData[1] * 3.3f / 4095;float temperature = regularData[2] * 3.3f / 4095;// 其他业务逻辑...}
}

关键机制解析

  1. 规则组

    • 由TIM2定时触发(1kHz),循环采样PA0/PA1/PA2。
    • 数据通过DMA自动存入regularData数组,无需CPU干预。
  2. 注入组

    • 由PA8按键(外部中断)触发,立即中断规则组并采样PA3。
    • 过压时在中断中紧急切断电源(高优先级响应)。
  3. 优先级

    • 注入组中断优先级(0)高于DMA传输,确保紧急事件即时处理。

实际应用场景

  • 电动汽车BMS:规则组监控电池组电压/电流,注入组在单体过压时紧急切断。
  • 工业PLC:规则组采集传感器数据,注入组处理急停信号。

通过此设计,实现了常规监测紧急响应的完美结合,充分发挥STM32 ADC的灵活性。

PA8按键:
(1)人工紧急检测
场景示例:

工业设备运行中,操作员发现异常(如仪表显示电压波动),手动按下PA8按键,立即触发ADC注入组采集关键信号(如PA3的紧急传感器数据)。

医疗设备中,医生在患者出现异常时手动触发高优先级采样。

特点:

依赖人员主动干预,适合非周期性但需要即时响应的场景。

(2)硬件故障保护
场景示例:

电源系统中,过压保护电路检测到电压超标后,通过硬件信号(如比较器输出)自动触发PA8中断(无需人工按键),注入组快速采集故障信号并执行保护动作(如切断电源)。

特点:

完全由硬件自动触发,响应速度极快(微秒级)。

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

相关文章:

  • setData执行后操作方法-微信小程序
  • DeepResearch深度搜索实现方法调研
  • 在线工具源码_字典查询_汉语词典_成语查询_择吉黄历等255个工具数百万数据 养站神器,安装教程
  • 嵌入式学习笔记 - 垂直消隐期
  • 自然语言处理-词性标注的基本概念
  • 黄金、碳排放期货市场API接口文档
  • 【阿里云免费领取域名以及ssl证书,通过Nginx反向代理web服务】
  • BUUCTF——杂项渗透之赛博朋克
  • 操作系统导论——第27章 插叙:线程API
  • softmax传递函数+交叉熵损失
  • ACTF2025 - Web writeup
  • C++编程语言:标准库:标准库概观(Bjarne Stroustrup)
  • 第六章 进阶09 我的人才观
  • 【设计模式】GoF设计模式之策略模式(Strategy Pattern)
  • rust 中的 EBNF 介绍
  • Uniapp编写微信小程序,使用canvas进行绘图
  • uni-app,小程序中的addPhoneContact,保存联系人到手机通讯录
  • 不止是UI库:React如何重塑前端开发范式?
  • Java中的内部类详解
  • iOS创建Certificate证书、制作p12证书流程
  • eNSP中路由器RIP协议配置完整实验实验和命令解释
  • Starrocks 的 ShortCircuit短路径
  • Rspress-快如闪电的静态站点生成器
  • Linux 学习笔记1
  • cilium路由模式和aws-eni模式下的IPAM
  • MySQL有哪些高可用方案?
  • CommunityToolkit.Mvvm详解
  • 前端面试每日三题 - Day 29
  • JavaScript性能优化实战,从理论到落地的全面指南
  • 阿里云 SLS 多云日志接入最佳实践:链路、成本与高可用性优化