|
||
---|---|---|
.. | ||
mb85rc64 | ||
tmp75 | ||
deepseek_mermaid_20250915_c716d2.png | ||
delay_us.c | ||
delay_us.h | ||
drv_adc.c | ||
drv_adc.h | ||
drv_usart.c | ||
drv_usart.h | ||
readme.md |
readme.md
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完成一次转换序列后,立即自动重新启动下一次转换,永不停止,连续不断地进行转换。
- 触发方式:通常由一次软件或硬件触发来启动这个连续的进程。
- 特点:一旦启动,无需干预即可获得连续的数据流,实时性高。但功耗相对较高,因为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单元协同工作,同步或交替采样 | 需要高采样率或通道间严格同步的高精度应用 |
如何选择?
- 单通道、低速采样:单次转换 + 中断。
- 多通道、低速采样:单次扫描 + DMA(或中断,但DMA更优)。
- 多通道、高速采样:连续扫描 + DMA (这是最常用、最经典的配置)。
- 极限采样率(单通道):使用双ADC的交替模式,配合DMA。
- 需要同步采样两个相关信号:使用双ADC的同步模式。
这是一个非常核心且优秀的问题!它触及了ADC模块设计思想的本质。
规则组和注入组 与 操作模式 和 数据转移方式 是不同维度的概念,但它们之间存在着紧密的协作和配合关系。您可以这样理解:
- 规则组 vs 注入组:定义的是 “要转换什么”(What),即ADC转换任务的内容和队列。它们就像是两个不同的任务列表。
- 操作模式:定义的是 “如何执行转换”(How),即如何对待上述任务列表(是执行一次还是循环执行,是软件启动还是硬件启动)。它定义了任务的执行策略。
- 数据转移方式:定义的是 “转换完成后如何处理数据”(What to do with the result),即如何获取转换结果。它定义了任务结果的收集方式。
它们之间的关系可以用下面的图表来清晰地展示:
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的库函数中,该函数的原型通常类似于:
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) |
⚠️ 注意事项
rank
值与实际转换顺序:rank
参数通常从0
开始递增,表示转换的先后顺序。rank
值越小,转换顺序越靠前。例如,rank = 0
的通道最先转换,rank = 1
的通道其次,以此类推。- 通道总数设置:在配置所有通道的
rank
之前,务必先通过adc_channel_length_config(adc_periph, ADC_ROUTINE_CHANNEL, n)
函数正确设置规则组的总通道数n
。 - 避免重复或越界:确保不同的
rank
值指向不同的序列位置,并且所有rank
值都小于总通道数n
。同时,确保选择的物理channel
在MCU实际存在的范围内。 - 采样时间:此函数的第四个参数
sample_time
(采样时间)同样重要,它决定了ADC对输入信号采样的持续时间,需根据信号源阻抗进行调整。
💡 总结
可以这样理解:
rank
(第二个参数)是“排队号”:决定通道转换的顺序。channel
(第三个参数)是“身份证”:确定转换的具体是哪个物理通道。
函数的作用就是将特定的物理通道(channel
)安排到规则组转换序列中的指定位置(rank
)上。