旋钮没有传数字,单片机为什么能读出位置?
本文为教学接线与设计预期,尚无实物测量记录;统一使用 NUCLEO-F030R8。
问题
旋钮里没有小电脑,也没有发出二零四八这个数字。可你一转,单片机却能显示位置。它究竟读到了什么?先看真实变化:滑动端的电压会跟着旋钮位置改变。单片机把这个连续电压,换成一个有限范围的数字。
物件动作
想象一根三点三伏到零伏的长尺,小熊拿着探针沿尺子移动。它移到中间,探针碰到的就是大约一半的电压。一端接三点三伏,另一端接地,滑动端就像这支会移动的探针;旋钮只是推动它。
真实连接
回到电路,拿一只一万欧电位器。两个固定端分别接开发板三点三伏和地,中间滑动端接 A0,也就是芯片 PA0。不要把两端都接电源,也不要把五伏送进这个三点三伏供电的模数输入。三根线的职责各不相同。
原因与结果
电位器内部是一条电阻轨。滑动端把电阻轨分成上下两段,两段分掉三点三伏,所以滑动端得到某个中间电压。芯片里的模数转换器,把零到三点三伏近似分成四千零九十六格;这里用十二位模式作为例子。
完整算例
如果滑动端恰在理想中点,电压约一点六五伏。拿一点六五除以三点三,再乘四千零九十五,约等于二千零四十八。旋钮没发送二千零四十八,是芯片按测得的电压算出读数。这个数字只是计算例子,不是本机实测。
验证与边界
验证时,用万用表量滑动端对地电压,同时看程序打印的采样值。慢慢旋转,两者应该同向变化;若方向反了,只是固定端左右接法相反。实际读数会有误差和噪声,不能保证每次恰好二千零四十八,更不能直接接高于允许范围的电压。
从一根电阻轨到一个数字
电位器两固定端之间约为 10 kΩ;滑动端把电阻轨分成上下两段。按理想分压关系,滑动端靠近 3.3 V 端时电压上升,靠近地端时下降。A0 是开发板连接器名称,真正进入芯片的是 PA0 的 ADC_IN0 功能。模数转换器采的是相对于参考电压的比例,并不是辨认旋钮印在外壳上的角度。如果固定端互换,电压随旋转方向反过来;但依然是同一个分压原理。
一次完整计算
假设参考电压正好是 3.3 V,滑动端恰好是 1.65 V,且选择 12 位转换。12 位有 4096 个可能码值,从 0 到 4095。理想码值约为 1.65÷3.3×4095,得到 2047.5,按舍入约 2048。这个值并非旋钮直接传来的数字,也不是保证每次采样必为 2048。真实参考电压偏差、接触噪声、ADC 量化以及采样设置都会使读数改变。若程序显示大幅异常,先用万用表量滑动端对公共地电压,再查 ADC 通道是否选对。
接线与安全边界
本例用开发板 3.3 V 和 GND,不用 5 V 给滑动端供电。先断电接线,确定电位器哪一脚是滑动端;通电后旋转到两端,滑动端对地电压应在允许范围内变化。若要获得稳定角度而非仅是相对位置,需要考虑电位器的机械行程、线性误差和校准。将几次读数做平均可以减小随机抖动,但不能修复断线、接错线或输入过压。
逐线接线清单
- CN6 3V3 → 电位器固定端 1:3.3 V
- CN6 GND → 电位器固定端 3:公共地
- 电位器滑动端 2 → CN8 A0/PA0:ADC_IN0
计算与实施边界
- 理想中点约 1.65 V,12 位码 1.65/3.3×4095≈2048;计算示例,非实测
这些参数和数值是本例选择或可复算计算;实际测量前,应先检查电源极性、公共地、元件额定值、仪器探头连接。
完整可运行的核心算例与验收
以下 C11 程序可在电脑上用 C 编译器单独编译运行,用来复算状态或数值;它不是已配置 GPIO、ADC、定时器和驱动的开发板固件。移植到实板时应按前述接线配置外设、检查读取错误,并另做实测。
#include<stdio.h>staticunsignedideal_adc_code(floatvolts){if(volts<0.0f)volts=0.0f;if(volts>3.3f)volts=3.3f;return(unsigned)(volts/3.3f*4095.0f+0.5f);}intmain(void){constfloatexamples[]={0.0f,1.65f,3.3f};for(unsignedi=0;i<3;++i)printf("%.2f V -> %u\n",examples[i],ideal_adc_code(examples[i]));return0;}验收时同时记录输入、关键节点电压或波形、程序输出;若发现传感器通信失败、输入超出允许范围或波形明显异常,应停止并排查。
官方资料
- https://www.st.com/resource/en/user_manual/dm00105823.pdf
- https://www.st.com/resource/en/datasheet/dm00088500.pdf