news 2026/10/20 4:21:15

STM32F373内置16位∑-Δ ADC实战:从初始化到校准滤波

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32F373内置16位∑-Δ ADC实战:从初始化到校准滤波

简介:面向 STM32F373 高精度模拟采集开发的完整工程资源,围绕 SDADC 的启动转换、采样保持、逐次逼近与结果读取全流程组织,适合工业自动化、环境监测等场景中的嵌入式开发者参考。压缩包共 159 个文件、3.16MB,包含 30 个 h 头文件、28 个 c 源文件、28 个 o 目标文件、27 个 crf 交叉引用文件,以及 uvproj/uvopt 工程配置和 hex、axf 等编译输出;头文件用于外设寄存器与接口声明,C 源文件提供驱动实现,o/crf/hex/axf 则支撑编译链接与烧录验证。资源中 stm32f37x_sdadc.c、stm32f37x_rcc.c 等示例覆盖独立、双通道同步和多通道模式,对两路 SDADC 同步采集、采样时间设置与校准逻辑有直观展示;同时保留 bak 备份配置,便于对比参数改动。工程还附有 s 启动文件与 map、lst 链接列表,可辅助分析启动流程和内存布局。已有 1866 人学习,适合需要缩短 STM32F373 数模转换调试周期、快速上手 SDADC 驱动开发的读者。

1. STM32F373 SDADC:16 位内置 Σ-Δ ADC,能不能替掉外置采集芯片?

大部分工程师听到 STM32F373 SDADC 的第一反应,是“单片机自带 ADC 能有多强”,直到看到它是 16 位 Σ-Δ 架构、自带可编程增益、支持差分输入,才意识到这颗外设不是用来做电机电流环那种高速采样的,而是给称重、压力、温度、微弱直流信号这类中低速高分辨率场景准备的。我这次拆的是一套围绕它搭建的工程模板,覆盖初始化、内部校准、多通道扫描、DMA 搬运、电压换算和滤波。适合想把 F373 内置 SDADC 真正用起来、又不想在外置 ADC 上多花成本的人。新手可以照着走,熟手可以直接看第三章之后的参数边界和调试坑。

2. 先看清 SDADC 的架构与选型:过采样原理、三种输入模式、OSR 如何取舍

2.1 Σ-Δ 过采样与噪声整形:为什么中低速测量会选它

大多数 MCU 内置 ADC 是逐次逼近型,12 位为主,做到 16 位需要外部高精度基准和前端调理。SDADC 是 Sigma-Delta 调制器加数字抽取滤波器的组合:调制器用远高于奈奎斯特频率的采样率对输入进行粗量化,产生一位或多位高速比特流,然后通过噪声整形把量化噪声推到高频段,再由数字滤波器把带外噪声滤掉。

这个过程换来的是高分辨率,代价是输出数据率不会太高。同样的过采样率下,分辨率越高、滤波器越陡,生效速率越低。做称重、应变、电化学传感器这类带宽在几十赫兹以内的信号,SDADC 的速率瓶颈完全可以接受,还能省掉外置仪表放大器和单独的高分辨率 ADC 芯片,这是我在选型时最看重的一点。

与逐次逼近型 ADC 相比,SDADC 的线性度和温漂表现更依赖数字滤波和校准。逐次逼近型 ADC 的失调和增益误差比较直观,而 SDADC 的误差在不同 OSR、不同 PGA 增益下会变化,不能只靠手册上的典型值推算,必须做内部校准或两点定标。这也是后面第四章重点讲校准的原因。

2.2 三种输入模式:单端 A、单端 B、差分 A-B 的接线与适用场景

F373 的 SDADC 提供了三种输入模式:单端 A、单端 B、差分 A-B。这直接影响传感器接线和信号调理电路设计,必须在初始化之前定下来,因为后续的通道配置、PGA 增益和数据符号解释都依赖它。

输入模式连接方式适合场景注意事项
单端 A信号接 A 引脚,参考地接公共地0~VREF 范围的正电压信号,输出数据通常为正或接近零抗共模干扰能力弱,信号源离 MCU 较远时容易引入地噪声
单端 B信号接 B 引脚,参考地接公共地少数用 B 引脚做第二路单端输入的板子和单端 A 一样,注意地回路
差分 A-B正端接 A,负端接 B桥式传感器、热电偶、应变片,信号幅值小且共模电压高数据有符号位,正负代表方向,接反会看到反向满码

