newPtz/drivers
DESKTOP-2E6P1Q6\Administrator 6d3f46b8cd 串口 2025-09-30 18:06:38 +08:00
..
beep 硬件i2c完成 2025-09-26 18:17:39 +08:00
mb85rc64 mb85rc64硬件I2C改写完成 2025-09-29 17:41:58 +08:00
tmp75 硬件i2c完成 2025-09-26 18:17:39 +08:00
deepseek_mermaid_20250915_c716d2.png adc修改:单通道、单词转换、扫描模式、规则组 2025-09-15 17:03:37 +08:00
delay.c mb85rc64硬件I2C改写完成 2025-09-29 17:41:58 +08:00
delay.h 硬件i2c完成 2025-09-26 18:17:39 +08:00
drv_adc.c mb85rc64硬件I2C改写完成 2025-09-29 17:41:58 +08:00
drv_adc.h mb85rc64硬件I2C改写完成 2025-09-29 17:41:58 +08:00
drv_i2c.c mb85rc64硬件I2C改写完成 2025-09-29 17:41:58 +08:00
drv_i2c.h 串口 2025-09-30 18:06:38 +08:00
drv_usart.c 串口 2025-09-30 18:06:38 +08:00
drv_usart.h 串口 2025-09-30 18:06:38 +08:00
readme.md 添加原理图; 2025-09-30 13:18:31 +08:00

readme.md

ADC原理说明

GD32F4系列搭载了高性能的12位逐次逼近型SARADC提供了非常灵活和强大的数据采集功能。其采集方式可以从操作模式数据转移方式两个维度来理解。

一、按操作模式划分

操作模式决定了ADC如何执行转换序列主要配置在 ADC_RSQ0ADC_RSQ1ADC_RSQ2寄存器(规则序列寄存器)和 ADC_OSQ寄存器(注入序列寄存器)。

1. 单次转换模式 (Single Conversion Mode)

  • 工作原理ADC只执行一次转换可以是一个通道也可以是多个通道组成的序列转换完成后自动停止并置位转换结束标志位EOC
  • 触发方式
    • 软件触发:通过设置 ADC_CTL1SWRCST位启动。
    • 硬件触发通过外部信号如定时器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即如何获取转换结果。它定义了任务结果的收集方式

它们之间的关系可以用下面的图表来清晰地展示:

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/中断):定义了结果数据的处理方式。

三者协同工作,共同构成了一个高效、可靠且响应及时的数据采集系统。

adc_routine_channel_config函数说明

在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个通道则是 015 取决于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)上。


ADC程序模式说明

这几种ADC模式是STM32中常见的配置组合主要区别在于转换组别、转换方式、数据采集方式等方面。让我详细解释每种模式:

ADC_MODE_0 - 基础单次转换模式

// 规则组、单次转换、非扫描
#define CONTINUOUS_STATUS		DISABLE		// 单次转换
#define SEQUENCE_CHANNEL		ADC_ROUTINE_CHANNEL	// 规则组
#define SCAN_STATUS				DISABLE		// 非扫描
#define CHANNEL_LENGTH			1			// 单通道

特点:

  • 单次转换:每次触发只转换一次
  • 规则组:常规转换通道组
  • 非扫描:只转换一个通道
  • 应用场景简单的单通道ADC读取如电位器、温度传感器

工作流程:

触发 → 转换通道1 → 停止 → 等待下次触发

ADC_MODE_1 - 注入组扫描模式

// 注入组、单次转换、扫描、转换结束标志位采集
#define CONTINUOUS_STATUS		DISABLE		// 单次转换
#define SEQUENCE_CHANNEL		ADC_INSERTED_CHANNEL	// 注入组
#define SCAN_STATUS				ENABLE		// 扫描模式
#define CHANNEL_LENGTH			2			// 多通道

特点:

  • 注入组:高优先级,可打断规则组转换
  • 扫描模式:自动按顺序转换多个通道
  • 查询方式:通过轮询标志位获取数据
  • 应用场景:需要打断常规转换的紧急测量

工作流程:

触发 → 转换通道1 → 转换通道2 → 设置EOC标志 → 读取数据

ADC_MODE 2 - 中断方式注入组扫描

// 注入组、单次转换、扫描、中断转换结束标志位采集
#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中读取数据

ADC_MODE 3 - DMA连续采集模式

// 规则组、连续转换、扫描、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] → ...
        ↑_____________________________循环___________________________↑

关键概念对比

1. 规则组 vs 注入组

特性 规则组 注入组
优先级 正常 高(可打断规则组)
通道数 最多16个 最多4个
应用 常规测量 紧急或同步测量

2. 单次 vs 连续转换

特性 单次转换 连续转换
工作方式 触发一次转换一次 自动重复转换
CPU占用 需要管理数据
适用场景 低速采样 高速连续采样

3. 数据获取方式对比

方式 查询标志位 中断方式 DMA方式
CPU占用 中等(需要轮询) 仅在ISR中处理 几乎为零
实时性 一般 最好
复杂度 简单 中等 复杂

实际应用建议

选择指南:

  • 简单单通道读取 → MODE_0
  • 紧急多通道测量 → MODE_1或MODE_2
  • 高速连续采集 → MODE_3
  • 需要实时响应 → MODE_2中断
  • 需要低CPU占用 → MODE_3DMA

性能考虑:

  • DMA模式适合采样率>10Ksps的场景
  • 中断模式适合1-10Ksps的中等速率
  • 查询模式适合<1Ksps的低速应用

这些模式覆盖了从简单到复杂的各种ADC应用场景可以根据具体需求灵活选择。


事件 断电保护 电压过高保护 过流保护 一般温度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
  • 故障上报与记录符合协议,信息完整且准确。

示例上报报文格式

{
  "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示例代码

// 电流监测中断处理示例
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();
}