4. 实时数据采集软件设计
实时数据采集软件的核心任务,是在确定的时间约束下,把传感器或前端调理电路输出的模拟/数字信号,按可预期的节拍转换为可被上层算法消费的数据块。它同时受四个量约束:采样率决定时间分辨率,分辨率决定幅度量化精度,缓冲策略决定数据在时间上的连续性,中断与DMA决定CPU以何种代价获得这些数据。多通道同步采集则是在上述约束之上,再叠加一个“通道间时间一致性”的要求。
一、采样率:从需求反推,而不是从芯片上限取
采样率首先由信号带宽决定。对心电、脑电、体温、血压这类低频生理信号,按奈奎斯特准则取最高关注频率的2.5~5倍即可;例如心电诊断带宽通常关注到150 Hz,工程上常取500 Hz或1000 Hz,既满足波形形态(QRS、ST段)还原,又给数字滤波留出过渡带。对超声、光电容积脉搏波的高频成分、肌电等信号,则可能取到10 kS/s甚至更高。
采样率一旦确定,就要核算三个量:单通道数据率 = 采样率 × 每样本字节数;总数据率 = 单通道数据率 × 通道数;以及单位时间中断/传输次数。例如8通道、16位、1 kS/s,单通道2 B/样本,总数据率16 kB/s,属于低速流,用普通定时器中断即可;若换成8通道、24位、50 kS/s,总数据率1.2 MB/s,就必须考虑DMA与块传输。采样率还直接决定定时器重载值:若ADC由定时器触发,触发周期 T = 1/f_s,定时器计数频率 f_clk 与预分频 P、重载值 ARR 满足 f_s = f_clk / ((P+1)(ARR+1)),配置时应先算 ARR 再取整,并核对实际采样率与目标值的偏差。
二、分辨率:位数、有效位数与量程的联合选择
分辨率不只是“选16位还是24位”。真正决定可用精度的是有效位数(ENOB),它受参考电压噪声、前端增益、PCB布局和采样保持电路影响。工程上常用“1 LSB对应多少物理量”来判断:若量程为±5 mV、ADC为24位、PGA增益100,则输入满量程对应±5 mV,1 LSB ≈ 10 mV / 2^24 ≈ 0.6 nV,这显然低于前端噪声底,说明此时限制精度的是模拟前端而非ADC位数。反之,若量程±5 V、16位、无增益,1 LSB ≈ 153 µV,对微弱生理信号就明显不够。因此分辨率选择要与量程、增益、噪声一起核算,避免“高位数量化噪声被前端淹没”或“低位数量化台阶可见”两种浪费。
三、缓冲策略:环形缓冲、双缓冲与水位控制
采集数据不能“采一个、传一个”,否则CPU被高频中断拖垮。常见做法是环形缓冲区(ring buffer):写指针由DMA或中断推进,读指针由消费任务推进,两者独立,靠“写指针 - 读指针”计算可读样本数。为避免读写冲突,通常采用单生产者单消费者模型,写端只改写指针,读端只改读指针,并用内存屏障或原子操作保证可见性。
缓冲深度的选择要同时满足两个条件:一是能覆盖最坏情况下的消费延迟(如上层算法一次处理耗时、任务调度抖动),二是不能大到让端到端延迟不可接受。工程上常按“最坏延迟 × 数据率 × 安全系数1.5~2”估算。若采用双缓冲(ping-pong),则DMA填满A块时中断通知处理B块,处理与采集并行,适合块处理算法;若采用多级水位,可设置低水位触发唤醒、高水位触发告警、溢出水位触发丢帧计数,把“缓冲”从被动存储变成主动流控。
四、中断与DMA:把CPU从搬运中解放出来
中断方式适合低速、事件型采集:每次转换完成触发中断,在ISR中读寄存器、写缓冲、更新计数。它的优点是实现简单、响应确定;缺点是中断频率随采样率和通道数线性上升,当总中断次数超过CPU可承受范围时,主循环和通信任务会被严重挤压。
DMA方式则让外设直接与内存交换数据,CPU只在“半传输/全传输完成”时被中断一次。以STM32类MCU为例,ADC配置为连续扫描+定时器触发,DMA设为循环模式,半满中断用于通知“前半块可读”,全满中断用于通知“后半块可读”,这样CPU处理的是数据块而不是单个样本,中断频率下降为原来的1/N(N为块长度)。代价是需要处理缓存一致性(若使用D-Cache)、DMA与CPU对同一缓冲区的访问顺序,以及传输错误、溢出等异常状态。
五、多通道同步采集:同时刻、同节拍、同时间戳
多通道同步的关键是“同一时刻采样”。若各通道轮流转换,通道间会存在固定时差,对相位敏感的应用(如阻抗分析、多导联心电)不可接受。常用方案有三类:一是同步采样ADC,每个通道独立采样保持,同时启动转换;二是多ADC同步触发,用同一触发源同时启动多个ADC;三是单ADC扫描+采样保持,在扫描前统一采样保持,再依次转换,转换期间保持电压不变,从而把“采样时刻”统一到扫描起点。
软件上还要解决三件事:通道顺序与数据打包格式(交错存储还是分通道存储)、通道间增益/偏置校准、以及统一时间戳。时间戳通常由触发定时器计数器给出,每个数据块记录起始计数值,消费端据此重建绝对时间轴。若存在通道间固定延迟,应在标定阶段测量并写入补偿表。
六、一个可落地的参数配置示例
假设某生理信号采集板使用8通道同步采样ADC,目标采样率1 kS/s,16位,量程±5 V,PGA增益1,MCU主频72 MHz,定时器计数频率72 MHz。先算定时器:取预分频P=71,则计数频率1 MHz,ARR=999,实际采样率 = 1 MHz / 1000 = 1 kS/s,误差为0。再算数据率:8通道 × 2 B × 1000 = 16 kB/s。DMA块长度取256个样本(即32个通道扫描帧),则每块时间 = 256/1000 = 256 ms,半满中断间隔128 ms,CPU有充足时间处理。环形缓冲深度取4096样本,约256 ms数据量,可覆盖一次算法处理的最坏延迟。若消费任务每50 ms取一次数据,则每次可取约800样本,远小于缓冲深度,不会溢出。
七、常见问题与排查方向
- 通道间相位不一致:检查是否使用了同步采样保持;若为顺序扫描,确认采样时刻是否统一到扫描起点,并测量通道间固定延迟。
- 采样率实际值与设定值不符:核对定时器时钟源、预分频和ARR是否按公式计算,注意ARR写入是否在更新事件后生效。
- 数据偶发错位:检查DMA与CPU对缓冲区的访问是否越界,半满/全满中断中是否误改了读指针。
- 噪声底偏高、有效位数不足:核算1 LSB与前端噪声,检查参考电压去耦、模拟地与数字地分割、采样保持电容匹配。
实时数据采集软件设计的本质,是把“时间—幅度—通道”三个维度的约束,翻译成定时器、ADC、DMA和缓冲区的具体参数。采样率决定节拍,分辨率决定精度,缓冲决定连续性,中断与DMA决定CPU代价,多通道同步决定通道间一致性。五者相互制约,任何一项单独调优都可能被另一项拖回瓶颈,因此设计时应先明确信号带宽与精度需求,再反推采样率与分辨率,最后用缓冲深度和DMA块长匹配消费端的处理节奏。