差分模式是我在桥式传感器项目里最常用的。传感器输出两端分别接到 A、B,SDADC 内部对差值做转换,共模电压在 AD 输入范围内时不会影响测量结果。这种接法对电源纹波容忍度明显比单端高,但要求 A、B 两路到传感器的走线尽量等长、等宽,避免共模噪声转成差模噪声。

如果信号本身是单端,但又希望利用差分模式的抗干扰能力,可以在前端把单端信号转成差分,这需要额外电路。工程模板里默认按单端 A 和差分两种模式各给了一组配置示例,改模式时只需要换初始化函数里的模式参数,接线按上表对应调整即可。

2.3 参考电压、时钟和 OSR:决定分辨率和数据率的三个旋钮

SDADC 的参考电压直接影响满量程范围。内部参考用起来省事,但精度和温漂受芯片自身限制;外部参考能拿到更好的长期稳定性,适合做精密测量。我一般先看传感器满量程输出幅值,把参考电压选到比最大输出略高一档,再用 PGA 增益把信号放大到接近满量程,这样有效位数利用率最高。

时钟和 OSR 是一对要一起看的参数。SDADC 的调制器和数字滤波器需要时钟驱动,OSR 决定每个输出样本积累多少个过采样点。OSR 越大,带内噪声被压得越低,但输出数据率也越低。选 OSR 时不要只看分辨率,要看系统需要的有效更新率。比如一个 10Hz 带宽的称重信号,OSR 取高一点没问题;如果要同时采集四路 1kHz 信号,OSR 必须往低调。

经验值是:先用参考电压和信号源幅值确定 PGA 和输入模式,再用目标数据率反推 OSR 上限,最后用短路噪声和外部基准做一轮实测,确认码分布宽度满足系统精度要求。OSR 128 和 OSR 256 对多数直流测量场景来说差别不大,但输出速率差一倍,别盲目追求高 OSR。

3. 把 SDADC 驱动起来:初始化、扫描模式与 DMA 缓冲区的工程模板

3.1 资源包结构:驱动层和应用层的分工

工程模板按“驱动层 + 应用层”拆开。驱动层只做 SDADC 的初始化、校准、通道配置、DMA 启动和原始码读取,不关心业务逻辑;应用层负责把原始码换算成电压、滤波、标定。这样换板子或换通道时不需要改应用代码,最多调驱动层的模式参数。

我拆过的模板里,关于 SDADC 的部分通常包含下面几个文件,实际工程里你拿到的包结构可能略有差异,但职责基本一致:

文件职责关键函数
sdadc_drv.c/hSDADC 底层初始化与启动sdadc_init、sdadc_start_dma
sdadc_cal.c/h内部校准和两点定标sdadc_calibrate、linear_cal
filter.c/h移动平均和一阶 IIR 滤波moving_average、iir_lowpass
app_read.c/h应用层电压换算与数据上报get_sensor_value

这样的分层有一个直接好处:调试 DMA 数据错位时只需盯着驱动层,排查内部校准问题时只需看 sdadc_cal,不用在几千行业务代码里翻配置。资源包拿到手后,我建议先编译一遍最小工程,确认 DMA 数据能稳定打进缓冲区,再往业务层接逻辑。

3.2 初始化与校准代码:标准外设库风格的配置片段

下面这段代码是标准外设库风格的表达方式,HAL 工程的函数名会有差异,但配置逻辑完全一致。我用这种风格写是因为它把寄存器操作表达得更直白,方便对着参考手册核对每一位的作用。

// 假设使用 SDADC1,初始化结构体变量先清零 SDADC_InitTypeDef sdadc_init; sdadc_init.SDADC_ModSel = SDADC_ModSel_SingleA; // 单端A模式 sdadc_init.SDADC_Prohibit = SDADC_Prohibit_None; // 不禁止任何输入模式 sdadc_init.SDADC_Resolution = SDADC_Resolution_16b; // 16位输出 SDADC_Init(SDADC1, &sdadc_init); // 使能SDADC1时钟和对应GPIO的模拟输入功能后,再做内部校准 SDADC_Cmd(SDADC1, DISABLE); // 校准前保持禁用状态 SDADC_CalibrationStart(SDADC1, SDADC_CalibrationSequence1); // 等待校准完成,避免在未就绪时启动转换 while (SDADC_GetCalibrationFlagStatus(SDADC1, SDADC_CalibrationSequence1) == RESET) { // 这里可以加超时保护,防止校准异常导致死循环 } // 校准完成后使能SDADC SDADC_Cmd(SDADC1, ENABLE);

