newPtz/drivers/readme.md

227 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

GD32F4系列搭载了高性能的12位逐次逼近型SARADC提供了非常灵活和强大的数据采集功能。其采集方式可以从**操作模式**和**数据转移方式**两个维度来理解。
### 一、按操作模式划分
操作模式决定了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完成一次转换序列后**立即自动重新启动**下一次转换,永不停止,连续不断地进行转换。
* **触发方式**:通常由**一次软件或硬件触发**来启动这个连续的进程。
* **特点**一旦启动无需干预即可获得连续的数据流实时性高。但功耗相对较高因为ADC一直处于工作状态。通常需要与DMA配合使用。
* **代码逻辑**`启动 -> (自动循环转换) -> 不断读取数据`
#### 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/中断):定义了结果数据的处理方式。
三者协同工作,共同构成了一个高效、可靠且响应及时的数据采集系统。
在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对输入信号采样的持续时间需根据信号源阻抗进行调整。
### 💡 总结
你可以这样理解:
* **`rank`(第二个参数)是“排队号”**:决定通道转换的**顺序**。
* **`channel`(第三个参数)是“身份证”**:确定转换的**具体是哪个物理通道**。
函数的作用就是将特定的物理通道(`channel`)安排到规则组转换序列中的指定位置(`rank`)上。
希望这些信息能帮助你更好地理解和使用GD32的ADC功能