2025-09-30 05:18:31 +00:00
|
|
|
|
## ADC原理说明
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-09-13 09:22:00 +00:00
|
|
|
|
GD32F4系列搭载了高性能的12位逐次逼近型(SAR)ADC,提供了非常灵活和强大的数据采集功能。其采集方式可以从**操作模式**和**数据转移方式**两个维度来理解。
|
|
|
|
|
|
|
|
|
|
### 一、按操作模式划分
|
|
|
|
|
|
|
|
|
|
操作模式决定了ADC如何执行转换序列,主要配置在 `ADC_RSQ0`、`ADC_RSQ1`、`ADC_RSQ2`寄存器(规则序列寄存器)和 `ADC_OSQ`寄存器(注入序列寄存器)。
|
|
|
|
|
|
|
|
|
|
#### 1. 单次转换模式 (Single Conversion Mode)
|
|
|
|
|
|
|
|
|
|
* **工作原理**:ADC只执行一次转换(可以是一个通道,也可以是多个通道组成的序列),转换完成后自动停止,并置位转换结束标志位(EOC)。
|
|
|
|
|
* **触发方式**:
|
|
|
|
|
* **软件触发**:通过设置 `ADC_CTL1`的 `SWRCST`位启动。
|
|
|
|
|
* **硬件触发**:通过外部信号(如定时器TRGO、EXTI线)启动。
|
|
|
|
|
* **特点**:最简单,功耗最低(转换间隙ADC可自动进入低功耗模式),但需要不断重新触发才能进行下一次转换。适用于对采样率要求不高的场合。
|
|
|
|
|
* **代码逻辑**:`启动 -> 等待EOC -> 读取数据 -> (下次需要时再次启动)`
|
|
|
|
|
|
|
|
|
|
#### 2. 连续转换模式 (Continuous Conversion Mode)
|
|
|
|
|
|
|
|
|
|
* **工作原理**:ADC完成一次转换序列后,**立即自动重新启动**下一次转换,永不停止,连续不断地进行转换。
|
|
|
|
|
* **触发方式**:通常由**一次软件或硬件触发**来启动这个连续的进程。
|
2025-09-15 09:03:37 +00:00
|
|
|
|
* **特点**:一旦启动,无需干预即可获得连续的数据流,实时性高。但**功耗相对较高**,因为ADC一直处于工作状态。通常需要与DMA配合使用。
|
2025-09-13 09:22:00 +00:00
|
|
|
|
* **代码逻辑**:`启动 -> (自动循环转换) -> 不断读取数据`
|
|
|
|
|
|
|
|
|
|
#### 3. 扫描模式 (Scan Mode)
|
|
|
|
|
|
|
|
|
|
* **工作原理**:此模式**不是独立的**,它需要与单次或连续模式结合使用。当使能扫描模式后,ADC会按照预先在规则序列寄存器 `ADC_RSQi`或注入序列寄存器 `ADC_OSQ`中设置好的**通道顺序**,依次对多个通道进行转换。
|
|
|
|
|
* **特点**:实现了多通道自动轮流采样。**特别注意**:
|
|
|
|
|
* 在扫描模式下,每次完成**整个序列**的转换后,才会产生一个**EOC**(转换结束)中断标志。
|
|
|
|
|
* 如果需要每个通道转换完都产生中断,需要使能 `EOCIE`并配合DMA使用。
|
|
|
|
|
* **常见组合**:
|
|
|
|
|
* **单次扫描模式**:触发一次,按顺序转换所有通道一次,然后停止。
|
|
|
|
|
* **连续扫描模式**:触发一次,按顺序循环不停地转换所有通道。
|
|
|
|
|
|
|
|
|
|
#### 4. 间断模式 (Discontinuous Mode)
|
|
|
|
|
|
|
|
|
|
* **工作原理**:此模式用于将一个长的转换序列**分批次(短序列)** 完成。您需要设置短序列的长度 `DISNUM`(例如n=3)。每次由一个硬件触发信号触发时,ADC不会转换整个序列,而是只转换序列中的**接下来的n个通道**。再次触发,再转换接下来的n个通道,直到整个序列完成,然后循环。
|
|
|
|
|
* **特点**:提供了更精细的触发控制,允许用多个触发信号来控制一个长序列的转换。应用相对小众,常用于由定时器精确控制采样点的复杂场景。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 二、按数据转移方式划分
|
|
|
|
|
|
|
|
|
|
转换完成后的数据需要被CPU读取,根据读取方式的不同,也决定了系统的效率。
|
|
|
|
|
|
|
|
|
|
#### 1. 中断方式 (Interrupt)
|
|
|
|
|
|
|
|
|
|
* **工作原理**:使能ADC中断(如EOC中断),在转换完成后进入中断服务函数(ISR),在ISR中读取 `ADC_RDATA`寄存器。
|
|
|
|
|
* **适用场景**:
|
|
|
|
|
* **单通道单次转换**:最简单。
|
|
|
|
|
* **扫描模式**:如果只关心整个序列转换完成,可以在EOC中断中读取所有数据(但需要自己记录顺序)。
|
|
|
|
|
* **缺点**:频繁中断会消耗大量CPU资源,尤其在高速、多通道采样时效率低下。
|
|
|
|
|
|
|
|
|
|
#### 2. DMA方式 (Direct Memory Access)
|
|
|
|
|
|
|
|
|
|
* **工作原理**:这是**多通道扫描+连续转换模式的标准且高效的解决方案**。使能ADC的DMA请求,并配置好DMA控制器。每次ADC转换完成一个通道的数据后,会自动触发DMA,由DMA控制器**在不占用CPU的情况下**,将 `ADC_RDATA`寄存器的数据直接搬运到指定的内存数组(Buffer)中。
|
|
|
|
|
* **特点**:
|
|
|
|
|
* **极高效率**:CPU只需在数据数组满或半满时进行处理,大大解放了CPU。
|
|
|
|
|
* **数据对齐**:ADC数据寄存器是32位的,但数据只有12位。DMA可以轻松处理数据对齐问题(左对齐或右对齐)。
|
|
|
|
|
* **适用场景**:几乎所有需要高速、实时、多通道采样的应用,如音频处理、电机控制、数字电源、多路数据采集卡等。
|
|
|
|
|
|
|
|
|
|
#### 3. 查询方式 (Polling)
|
|
|
|
|
|
|
|
|
|
* **工作原理**:在主循环或函数中,不断**查询**ADC状态寄存器中的标志位(如EOC),一旦发现标志位置位,就去读取数据。
|
|
|
|
|
* **特点**:编程简单,但CPU利用率最低,因为在等待转换完成时CPU什么也做不了,一直在空循环。**不推荐在实际项目中使用**,仅用于简单测试。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 三、特殊模式:双ADC模式 (Dual ADC Mode)
|
|
|
|
|
|
|
|
|
|
GD32F4系列通常有多个ADC单元(如ADC0, ADC1, ADC2)。它们可以协同工作,组成更高级的采样模式,用于需要精确同步采样的场景。
|
|
|
|
|
|
|
|
|
|
* **同步注入模式**:一个主ADC被触发后,从ADC同时被触发进行注入组转换。
|
|
|
|
|
* **同步规则模式**:主从ADC同步进行规则组转换。
|
|
|
|
|
* **交替触发模式**:定时器触发后,主从ADC交替采样**同一个通道**,可以实现**2倍于单个ADC**的采样率。
|
|
|
|
|
* **交替模式**:主从ADC交替采样,每次触发交替转换。
|
|
|
|
|
* **混合模式**:规则组和注入组可以分别配置为不同的同步模式。
|
|
|
|
|
|
|
|
|
|
### 总结与对比
|
|
|
|
|
|
|
|
|
|
| 模式分类 | 模式名称 | 特点 | 适用场景 |
|
|
|
|
|
| :----------------- | :------------------ | :-------------------------------------------------- | :--------------------------------------------------- |
|
|
|
|
|
| **操作模式** | **单次转换** | 转换一次即停止,低功耗,需反复触发 | 低速、单点采样,电池供电设备 |
|
|
|
|
|
| | **连续转换** | 转换一次后自动开始下一次,连续不断 | 高速、实时数据流采集 |
|
|
|
|
|
| | **扫描模式** | 按预设顺序自动转换多个通道 | **多通道**数据采集(必须配合单次/连续模式) |
|
|
|
|
|
| | **间断模式** | 分多次触发完成一个长序列 | 由外部信号精细控制采样节奏的复杂应用 |
|
|
|
|
|
| **数据转移** | **查询方式** | CPU不断查询状态标志,效率最低 | 简单测试,不推荐用于实际项目 |
|
|
|
|
|
| | **中断方式** | 转换完成产生中断,CPU在ISR中读取数据 | 中低速、通道数较少的应用 |
|
|
|
|
|
| | **DMA方式** | **自动**将数据搬运到内存,**不占用CPU** | **高速、多通道、实时**采集的**首选方案** |
|
|
|
|
|
| **ADC组合** | **双ADC模式** | 多个ADC单元协同工作,同步或交替采样 | 需要高采样率或通道间严格同步的高精度应用 |
|
|
|
|
|
|
|
|
|
|
### 如何选择?
|
|
|
|
|
|
|
|
|
|
1. **单通道、低速采样**:单次转换 + 中断。
|
|
|
|
|
2. **多通道、低速采样**:单次扫描 + DMA(或中断,但DMA更优)。
|
|
|
|
|
3. **多通道、高速采样**:**连续扫描 + DMA** (这是最常用、最经典的配置)。
|
|
|
|
|
4. **极限采样率(单通道)**:使用双ADC的交替模式,配合DMA。
|
|
|
|
|
5. **需要同步采样两个相关信号**:使用双ADC的同步模式。
|
|
|
|
|
|
|
|
|
|
这是一个非常核心且优秀的问题!它触及了ADC模块设计思想的本质。
|
|
|
|
|
|
|
|
|
|
**规则组和注入组** 与 **操作模式** 和 **数据转移方式** 是不同维度的概念,但它们之间**存在着紧密的协作和配合关系**。您可以这样理解:
|
|
|
|
|
|
|
|
|
|
* **规则组 vs 注入组**:定义的是 **“要转换什么”**(What),即ADC转换任务的**内容**和**队列**。它们就像是两个不同的**任务列表**。
|
|
|
|
|
* **操作模式**:定义的是 **“如何执行转换”**(How),即如何对待上述任务列表(是执行一次还是循环执行,是软件启动还是硬件启动)。它定义了任务的**执行策略**。
|
|
|
|
|
* **数据转移方式**:定义的是 **“转换完成后如何处理数据”**(What to do with the result),即如何获取转换结果。它定义了任务结果的**收集方式**。
|
|
|
|
|
|
|
|
|
|
它们之间的关系可以用下面的图表来清晰地展示:
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
flowchart TD
|
|
|
|
|
subgraph A[任务内容(What)]
|
|
|
|
|
direction LR
|
|
|
|
|
A1[规则组<br>常规任务队列]
|
|
|
|
|
A2[注入组<br>高优先级任务队列]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
subgraph B[执行策略(How)]
|
|
|
|
|
B1[操作模式<br>单次/连续/扫描/间断]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
subgraph C[结果收集(What to do)]
|
|
|
|
|
direction LR
|
|
|
|
|
C1[数据转移方式<br>查询/中断/DMA]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
D[原始模拟信号] --> A
|
|
|
|
|
A -- 任务列表 --> B
|
|
|
|
|
B -- 执行转换 --> C
|
|
|
|
|
C -- 获取结果 --> E[数字转换结果]
|
|
|
|
|
|
|
|
|
|
B -.->|执行策略同时<br>应用于两个组| A1
|
|
|
|
|
B -.->|执行策略同时<br>应用于两个组| A2
|
|
|
|
|
|
|
|
|
|
C1 -->|读取规则组<br>需及时处理| A1
|
|
|
|
|
C1 -->|读取注入组<br>有专用寄存器| A2
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
下面我们进行详细的解读。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 1. 规则组/注入组 与 操作模式 的关系
|
|
|
|
|
|
|
|
|
|
操作模式(单次、连续、扫描)**同时适用于规则组和注入组**,但两者的行为有一些关键区别。
|
|
|
|
|
|
|
|
|
|
| 特性 | 规则组 (Routine Group) | 注入组 (Injected Group) |
|
|
|
|
|
| :--------------------- | :--------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
|
|
|
| **扫描模式** | **必须启用**才能转换多通道序列。 | 注入组**本身就是一个短序列**,其通道数由 `IL`(Injected Length) 决定,**无需**单独的“扫描模式”使能。 |
|
|
|
|
|
| **单次 vs 连续** | 决定了规则序列是执行一次还是循环执行。 | 决定了注入序列是执行一次还是循环执行。**注意**:一个注入触发信号通常只执行一次注入序列,除非配置为连续模式。 |
|
|
|
|
|
| **触发源** | 可以使用软件触发或硬件触发(如定时器)。 | 同样可以使用软件触发或**独立的**硬件触发源。**关键**:注入组的硬件触发可以**中断**当前正在进行的规则组转换,立即执行注入序列,完成后自动恢复规则组转换。这就是“注入”(Injected)的含义——高优先级任务插入。 |
|
|
|
|
|
|
|
|
|
|
**关系小结**:操作模式定义了各组转换的**执行流程**。规则组是“常规任务流程”,而注入组是可打断常规流程的“高优先级中断任务流程”。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 2. 规则组/注入组 与 数据转移方式 的关系
|
|
|
|
|
|
|
|
|
|
这是关系最紧密的部分,**数据转移方式的选择直接受到所用组别的严重影响**。
|
|
|
|
|
|
|
|
|
|
| 特性 | 规则组 (Routine Group) | 注入组 (Injected Group) |
|
|
|
|
|
| :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
|
|
|
| **数据寄存器** | 只有**一个**数据寄存器 `ADC_RDATA`。所有规则通道的转换结果都放在这里。**如果不及时读取,就会被下一个通道的结果覆盖**。 | 有**多个**独立的数据寄存器(如 `ADC_IDATA0`, `ADC_IDATA1`, `ADC_IDATA2`, `ADC_IDATA3`)。每个注入通道都有自己专用的寄存器,结果不会被覆盖。 |
|
|
|
|
|
| **数据转移方式** | **强烈依赖DMA**。因为在扫描模式下,多个通道快速连续转换,CPU很难及时读取单个寄存器而不丢失数据。DMA可以自动将每个通道的结果搬运到指定数组。 | **非常适合使用中断**。因为注入组通道数少,且每个结果都有独立的寄存器,不会丢失。可以在注入转换完成中断(JEOC)中安全地读取所有 `ADC_IDATAx` 寄存器。 |
|
|
|
|
|
| **标志位** | 转换结束标志 `EOC` 在**每个通道**转换完成后都置位。序列结束标志 `EOS` 在**整个规则序列**转换完成后置位。 | 注入组转换结束标志 `JEOC` 在**整个注入序列**转换完成后置位。 |
|
|
|
|
|
|
|
|
|
|
**关系小结**:
|
|
|
|
|
|
|
|
|
|
* **规则组 + 多通道 + 扫描模式 => 几乎必须使用DMA**来高效可靠地搬运数据。
|
|
|
|
|
* **注入组 + 少数通道 => 使用查询或中断**即可安全地读取数据,因为结果有专属“座位”(寄存器),不会丢。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### 实际应用场景举例(结合三者)
|
|
|
|
|
|
|
|
|
|
**场景:云台系统监控**
|
|
|
|
|
|
|
|
|
|
* **规则组**(常规任务):用于**周期性采集**电机编码器位置、系统电压、系统电流。配置为**连续扫描模式 + DMA**。ADC在后台持续采样,DMA自动将三个通道的数据循环写入内存数组,主循环只需读取数组即可,极其高效。
|
|
|
|
|
* **注入组**(紧急任务):用于**过流保护**。配置一个电流通道,设置为**单次转换模式 + 中断**,并由一个比较器的硬件输出信号作为触发源。当电流突然超过阈值,比较器触发信号立即产生,ADC**中断**正在进行的规则组转换,**立即**执行注入转换采集电流,并在转换完成后进入中断服务程序。在中断中,程序可以立即读取 `ADC_IDATA0` 得到电流值,并紧急停止电机。
|
|
|
|
|
|
|
|
|
|
在这个例子中,您可以看到:
|
|
|
|
|
|
|
|
|
|
* **What** (规则组/注入组):定义了监控和保护两个任务。
|
|
|
|
|
* **How** (连续扫描/单次):定义了任务的执行节奏。
|
|
|
|
|
* **What to do** (DMA/中断):定义了结果数据的处理方式。
|
|
|
|
|
|
|
|
|
|
三者协同工作,共同构成了一个高效、可靠且响应及时的数据采集系统。
|
2025-09-13 10:15:31 +00:00
|
|
|
|
|
2025-09-30 05:18:31 +00:00
|
|
|
|
## `adc_routine_channel_config`函数说明
|
|
|
|
|
|
2025-09-13 10:15:31 +00:00
|
|
|
|
在GD32微控制器的ADC驱动库中,`adc_routine_channel_config`函数用于配置规则组(常规序列)的通道序列。
|
|
|
|
|
|
|
|
|
|
### 🧾 函数原型
|
|
|
|
|
|
|
|
|
|
在GD32的库函数中,该函数的原型通常类似于:
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
void adc_routine_channel_config(uint32_t adc_periph, uint8_t rank, uint8_t channel, uint32_t sample_time);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 📊 参数详解
|
|
|
|
|
|
|
|
|
|
为了更直观地理解第二和第三个参数的区别与联系,请看下表:
|
|
|
|
|
|
|
|
|
|
| 特性 | 第二个参数 (`rank`) | 第三个参数 (`channel`) |
|
|
|
|
|
| :------------------- | :------------------------------------------------------------------------------ | :-------------------------------------------------------------------------------------------- |
|
|
|
|
|
| **参数含义** | 指定**转换顺序中的序号**(即该通道在规则组序列中的**位置**) | 指定**具体的ADC物理通道**(即连接模拟信号的**输入源**) |
|
|
|
|
|
| **参数目的** | 决定**多个通道的转换先后顺序** | 决定**转换哪个引脚或内部信号源** |
|
|
|
|
|
| **取值范围** | 通常从 `0`开始,最大取决于规则组通道总数(例如,16个通道则是 `0`到 `15`) | 取决于MCU型号,例如 `ADC_CHANNEL_0`, `ADC_CHANNEL_1`, ..., `ADC_CHANNEL_17`(内部通道) |
|
|
|
|
|
| **配置寄存器** | `ADC_RSQ2`, `ADC_RSQ1`, `ADC_RSQ0` (规则序列寄存器) | 与 `rank`共同配置规则序列寄存器 |
|
|
|
|
|
| **示例说明** | `rank = 0`表示该通道是序列中**第一个**被转换的 | `channel = ADC_CHANNEL_5`表示选择MCU的**特定ADC引脚**(如PA5) |
|
|
|
|
|
|
|
|
|
|
### ⚠️ 注意事项
|
|
|
|
|
|
|
|
|
|
1. **`rank`值与实际转换顺序**:`rank`参数通常从 `0`开始递增,表示转换的先后顺序。**`rank`值越小,转换顺序越靠前**。例如,`rank = 0`的通道最先转换,`rank = 1`的通道其次,以此类推。
|
|
|
|
|
2. **通道总数设置**:在配置所有通道的 `rank`之前,务必先通过 `adc_channel_length_config(adc_periph, ADC_ROUTINE_CHANNEL, n)`函数正确设置规则组的总通道数 `n`。
|
|
|
|
|
3. **避免重复或越界**:确保不同的 `rank`值指向不同的序列位置,并且所有 `rank`值都小于总通道数 `n`。同时,确保选择的物理 `channel`在MCU实际存在的范围内。
|
|
|
|
|
4. **采样时间**:此函数的第四个参数 `sample_time`(采样时间)同样重要,它决定了ADC对输入信号采样的持续时间,需根据信号源阻抗进行调整。
|
|
|
|
|
|
|
|
|
|
### 💡 总结
|
|
|
|
|
|
2025-09-15 09:03:37 +00:00
|
|
|
|
可以这样理解:
|
2025-09-13 10:15:31 +00:00
|
|
|
|
|
|
|
|
|
* **`rank`(第二个参数)是“排队号”**:决定通道转换的**顺序**。
|
|
|
|
|
* **`channel`(第三个参数)是“身份证”**:确定转换的**具体是哪个物理通道**。
|
|
|
|
|
|
|
|
|
|
函数的作用就是将特定的物理通道(`channel`)安排到规则组转换序列中的指定位置(`rank`)上。
|
2025-09-29 09:41:58 +00:00
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2025-09-30 05:18:31 +00:00
|
|
|
|
## ADC程序模式说明
|
2025-09-29 09:41:58 +00:00
|
|
|
|
|
|
|
|
|
这几种ADC模式是STM32中常见的配置组合,主要区别在于**转换组别、转换方式、数据采集方式**等方面。让我详细解释每种模式:
|
|
|
|
|
|
2025-09-30 05:18:31 +00:00
|
|
|
|
### ADC_MODE_0 - 基础单次转换模式
|
2025-09-29 09:41:58 +00:00
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
// 规则组、单次转换、非扫描
|
|
|
|
|
#define CONTINUOUS_STATUS DISABLE // 单次转换
|
|
|
|
|
#define SEQUENCE_CHANNEL ADC_ROUTINE_CHANNEL // 规则组
|
|
|
|
|
#define SCAN_STATUS DISABLE // 非扫描
|
|
|
|
|
#define CHANNEL_LENGTH 1 // 单通道
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**特点:**
|
|
|
|
|
|
|
|
|
|
- **单次转换**:每次触发只转换一次
|
|
|
|
|
- **规则组**:常规转换通道组
|
|
|
|
|
- **非扫描**:只转换一个通道
|
|
|
|
|
- **应用场景**:简单的单通道ADC读取,如电位器、温度传感器
|
|
|
|
|
|
|
|
|
|
**工作流程:**
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
触发 → 转换通道1 → 停止 → 等待下次触发
|
|
|
|
|
```
|
|
|
|
|
|
2025-09-30 05:18:31 +00:00
|
|
|
|
### ADC_MODE_1 - 注入组扫描模式
|
2025-09-29 09:41:58 +00:00
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
// 注入组、单次转换、扫描、转换结束标志位采集
|
|
|
|
|
#define CONTINUOUS_STATUS DISABLE // 单次转换
|
|
|
|
|
#define SEQUENCE_CHANNEL ADC_INSERTED_CHANNEL // 注入组
|
|
|
|
|
#define SCAN_STATUS ENABLE // 扫描模式
|
|
|
|
|
#define CHANNEL_LENGTH 2 // 多通道
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**特点:**
|
|
|
|
|
|
|
|
|
|
- **注入组**:高优先级,可打断规则组转换
|
|
|
|
|
- **扫描模式**:自动按顺序转换多个通道
|
|
|
|
|
- **查询方式**:通过轮询标志位获取数据
|
|
|
|
|
- **应用场景**:需要打断常规转换的紧急测量
|
|
|
|
|
|
|
|
|
|
**工作流程:**
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
触发 → 转换通道1 → 转换通道2 → 设置EOC标志 → 读取数据
|
|
|
|
|
```
|
|
|
|
|
|
2025-09-30 05:18:31 +00:00
|
|
|
|
### ADC_MODE 2 - 中断方式注入组扫描
|
2025-09-29 09:41:58 +00:00
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
// 注入组、单次转换、扫描、中断转换结束标志位采集
|
|
|
|
|
#define CONTINUOUS_STATUS DISABLE
|
|
|
|
|
#define SEQUENCE_CHANNEL ADC_INSERTED_CHANNEL // 注入组
|
|
|
|
|
#define SCAN_STATUS ENABLE // 扫描模式
|
|
|
|
|
#define CHANNEL_LENGTH 2 // 多通道
|
|
|
|
|
#define ADCX_IRQn ADC_IRQn // 启用中断
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**特点:**
|
|
|
|
|
|
|
|
|
|
- **中断方式**:转换完成后产生中断
|
|
|
|
|
- **实时性更好**:不需要轮询等待
|
|
|
|
|
- **应用场景**:对实时性要求高的多通道测量
|
|
|
|
|
|
|
|
|
|
**工作流程:**
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
触发 → 转换通道1 → 转换通道2 → 产生中断 → 在ISR中读取数据
|
|
|
|
|
```
|
|
|
|
|
|
2025-09-30 05:18:31 +00:00
|
|
|
|
### ADC_MODE 3 - DMA连续采集模式
|
2025-09-29 09:41:58 +00:00
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
// 规则组、连续转换、扫描、DMA采集
|
|
|
|
|
#define CONTINUOUS_STATUS ENABLE // 连续转换
|
|
|
|
|
#define SEQUENCE_CHANNEL ADC_ROUTINE_CHANNEL // 规则组
|
|
|
|
|
#define SCAN_STATUS ENABLE // 扫描模式
|
|
|
|
|
#define CHANNEL_LENGTH 2 // 多通道
|
|
|
|
|
#define DMAX DMA1 // 使用DMA
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**特点:**
|
|
|
|
|
|
|
|
|
|
- **连续转换**:自动重复转换序列
|
|
|
|
|
- **DMA传输**:自动将数据搬运到内存
|
|
|
|
|
- **高效率**:不占用CPU资源
|
|
|
|
|
- **应用场景**:高速数据采集、波形采样、实时监控
|
|
|
|
|
|
|
|
|
|
**工作流程:**
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
启动 → [转换通道1 → 转换通道2] → DMA传输 → [转换通道1 → 转换通道2] → ...
|
|
|
|
|
↑_____________________________循环___________________________↑
|
|
|
|
|
```
|
|
|
|
|
|
2025-09-30 05:18:31 +00:00
|
|
|
|
### 关键概念对比
|
2025-09-29 09:41:58 +00:00
|
|
|
|
|
2025-09-30 05:18:31 +00:00
|
|
|
|
#### 1. 规则组 vs 注入组
|
2025-09-29 09:41:58 +00:00
|
|
|
|
|
|
|
|
|
| 特性 | 规则组 | 注入组 |
|
|
|
|
|
| ------ | -------- | ------------------ |
|
|
|
|
|
| 优先级 | 正常 | 高(可打断规则组) |
|
|
|
|
|
| 通道数 | 最多16个 | 最多4个 |
|
|
|
|
|
| 应用 | 常规测量 | 紧急或同步测量 |
|
|
|
|
|
|
2025-09-30 05:18:31 +00:00
|
|
|
|
#### 2. 单次 vs 连续转换
|
2025-09-29 09:41:58 +00:00
|
|
|
|
|
|
|
|
|
| 特性 | 单次转换 | 连续转换 |
|
|
|
|
|
| -------- | ---------------- | ------------ |
|
|
|
|
|
| 工作方式 | 触发一次转换一次 | 自动重复转换 |
|
|
|
|
|
| CPU占用 | 低 | 需要管理数据 |
|
|
|
|
|
| 适用场景 | 低速采样 | 高速连续采样 |
|
|
|
|
|
|
2025-09-30 05:18:31 +00:00
|
|
|
|
#### 3. 数据获取方式对比
|
2025-09-29 09:41:58 +00:00
|
|
|
|
|
|
|
|
|
| 方式 | 查询标志位 | 中断方式 | DMA方式 |
|
|
|
|
|
| ------- | ---------------- | ------------------- | -------- |
|
|
|
|
|
| CPU占用 | 中等(需要轮询) | 低(仅在ISR中处理) | 几乎为零 |
|
|
|
|
|
| 实时性 | 一般 | 好 | 最好 |
|
|
|
|
|
| 复杂度 | 简单 | 中等 | 复杂 |
|
|
|
|
|
|
2025-09-30 05:18:31 +00:00
|
|
|
|
### 实际应用建议
|
2025-09-29 09:41:58 +00:00
|
|
|
|
|
2025-09-30 05:18:31 +00:00
|
|
|
|
#### 选择指南:
|
2025-09-29 09:41:58 +00:00
|
|
|
|
|
|
|
|
|
- **简单单通道读取** → MODE_0
|
|
|
|
|
- **紧急多通道测量** → MODE_1或MODE_2
|
|
|
|
|
- **高速连续采集** → MODE_3
|
|
|
|
|
- **需要实时响应** → MODE_2(中断)
|
|
|
|
|
- **需要低CPU占用** → MODE_3(DMA)
|
|
|
|
|
|
2025-09-30 05:18:31 +00:00
|
|
|
|
#### 性能考虑:
|
2025-09-29 09:41:58 +00:00
|
|
|
|
|
|
|
|
|
- DMA模式适合采样率>10Ksps的场景
|
|
|
|
|
- 中断模式适合1-10Ksps的中等速率
|
|
|
|
|
- 查询模式适合<1Ksps的低速应用
|
|
|
|
|
|
|
|
|
|
这些模式覆盖了从简单到复杂的各种ADC应用场景,可以根据具体需求灵活选择。
|
2025-09-30 05:18:31 +00:00
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
| 事件 | 断电保护 | 电压过高保护 | 过流保护 | 一般温度(10℃以下)故障 | 极限温度(10℃以上)故障 | 光电开关遮挡 |
|
|
|
|
|
| :--: | :----------: | :----------: | :------: | :----------------------: | :----------------------: | -------------------- |
|
|
|
|
|
| 响应 | 检测掉电存储 | 断电 | 电机停转 | -(仅故障回传) | 电机停转 | 同时累计遮挡电机停转 |
|
|
|
|
|
| | | | | | | |
|
|
|
|
|
| | | | | | | |
|
|
|
|
|
|
|
|
|
|
# 高精度转台/云台嵌入式软件故障上报与响应规范
|
|
|
|
|
|
|
|
|
|
## 概述
|
|
|
|
|
|
|
|
|
|
此文档定义了高精度转台(云台)嵌入式软件中的故障上报与响应机制。涵盖的主要故障类型包括电源异常(过电压、过流)、温度异常、光电挡板(限位传感器)异常、掉电保护等。
|
|
|
|
|
|
|
|
|
|
### 大概故障分类
|
|
|
|
|
|
|
|
|
|
按紧急程度分为P0(致命)、P1(高)、P2(中)、P3(低)四类故障。
|
|
|
|
|
|
|
|
|
|
| 故障类型 | 定义 | 响应 |
|
|
|
|
|
| ------------- | ------------------------------------ | -------------------------------------- |
|
|
|
|
|
| P0 致命 | 严重电流过载、电压过高、温度过高 | 立即停机、断电、报警,并持久化故障状态 |
|
|
|
|
|
| P1 高 | 光电挡板遮挡、电流持续过流、电压过低 | 停机、限流、恢复模式,报警上报 |
|
|
|
|
|
| P2 中 | 温度接近限制、传感器异常 | 限速、报警上报 |
|
|
|
|
|
| P3 低(可不用) | 通信错误、较小的传感器波动 | 记录日志,便于后续诊断 |
|
|
|
|
|
|
|
|
|
|
## 关键设计原则
|
|
|
|
|
|
|
|
|
|
- **快速检测,安全响应**:利用硬件中断和软件冗余检测保障故障发生时的最短响应时间。
|
|
|
|
|
- **可恢复优先,不能恢复则安全停机**:在无法恢复的情况下紧急停机并持久化关键故障信息。
|
|
|
|
|
- **掉电保护**:确保在掉电时能够正确保存系统状态,以便恢复。
|
|
|
|
|
|
|
|
|
|
## 主要模块
|
|
|
|
|
|
|
|
|
|
### 电压监测
|
|
|
|
|
|
|
|
|
|
- **硬件设计**:利用ADC模块(或者电压比较器)监测主电源电压。
|
|
|
|
|
- **故障响应**:过电压和欠电压将触发报警,并在满足条件时进行电机断电、停机。
|
|
|
|
|
|
|
|
|
|
### 电流监测
|
|
|
|
|
|
|
|
|
|
- **硬件设计**:使用霍尔传感器或分流电阻监测电机电流。
|
|
|
|
|
- **故障响应**:持续过流时,电机停止工作,并切断PWM驱动或者发送停转电机指令。
|
|
|
|
|
|
|
|
|
|
### 温度监测
|
|
|
|
|
|
|
|
|
|
- **硬件设计**:通过温度传感器(如NTC热敏电阻或者TMP75)进行监测。
|
|
|
|
|
- **故障响应**:超过设定温度阈值时,限制负载和转速,或停机保护。
|
|
|
|
|
|
|
|
|
|
### 光电挡板(限位)监测
|
|
|
|
|
|
|
|
|
|
- **硬件设计**:使用光电传感器或光耦监测挡板状态。
|
|
|
|
|
- **故障响应**:检测到遮挡时,立即停机,避免碰撞。
|
|
|
|
|
|
|
|
|
|
### 掉电保护
|
|
|
|
|
|
|
|
|
|
- **硬件设计**:通过监测电源电压下降,并使用电容保证在掉电瞬间写入系统状态。
|
|
|
|
|
- **故障响应**:在掉电事件前保存关键状态数据。
|
|
|
|
|
|
|
|
|
|
## 故障上报
|
|
|
|
|
|
|
|
|
|
错误代码使用统一格式进行上报,确保与上位机的兼容性。
|
|
|
|
|
|
|
|
|
|
| 错误码 | 错误描述 | 优先级 | 模块 |
|
|
|
|
|
| ---------- | -------------------- | ------ | ---------- |
|
|
|
|
|
| 0x01010001 | 主电源过压 | P1 | 电源 |
|
|
|
|
|
| 0x01010002 | 主电源欠压 | P1 | 电源 |
|
|
|
|
|
| 0x02020001 | 电机A持续过流 | P0 | 电流 |
|
|
|
|
|
| 0x02020002 | 电机B短路 | P0 | 电流 |
|
|
|
|
|
| 0x03030001 | 驱动模块过温 | P1 | 温度 |
|
|
|
|
|
| 0x04040001 | 光电挡板左侧遮挡异常 | P1 | 限位传感器 |
|
|
|
|
|
| 0x04040002 | 光电挡板右侧开路 | P2 | 限位传感器 |
|
|
|
|
|
| 0x05050001 | 编码器错位 | P2 | 传感器 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 测试与验收
|
|
|
|
|
|
|
|
|
|
### 单元测试
|
|
|
|
|
|
|
|
|
|
* 电压检测:模拟电压过高/过低,验证响应动作。
|
|
|
|
|
* 电流检测:模拟过流,验证驱动停止和故障上报。
|
|
|
|
|
* 温度检测:模拟温度过高,验证系统限速和停机保护。
|
|
|
|
|
|
|
|
|
|
### 集成测试
|
|
|
|
|
|
|
|
|
|
* 多故障并发:模拟电流过载和电压不稳,检查故障优先级和响应动作。
|
|
|
|
|
* 长时间压力测试:测试系统长时间稳定运行,模拟逐渐升温。
|
|
|
|
|
|
|
|
|
|
### 验收标准
|
|
|
|
|
|
|
|
|
|
* 掉电保护成功率:99.9%(断电前成功写入状态)
|
|
|
|
|
* 电流/电压/温度监测反应时间:≤5ms
|
|
|
|
|
* 故障上报与记录符合协议,信息完整且准确。
|
|
|
|
|
|
|
|
|
|
**示例上报报文格式** :
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"error_code": "0x01020005",
|
|
|
|
|
"severity": "P1",
|
|
|
|
|
"timestamp": "2025-09-30T11:32:14Z",
|
|
|
|
|
"voltage_v": 28.3,
|
|
|
|
|
"current_a": 1.3,
|
|
|
|
|
"temp_c": 52.4,
|
|
|
|
|
"encoder_deg": 12.345,
|
|
|
|
|
"message": "motor B continuous overcurrent",
|
|
|
|
|
//"firmware": "v1.2.3",
|
|
|
|
|
"cmd_id": "PT-001"
|
|
|
|
|
"mac": "PT-001"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## C示例代码
|
|
|
|
|
|
|
|
|
|
```c
|
|
|
|
|
// 电流监测中断处理示例
|
|
|
|
|
void OVERCURRENT_IRQHandler(void) {
|
|
|
|
|
// 立即切断驱动使能
|
|
|
|
|
Motor_DisableDriver(MOTOR_B);
|
|
|
|
|
|
|
|
|
|
// 读取电流并记录
|
|
|
|
|
float current = adc_read(CURRENT_B);
|
|
|
|
|
log_error(ERROR_CODE_OVERCURRENT(MOTOR_B), "Overcurrent detected", current);
|
|
|
|
|
|
|
|
|
|
// 上报错误至上位机
|
|
|
|
|
ReportErrorToHost(ERROR_CODE_OVERCURRENT(MOTOR_B));
|
|
|
|
|
|
|
|
|
|
// 进入等待人工复位模式
|
|
|
|
|
EnterSafeLoop();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 掉电ISR 保存最小状态
|
|
|
|
|
volatile bool power_failing = false;
|
|
|
|
|
|
|
|
|
|
void POWER_FALL_IRQHandler(void) {
|
|
|
|
|
if (power_failing) return;
|
|
|
|
|
power_failing = true;
|
|
|
|
|
|
|
|
|
|
// 禁止新动作,立即切断PWM
|
|
|
|
|
Motor_StopAllPWMImmediate();
|
|
|
|
|
|
|
|
|
|
// 采集快照
|
|
|
|
|
Snapshot_t snap;
|
|
|
|
|
snap.magic = SNAP_MAGIC;
|
|
|
|
|
snap.timestamp = rtc_get_time();
|
|
|
|
|
snap.voltage = adc_read(VOLTAGE_CHANNEL);
|
|
|
|
|
snap.current = adc_read(CURRENT_CHANNEL);
|
|
|
|
|
snap.temp = adc_read(TEMP_CHANNEL);
|
|
|
|
|
snap.encoder_pos = encoder_get_position();
|
|
|
|
|
snap.error_flags = global_error_flags;
|
|
|
|
|
|
|
|
|
|
// 计算CRC并保存
|
|
|
|
|
snap.crc = crc32((uint8_t*)&snap, sizeof(snap) - sizeof(snap.crc));
|
|
|
|
|
FRAM_Write(SNAPSHOT_ADDR, (uint8_t*)&snap, sizeof(snap));
|
|
|
|
|
|
|
|
|
|
// 启动刹车机制
|
|
|
|
|
Hardware_EnableBrake();
|
|
|
|
|
|
|
|
|
|
// 进入安全循环
|
|
|
|
|
EnterSafeLoop();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
```
|