SDADC_ModSel 参数决定后续所有通道默认输入模式,比如差分模式对应的枚举通常与单端不同,HAL 里写在通道配置结构体中而不是初始化结构体里。我习惯把模式参数写成编译期宏,方便在单端和差分之间切换,避免手动改多个文件。

SDADC_CalibrationSequence1 是内部校准序列,必须在使能 SDADC 之前触发,否则校准序列可能无法正确执行。校准完成标志是置位还是清零取决于库实现,代码里用 while 等待时务必加超时,因为如果供电异常或时钟没配好,校准标志可能一直不变化,整个系统卡在这一行。

3.3 多通道扫描与 DMA:缓冲区里的数据顺序怎么排

SDADC 支持一个 ADC 外设扫描多个已配置通道,转换结果按通道号顺序写入。多通道初始化时,需要逐个通道调用通道配置函数,并指定对应输入模式、PGA 增益。

SDADC_ChannelConfigTypeDef ch_cfg; // 通道0:单端A,PGA增益为1,接到压力传感器 ch_cfg.SDADC_Channel = SDADC_Channel_0; ch_cfg.SDADC_InputMode = SDADC_InputMode_SingleEndA; ch_cfg.SDADC_PGASel = SDADC_PGA_Gain1; SDADC_ChannelConfig(SDADC1, &ch_cfg); // 通道1:差分A-B,PGA增益为4,接到桥式应变片 ch_cfg.SDADC_Channel = SDADC_Channel_1; ch_cfg.SDADC_InputMode = SDADC_InputMode_DiffAB; ch_cfg.SDADC_PGASel = SDADC_PGA_Gain4; SDADC_ChannelConfig(SDADC1, &ch_cfg);

通道配置的意义是把每个通道各自的信号条件告诉 SDADC,包括输入模式、增益和是否参与扫描。注意每配置一个通道,就相当于把它加进扫描序列里。如果在参考手册的寄存器位定义里看到 Prohibit 字段,那是用来屏蔽某些模式下不需要的输入方式,通常保持 None 即可。

DMA 配置的关键在于缓冲区数据类型。SDADC 输出是 16 位有符号整数,DMA 搬运时按半字(16 位)处理。我习惯把缓冲区定义为 int16_t 数组,长度等于扫描通道数乘以上下文的帧数。启动扫描后,第一个转换结果写入 buffer[0],第二个写入 buffer[1],顺序与通道号一致,不会乱序。

#define SDADC_CH_COUNT 2 static int16_t sdadc_buf[SDADC_CH_COUNT]; // 启动DMA传输,循环模式让数据不停刷新 // 这里仅示意DMA源地址和内存地址,实际请按你的库填写 SDADC_DMAConfig(SDADC1, DMA_Channel_Config, (uint32_t)&sdadc_buf[0], SDADC_DMA_Mode_Circular); SDADC_DMACmd(SDADC1, ENABLE); SDADC_StartConversion(SDADC1);

如果 DMA 配置成了字节模式或缓冲区类型写成了 uint8_t,就会出现高低字节错位的问题。这个坑我放到第五章细说。这里先记一个原则:SDADC 一个数据单元是 16 位,DMA 缓冲区元素宽度必须是 16 位。

3.4 从缓冲区读数据:启动转换与轮询/中断的取舍

转换启动后,数据会持续写入 DMA 缓冲区。如果只需要单次采样,可以关闭 DMA 循环模式,在传输完成中断里读取;如果需要连续监控,用循环模式让 DMA 自己滚动更新,应用层只管按固定节拍读 buffer 值即可。

轮询模式不是不能用,但要注意 OSR 较高时输出数据率低,主循环里反复查询转换完成标志会导致 CPU 空转。我在低功耗或高并发系统里通常用 DMA 完成中断或空闲中断去读数据,主循环保持空闲。这样做的另一个好处是,滤波器若放在中断里,采样节拍不会因为主循环任务抖动而漂移,滤波效果更稳。

读缓冲区时还有一个容易被忽略的细节:DMA 正在搬运和主循环读取同一块 buffer 时,可能读到“半个帧”的数据。如果只需要稳态值,这点撕裂影响不大;如果对数据一致性敏感,我一般用双缓冲,DMA 写入后缓冲、主循环读前缓冲,中间用一个标志切换。工程模板里 DMA 配置成循环模式,实测单通道连续读取没问题,多通道加滤波后建议考虑双缓冲。

