
简介这是一套基于德州仪器低功耗微控制器实现的位移测量电子尺完整工程适合嵌入式课程设计、电子设计竞赛备赛以及正在学习单片机与传感检测技术的开发者参考。压缩包共集成十五个文件整体体积约三十二KB以C语言源程序、头文件、工程配置文件、调试输出辅助脚本和批处理文件为主可在专用集成开发环境中直接导入并重新编译调试。目前已有137人学习下载。通过分析源码可以掌握微控制器模拟信号采集、模数转换、定时与中断处理、液晶屏驱动以及位移数据换算与实时显示等关键环节工程文件组织简洁软硬件协同设计思路清晰便于按需修改和扩展尤其适合课堂演示、自主仿写或作为毕业设计参考。1. 从 dianzichi.zip 开始用 MSP430 传感器做位移测量的第一件事同事递过来一个工程压缩包文件名就叫 dianzichi.zip。拆开看里面是 MSP430 传感器相关的一整套代码和笔记核心任务写得很直白位移测量。“dianzichi”按拼音读就是电子尺放到工业现场更准确的叫法是 LVDT 位移传感器也就是电感式差动变压器。这玩意儿不能用万用表像测电位器那样直接读数因为它的输出是幅度随铁芯位置变化、相位随方向翻转的交流信号。要让 MSP430 既当信号源、又当采样器把载波激励和解调全部自己做掉才能换算出毫米值。这种场景下MSP430 反而是比 ARM 更顺手的工具定时器精度足够ADC 支持多通道序列转换整体功耗又低。你能拿到这套方案大概率是碰上传感器课程设计或者在产线上要给 LVDT 配数据采集。下面我按一条可复现的路径讲先从传感原理说起再落到最小电路、固件解调和标定最后讲一个真正提升精度的技巧。后面的参数可以直接抄换成自己的传感器量程再微调即可。2. 电子尺LVDT位移传感器原理与 MSP430 的匹配选型2.1 LVDT 电子尺为什么用差动线圈要理解电子尺先看它内部的线圈结构。LVDT 有一组初级绕组两边各有一段次级绕组两个次级反相串联。铁芯处于几何零位时两端次级感应电压大小相等、方向相反差动输出为零。铁芯向一侧移动两个互感一边增大一边减小输出端出现幅度与位移近似成正比的交流电压。更妙的是相位信息铁芯越过零位到另一侧时输出相对激励反相 180 度。位移方向不在幅度里而在相位里。写成分式就是Vout k × x × Vinx 是铁芯机械位移Vin 是激励电压k 跟线圈匝数、磁导率、激励频率和量程有关。注意这个式子只在中间段近似线性越靠近端部非线性越明显。这也是后面必须做标定和拟合的原因。MSP430 在这里的角色很清晰定时器产生载波激励ADC 按整周期等间隔采样最后在软件里做相敏检波。以经典的 MSP430F149 为例内部 Timer_A 输出 PWMADC12 支持多通道序列转换一颗芯片就能把激励、采样、解调全包掉外围只缺运放和传感器本身。2.2 位移测量传感器选型电感式、电涡流、霍尔和光栅怎么选位移测量并不只有电子尺一种选择。电涡流传感器适合几毫米到几十毫米的非接触小量程对金属目标物直接测量抗油污和粉尘但线性量程偏窄标定结果依赖被测材料。霍尔传感器靠磁钢移动改变磁场电路简单、价格便宜但温漂明显磁钢还容易吸附铁屑。光栅尺精度高机床数显里很常见但对油污粉尘敏感密封要求很高。还有反射式传感器这类光电方案适合近距离测距精度天花板比较有限。把它们放到同一张表里对比选型会直观很多类型量程典型分辨率接触/非接触环境耐受成本LVDT 电子尺±1 mm 到 ±500 mm0.1 µm 级别接触无摩擦耐油污、粉尘中高电涡流±0.5 mm 到 ±60 mm亚微米非接触耐油污、高温中霍尔5 mm 到 50 mm10 µm 以上非接触怕磁场、温漂大低光栅尺长量程纳米到微米非接触怕污、需密封高像 MQ2、MQ3 这类气体浓度检测项目和位移测量完全是两个方向不要拿气体传感器的 ADC 读数思路套在 LVDT 上。气体传感器侧重基线漂移和浓度曲线LVDT 侧重相位、线性度和重复性。LVDT 最大的竞争力是无机械磨损、寿命长、重复性好所以传感器课程设计和工业位置反馈里用得非常多。如果你要非接触、小量程、目标又是金属优先看电涡流要长行程高精度位置反馈LVDT 基本是绕不开的选项。2.3 MSP430 选型和外设资源怎么算LVDT 采样的核心参数是载波频率和每周期采样点数。常见电子尺激励频率从几百赫兹到 10 kHz 都有我一般取 2.5 kHz 到 5 kHz既能保证互感效率又给 ADC 采样留足余量。如果每周期采 16 个点2.5 kHz 对应 40 kSPSMSP430F149 的 ADC12 在 4 MHz 转换时钟下可以轻松跑满。之所以选 F149 而不是 MSP430G2553核心原因是 ADCG2553 只有 10 位F149 是 12 位且支持多通道序列转换解调精度差四倍。外设资源按下面这张表分配功能外设引脚/说明激励 PWMTimer_ATA0.150% 占空比P2.0 输出差动信号采样ADC12 通道 A0仪表放大器输出比率测量备用通道ADC12 通道 A1接第二段次级绕组电平参考外部 1.65 V 基准做直流偏置和 ADC 参考提示MSP430FR5969 等新一代 FRAM 型号寄存器兼容度很高产品化时可以换成低功耗更强的型号固件框架不用推倒重来。3. 方波到正弦激励MSP430 驱动电子尺的硬件电路3.1 激励频率和 PWM 参数一起定MSP430 引脚输出不了高品质正弦波最省事的做法是输出方波再利用 LVDT 的窄带特性配合外部低通滤波把基波能量留下来。激励频率、定时器计数初值和采样率三个参数必须一起算。以 SMCLK 为 8 MHz、目标载波 2.5 kHz 为例直接写成宏定义#define SMCLK_HZ 8000000UL #define EXC_HZ 2500UL #define TA0CCR0_VAL (SMCLK_HZ / EXC_HZ - 1UL) // 3200-1 #define TA0CCR1_VAL (TA0CCR0_VAL / 2UL) // 50% 占空比CCR0 决定 PWM 周期CCR1 决定占空比。这里频率选 2.5 kHz 不是拍脑袋LVDT 次级输出幅度和频率相关低频段敏感度下降高频段 ADC 采样压力大。2.5 kHz 下每周期采 16 点只需 40 kSPSMSP430 有充足时间去处理解调累加。想换 5 kHz 就把 EXC_HZ 改成 5000低通滤波器参数同步调整即可。3.2 二阶有源低通把方波整形成正弦50% 占空比方波里主要成分是基波加 3 次、5 次谐波。要得到可用正弦激励至少需要一个二阶低通把 3 次谐波压下去。我用的是经典 Sallen-Key 结构运放做同相缓冲电阻等值、电容取 2:1 比例R1 R2 6.8 kΩC1 10 nFC2 4.7 nF估算特征频率f0 1 / (2π × sqrt(R1 × R2 × C1 × C2)) ≈ 3.4 kHz这个频率是载波 2.5 kHz 的 1.4 倍基波只会被轻微衰减7.5 kHz 的 3 次谐波则被大幅压制。这个参数组合下 Q 值约 0.73接近巴特沃斯特性输出不会过冲。运放用 5 V 单电源的轨到轨型号就行比如 OPA2340 或者 LMV358。低通输出之后再串一个缓冲级去驱动 LVDT 初级绕组缓冲级可以用达林顿对管也可以用运放扩流。电容务必选 C0G/NP0 材质温度系数小相位稳定性好。用普通 X7R 电容做滤波器载波相位会随着温度漂移直接影响后面解调的方向判断。3.3 差动信号到 ADC 的调理偏置到 1.65 VLVDT 两个次级反相串联后输出双极性交流而 MSP430 的 ADC12 只能采 0 到 3.3 V 单端信号。因此必须先把信号中点抬到 1.65 V再做线性放大。仪表放大器是最省事的方案AD620 的 REF 引脚接 1.65 V 后输出自动以 1.65 V 为中心摆动。增益要留余量。比如正负满量程时差动输出 ±150 mV希望 ADC 输入摆到 ±1.5 V增益就是 10 倍AD620 增益公式为G 49.4 kΩ / RG 1RG 取 4.7 kΩ 时 G ≈ 11.5输入 150 mV 对应 1.7 V 摆幅贴近 ADC 满量程但不会饱和。RG 阻值不需要卡得死死的最后的增益残差会在标定拟合时被斜率系数吃掉。需要注意的是放大器输出不能超过 ADC 供电范围否则解决温漂前先引入截波失真。3.4 一张可以直接照抄的接线表把上面几节串起来一张最小系统接线表如下信号路径器件参数说明P2.0/TA0.1 → Sallen-Key6.8 kΩ 10 nF/4.7 nFf0≈3.4 kHz方波转正弦运放输出 → 初级线圈OPA2340 缓冲限流 100 Ω提供 mA 级激励电流次级差动 → 仪表放大器AD620RG 4.7 kΩ差分转单端AD620 REF → 1.65 V精密电阻分压中点偏置ADC 输入范围 0~3.3 VA0 输入前100 Ω/1 nFRC 低通抗混叠、防 ESD接地是整个电路最容易翻车的地方。初级驱动和次级采样之间要单点接地仪表放大器走线尽量短放大器电源引脚加 100 nF 去耦电容。LVDT 自带屏蔽层时屏蔽层接模拟地不要一边接模拟地一边接数字地否则地环路会引入 50 Hz 工频干扰。4. 固件解调MSP430 定时器、ADC12 与相敏检波4.1 Timer_A 输出载波 PWM 的寄存器写法为了让激励频率和采样严格同步PWM 直接用 Timer_A 硬件输出不占 CPU。代码如下TA0CTL TASSEL_2 MC_1 TACLR; // SMCLK增计数清计数器 TA0CCR0 3199; // 8MHz / 3200 2.5kHz TA0CCR1 1599; // 50% 占空比 TA0CCTL1 OUTMOD_7; // 复位/置位模式 P2DIR | BIT0; P2SEL | BIT0; // P2.0 复用为 TA0.1 输出这段代码里TASSEL_2 把时基选为 SMCLKMC_1 让定时器从 0 增计数到 CCR0 后归零输出周期由 CCR01 决定。OUTMOD_7 的含义是TAR 小于 CCR1 时输出高电平计数到 CCR0 时复位所以 CCR1 与 CCR0 的比值就是占空比。P2SEL 置位后引脚才切换为 TA0.1 复用功能。改激励频率只需要改 CCR0 和 CCR1别的都不要动。比如改用 5 kHz就把 CCR0 改为 1599、CCR1 改为 799。占空比始终保持 50%除非传感器手册明确要求非对称激励。对称方波能避免偶次谐波进入输出零点读数会干净很多。4.2 ADC12 序列转换把两路次级信号采进来解调至少需要一路差动信号如果要做比率测量还需要第二路信号。F149 的 ADC12 可以用序列模式一次触发完成多通道转换。配置如下ADC12CTL0 ADC12ON ADC12SHT0_2 ADC12MSC; ADC12CTL1 ADC12SHP ADC12SSEL_2 ADC12DIV_1 ADC12CONSEQ_3; ADC12MCTL0 ADC12INCH_0; // 通道 A0 ADC12MCTL1 ADC12INCH_1 ADC12EOS; // 通道 A1序列结束 ADC12IE BIT1; // 序列完成中断 ADC12CTL0 | ADC12ENC ADC12SC; // 启动逐个参数看ADC12SSEL_2 表示 ADC 时钟取自 SMCLKADC12DIV_1 是 2 分频得到 4 MHz。ADC12SHT0_2 对应 16 个 ADC12CLK即 4 µs 采样保持时间对仪表放大器几百欧姆的输出阻抗足够。CONSEQ_3 是重复序列模式转换完 A0、A1 后自动从头开始不需要软件反复触发。中断服务程序里只干两件事把 ADC12MEM0 和 ADC12MEM1 存入两个环形缓冲区然后清 ADC12IFG1。采样率由硬件连续跑固件只需要保证每 16 个采样点对齐一个载波周期。如果发现两个通道切换时数值跳动把 SHT0 提到 32 个时钟采样时间翻倍代价是总转换速率下降。4.3 相敏检波用正弦余弦表算幅度和方向解调的核心是做乘法ADC 采样序列和本地参考信号相乘再累加。取一个载波周期 16 个点分别乘上正弦表和余弦表得到 I、Q 两个分量#define N 16 const int sinTab[N] {0,49,90,117,127,117,90,49,0,-49,-90,-117,-127,-117,-90,-49}; const int cosTab[N] {127,117,90,49,0,-49,-90,-117,-127,-117,-90,-49,0,49,90,117}; long I 0, Q 0; for (int i 0; i N; i) { int x (int)adc_buf[i] - 2048; // 去掉 1.65V 直流偏置 I (long)x * sinTab[i]; Q (long)x * cosTab[i]; } I I * 2 / N; Q Q * 2 / N;先把 adc_buf 减 2048是把 0~4095 的原始码转换成双极性信号这样才能正确解调交流分量。sinTab 和 cosTab 是 127 标度后的定点正弦表查表代替实时算正弦MSP430 没有硬件乘法器也能快速累加。除以 N/2 是为了把幅度归一化回原始比例。幅度是 sqrt(I²Q²)方向则要看 I、Q 的组合符号。但 LVDT 信号经过低通滤波器后相位并不等于激励相位直接看 I 的符号会判错方向。稳妥做法是先做一次相位校准把铁芯推到正行程某一位置算 atan2(Q, I) 得到参考相位 θ之后每次测量都用投影 P I×cosθ Q×sinθ。P 的正负代表位移方向绝对值代表幅度。提示改采样点数 N 时正弦表和余弦表必须同步换成 N 个值循环变量 i 不能超过表长度。5. 位移标定、线性拟合与常见误差消除5.1 用螺旋测微台架做正反向标定把 LVDT 固定在标定台架上铁芯端连接螺旋测微头或者直接用标准位移台。每移动一个固定步长记录解调值 P 和机械位移。正向从零推到满量程反向再从满量程退回零两个方向都要记录这样能一次性看出回程差和机械间隙。零位附近记录密一点每 0.5 mm 一个点远离零位可以放到 1 mm。我用过的典型记录片段是这样位移 mm正向 P 值反向 P 值0.0-12-82.06216184.0125512496.0183118268.02370236510.028922890注意零位处 P 值不是严格为 0这是零位残压导致的正常现象。质量好的 LVDT 零位电压在满量程的 0.5% 以内。如果零点读数偏大太多先检查机械对中再查次级线圈对称性不要急着在软件里加减偏移量。5.2 最小二乘拟合把 P 值换算成毫米拿到标定数据后用一阶最小二乘拟合就够了。Python 后处理比在单片机里做矩阵运算方便得多import numpy as np p np.array([-12, 621, 1255, 1831, 2370, 2892]) mm np.array([0.0, 2.0, 4.0, 6.0, 8.0, 10.0]) k, b np.polyfit(p, mm, 1) fit k * p b err mm - fit print(k%.5f b%.3f % (k, b)) print(max nonlinearity: %.4f mm % np.max(np.abs(err)))polyfit 第一个参数是自变量 P 值第二个参数是因变量 mm返回斜率 k 和截距 b。固件里最后只需保存 k 和 b测量时执行 mm k × P b。脚本输出的 max nonlinearity 如果超过量程的 0.5%优先排查机械装夹是否松动而不是继续堆拟合阶数。拟合残差要观察分布形态。残差全部偏正或全部偏负是斜率或截距没拟合好。残差呈对称 U 形说明 LVDT 端部非线性没有被一阶模型覆盖这时再考虑二阶多项式。课程设计阶段做到一阶拟合加残差检查已经足够。5.3 温度漂移和激励幅度变化怎么压掉电子尺初级绕组是铜线温度升高时直流电阻变大次级感应电压整体下降。结果是同一位置读数变小这就是温度漂移。此外 PWM 方波经过滤波器后电源电压波动也会直接影响激励幅度导致测量值整体缩放。对付这种共模漂移的惯用手法是比率测量同时采样两段次级绕组各自的幅值 V1 和 V2计算out (V1 - V2) / (V1 V2) × GainV1V2 随激励幅度同步变化分子分母同时缩放比值基本不变。这样激励幅值漂移和初级铜阻温漂被抵消掉一大半。代价是需要两个 ADC 通道分别采两段次级信号固件按前面 4.2 节的序列模式扩展即可。V1、V2 必须是解调后的幅值不能拿原始 ADC 码直接算因为原始码里还叠着 1.65 V 直流偏置。6. 把测量精度再抬一档同步检波与过采样的配合到这里读数已经能稳定输出但如果你拿它做高精度位置反馈还可以再压出一两倍信噪比。技巧是两件事一起做把解调窗口从单个周期拉长到几十个周期再把采样时刻严格锁在 PWM 边沿上。先说过采样。单个载波周期的 16 个点解调一次白噪声还占一定比例。如果连续取 32 个周期的数据再做 I/Q 累加等效于对 512 个采样点做相干平均白噪声功率降到约 1/√512也就是 4% 左右。对 12 位 ADC 而言这个操作理论上能把有效分辨率推高 2 到 3 位。代价只是几毫秒的响应延迟MSP430 在 8 MHz 下做几百次乘累加完全没有压力。过采样的大前提是相位严格同步。ADC 自由运行采样会引入相位抖动直接污染 I/Q 解调结果。最干净的做法是让 ADC 触发源复用 Timer_A 的同一个输出比较通道每次采样点相对 PWM 边沿的延迟完全固定。如果芯片不支持硬件触发就在 TA0 中断里计算下一次采样时刻用软件触发 ADC也能达到非常高的相位一致性。同步检波的本质是把 ADC 的宽频噪声通过乘法运算收窄到一个频点附近采样时刻抖动越小陷波效果越好。相位漂移还有一个人为制造的大坑低通滤波器电容的温漂。前面强调 C0G/NP0 电容就是因为它对相位稳定至关重要。如果激励路径里用了 X7R 电容载波相位会随环境温度缓慢漂移。处理办法是定期重新校准参考相位 θ把铁芯推到已知标定点位用 atan2(Q, I) 更新 θ再对当前读数做投影计算。校准频率取决于环境温度变化速率产线环境通常一小时一次就够。最后给一个实用的验收标准当 P 值在满量程的 0.1% 以内波动时说明解调、过采样和电源地线都过关了。如果毫秒级波动超过 1%先回硬件查激励波形失真度和地环路再去改软件滤波参数。这个顺序别搞反。本文还有配套的精品资源点击获取