4. 把原始码变成物理量:内部校准、数字滤波与两点定标

4.1 内部校准:启动时机和校准状态检查

SDADC 的内部校准用来调整失调和部分增益误差,它是在芯片出厂测试基础上做的用户侧校准。校准触发时机非常关键:一定要在 SDADC 禁用状态下启动校准,等校准完成后再使能转换。如果顺序反了,后续读到的数据会整体偏一个固定值,而且这个偏移量在每片芯片上不一致,很难用统一补偿消除。

校准完成后,有些库会要求把校准结果写回特定寄存器,有些库自动完成。工程模板里我在校准等待之后加了一段读取校准值的代码,用串口或调试器打印出来,目的是确认校准确实执行过。若校准值读出来全是 0 或全 F,优先怀疑 SDADC 时钟没配好,而不是芯片坏了。

4.2 数字滤波:移动平均与一阶 IIR 的参数选择

SDADC 本身已经有数字抽取滤波器,但输出的数据里仍存在少量白噪声。针对直流或缓慢变化信号,在应用层加一阶低通或多点移动平均是常规做法。移动平均的优点是线性相位,缺点是内存占用和响应延迟随窗口长度增加;一阶 IIR 的优点是内存少、计算快,缺点是相位非线性,阶跃响应有拖尾。

// 移动平均:窗口大小为N,存最近N个采样值 float moving_average_filter(float new_sample, float *buf, uint32_t n, uint32_t *index) { buf[*index] = new_sample; *index = (*index + 1) % n; // 环形缓冲,覆盖最旧数据 float sum = 0.0f; for (uint32_t i = 0; i < n; i++) { sum += buf[i]; } return sum / (float)n; }

窗口 N 通常取 4、8、16 或 32,具体选多大要看数据更新率和系统响应要求。比如数据率是 1kSPS,N=32 时滤波后等效带宽约 30Hz,能压掉大部分高频抖动,但阶跃响应大约要 32ms 才能稳定。如果动态响应要求高,N 就得往小调,或者改用 IIR。

一阶 IIR 滤波器的系数用 alpha 控制,alpha 越大滤波越轻、响应越快,alpha 越小滤波越重、响应越慢。我一般把 alpha 设为 0.1 到 0.3 之间,配合 OSR 和移动平均一起看效果。注意滤波器的截止频率要和实际信号带宽匹配,不是越低越好,过低的截止频率会把有用信号变化也抹掉,看起来“数据很稳”,实际上已经失真。

4.3 电压换算与两点定标:消除增益误差的完整公式

SDADC 的原始码是 16 位有符号整数,满量程范围由参考电压和 PGA 增益决定。单端模式下的理论换算公式是:

电压值 = 原始码 × 参考电压 / 32768 / PGA增益

差分模式同理,原始码为正值表示 A 端高于 B 端,负值表示相反。这个公式只用了理想增益,实际芯片的增益误差和失调会让换算结果偏大或偏小,工程上必须做两点定标。

typedef struct { float code_low; float code_high; float value_low; // 对应低端物理量 float value_high; // 对应高端物理量 } linear_cal_t; float linear_cal_convert(int16_t raw_code, linear_cal_t *cal) { float slope = (cal->value_high - cal->value_low) / (float)(cal->code_high - cal->code_low); float offset = cal->value_low - slope * cal->code_low; return slope * raw_code + offset; }

两点定标的思路是:给传感器施加一个已知的低端值和高端值,记录对应的原始码,然后按直线关系把整个量程映射到物理量。这样增益误差、失调、以及部分非线性误差在两端被强制修正,中间段误差取决于传感器本身的线性度。

标定时要注意两个原始码之间距离不能太小,否则斜率容易放大噪声。我在实践里会把低端取量程的 10% 以下,高端取量程的 90% 以上,确保斜率有足够像素距。定标参数存到非易失区后,设备重启直接读取,不用每次上电都重新标定。

5. 避坑:SDADC 调试中五个高发问题和对应解法

5.1 读出的数据像噪声一样跳动,码宽超过预期

现象:输入短接或接稳定电压时,连续读到的原始码分布很宽,几个 LSB 甚至十几 LSB 的跳变,明显比规格书里的噪声典型值差。

原因:这类问题七成出在参考电压或电源去耦。SDADC 对参考噪声非常敏感,如果参考引脚没接足够容值的去耦电容,或者去耦电容离引脚太远,内部基准的噪声会直接叠加到量化结果上。另有部分原因是 OSR 设置过低,没有足够的过采样来压制带内噪声。

解决:把参考电压和模拟电源引脚的 0.1uF 与 1uF 电容尽量靠近芯片放置,并保证地平面连续。再把 OSR 提高一档,观察码宽变化。若 OSR 64 时跳 4 个 LSB,OSR 256 时降到 1 个 LSB,说明主要问题在噪声整形,不是芯片故障。若 OSR 提高但码宽几乎不变,优先查时钟和参考。

5.2 差分模式下数据始终偏向 0x7FFF 或 0x8000

现象:差分输入接法正确,也给了合理的共模电压,但读到的数据经常顶到满量程附近,单端模式却正常。

原因:A、B 两端信号反接了。差分输入是有方向的,当传感器正负端与 A、B 引脚接反时,信号幅值超过正满量程或负满量程,输出会被钳到边界。部分传感器在静态时两端电压差本来就接近满量程,反接后直接饱和。

解决:先量一下 A、B 两脚对参考地的静态电压,确认差值方向和幅值符合预期。然后把差分输入交换 A、B 或者在前端加方向选择开关,让信号落在转换范围内。调试时可以从数据符号判断:差分模式读数为负且接近满偏,大概率是接反,而不是芯片坏了。

5.3 通道切换后第一帧数据明显偏大或偏小

现象:多通道扫描时,每次切换通道后读到的第一个数据与稳定值差很多,后续帧正常,且数据率越快越明显。

原因:输入通道切换后,SDADC 内部滤波器和 PGA 需要建立时间。不同输入阻抗、不同外部源阻抗下,建立时间变化很大。扫描周期很短时,第一帧数据包含了前一通道的残留影响,不能当真实采样值用。

解决:在应用层丢弃每个通道切换后的第一帧数据,从第二帧开始算有效数据。如果多通道里某一路对建立时间特别敏感,可以把这个通道配置到扫描序列里重复两次,只取第二次的结果。配合 DMA 循环模式,丢弃数据不用改驱动,只需在数据处理函数里加一个起始偏移。

5.4 OSR 调高后系统响应变“卡”

现象:把 OSR 从 64 调到 256 后,数据显示率明显下降,主循环里轮询转换标志时 CPU 占用率飙升,按键响应和显示刷新都变慢。

原因:OSR 提高导致数据输出率下降,这在预期内;但轮询模式会让主循环持续等待,把 CPU 时间消耗在无用的空转上。OSR 只是放慢了数据速率,并没有让 CPU 休眠或让出总线。

解决:改用 DMA 循环模式加空闲中断,数据到达后只置一个标志位,主循环在空闲时才处理。滤波代码也应放到中断或低优先级任务里,不要放在轮询主循环中。若系统里还有其它实时任务,把 SDADC 的数据读取拆成“缓冲区轮询 + 节拍处理”两个阶段,避免长阻塞。

5.5 DMA 数据高低字节错位,缓冲区里通道序乱

现象:DMA 启动后,读到的 buffer[0] 和 buffer[1] 看起来像两个半字节被拆散重排,单通道时数据在高低字节间抖动。

原因:DMA 配置成字节模式,而 SDADC 输出是 16 位数据。缓冲区类型又是 int16_t,结果一次搬运半个字,造成高低字节错位和通道错位。另一常见原因是缓冲区地址没有按半字对齐,或 DMA 外设地址配到了 32 位寄存器。

解决:把 DMA 的数据宽度明确配置为半字,内存地址也要与缓冲区元素宽度一致。缓冲区数组用 int16_t 类型,确保起始地址按 2 字节对齐。最后检查 DMA 外设地址是 SDADC 数据寄存器而不是某些库封装的缓冲寄存器。改完后单通道先看原始码是否随输入单调变化,再开多通道。

6. 进阶验证:用短路噪声和外部基准摸透一片 SDADC 的真实底细

SDADC 配好并能读到数,只是第一步。真正判断这块 SDADC 能否满足精度目标,我会先做两项实测,而不是急着看滤波后的数据好不好看:一是短路输入统计噪声宽度,二是接外部基准验证换算精度。

短路输入做法是:把 A、B 输入端都接到参考地,或直接短接,保证外部没有真实信号。连续采集 1000 帧原始码,统计最大值、最小值和标准差。码宽越窄说明噪声底越低,也说明电源和布局基本健康。若码宽明显大于理论预期,除非硬件改版,否则只能靠数字滤波和两点标定去补偿,但这个补偿是有代价的,会把系统响应拖慢。实测代码逻辑很简单:

int16_t raw_min = 32767, raw_max = -32768; uint32_t sum = 0, n = 1000; for (uint32_t i = 0; i < n; i++) { int16_t sample = read_sdadc_ch(0); // 读取当前通道原始码 if (sample < raw_min) raw_min = sample; if (sample > raw_max) raw_max = sample; sum += (uint32_t)sample; } float avg = (float)sum / (float)n; float peak_to_peak = (float)(raw_max - raw_min);

短路输入验证完,再接一个稳定外部基准电压做单点精度测试。选一个接近量程 80% 的电压,记录几千帧数据的平均值,与理想换算值作差,能得到实际增益误差。把低端和高端两点都测一遍,就能算出两点定标需要的斜率和截距。这两项做完,SDADC 的底细就清楚了:噪声底有多低、增益误差有多大、线性度怎么样,全都有数。

从那以后,我每次换板子或调整 SDADC 配置,都强制先跑一遍短路噪声和外部基准两点验证,数据宽度超标就先查布局和时钟,不急着上滤波和标定。这套流程不复杂,却能省掉后面一大半“数据为什么不对”的血泪排查,也让我对每一片板子上的 SDADC 真实表现有底。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 4:19:48

C#删除PDF数字签名:原理、策略与批量清理实战

按我处理文件自动化项目多年的经验&#xff0c;用 C# 处理 PDF 数字签名这件事&#xff0c;大家研究得多半是“怎么加签”&#xff0c;很少人认真想过“怎么删”。直到我接手了一个合同归档系统的改造&#xff1a;两千多份带测试签名的 PDF 模板必须复用&#xff0c;验签一跑就…

作者头像 李华
网站建设 2026/10/20 4:19:47

8位OTP单片机JZ8P2613 DEMO配置字与汇编例程调试全攻略

简介&#xff1a;这份压缩包是一份针对晶哲jZ8P2613高性能低功耗8位单片机的演示程序与配置指南&#xff0c;面向嵌入式开发者和单片机学习者&#xff0c;适合需要掌握8051汇编编程、寄存器配置及中断/通信处理的实践场景。包内共44个文件&#xff0c;整体1.92MB&#xff0c;包…

作者头像 李华
网站建设 2026/10/20 4:19:28

上下文模式架构设计:从状态管理到工程实践

1. 从"上下文模式"说起&#xff1a;一个被低估的架构决策第一次看到"context-mode"这个词&#xff0c;很多人会下意识地把它归类成某个框架里的配置项&#xff0c;或者某个API的开关参数。但如果你真正在系统设计里摸爬滚打过几年&#xff0c;就会意识到&a…

作者头像 李华
网站建设 2026/10/20 4:19:07

Elasticsearch查询实战:从DSL语法到性能调优的踩坑全记录

平时写接口和调业务逻辑的时候&#xff0c;大家可能都有同感&#xff1a;Elasticsearch 的查询语法说简单也简单&#xff0c;但真到了线上排查问题&#xff0c;或者突然要写一个稍微复杂的聚合统计时&#xff0c;往往还是得翻文档、翻历史记录。我自己的习惯是&#xff0c;每次…

作者头像 李华
网站建设 2026/10/20 4:18:24

银河麒麟V10 SP1 ARM64部署Elasticsearch实战与避坑指南

1. 为什么要在国产ARM64服务器上折腾Elasticsearch第一次在银河麒麟高级服务器操作系统 V10 SP1 的ARM64环境里部署Elasticsearch&#xff0c;我的反应是"这不就是换个架构装个包的事"。结果从下载发行版那一刻起&#xff0c;就发现事情没那么简单。官方预编译包默认…

作者头像 李华
网站建设 2026/10/20 4:18:02

地磅串口转MQTT上云:从仪表到看板的完整实战指南

前几天有人问我&#xff0c;地磅房里那台托利多地磅的仪表串口&#xff0c;能不能直接连到MQTT服务上&#xff0c;让过磅数据实时跑到办公室看板里。我说能&#xff0c;而且这种活现在已经算工业数采里的固定套路了&#xff1a;仪表串口出来&#xff0c;接一台有人串口网关&…

作者头像 李华