51单片机课程设计实战:基于HX711与DS18B20的体重体温秤全解析
简介本资源是一套完整的基于51单片机的智能体重秤设计开发包面向嵌入式初学者、课程设计学生及电子竞赛备赛者解决多传感器数据采集、存储与人机交互显示等典型单片机应用问题。资源包含65个文件涵盖Proteus仿真工程.pdsprj、Keil源码工程.uvproj/.c/.h/.hex、原理图.SchDoc/PDF、系统流程图与模块流程图.bmp、元件清单.xls、功能说明文档.pdf及演示视频.mp4其中C语言源码含HX711体重传感、DS18B20体温采集、AMPIRE12864液晶驱动等核心模块支持3组数据本地存储与按键查询。压缩包大小为23.87MB结构清晰、模块解耦便于理解软硬件协同逻辑与调试要点。目前已有188人学习下载配套演示视频与多张界面截图直观呈现测量、存储、查询全流程显著降低实物调试门槛特别适合教学实践与毕业设计参考。 又到课程设计季。这两天好几个朋友在问我要“51单片机课设题库”我翻U盘的时候正好看到一个老项目编号1537的“基于51单片机的体重秤”带体重和体温双测量、12864液晶显示Proteus仿真、原理图、流程图、物料清单、仿真图、源代码全套都在。我仔细扫了一遍代码和仿真工程觉得这个项目很适合当作“一个单片机小系统该怎么串起来”的完整范例所以干脆把整个项目从方案到实物复盘的思路写出来给你做一个可以直接参考的底稿。这个项目表面上不复杂就是称重加上测温再加个显示。但真正动手之后你会发现称重牵扯到传感器小信号采集、ADC标定和滤波体温牵扯到传感器精度、单总线时序和测量部位的现实约束12864牵扯到并口串口选择和汉字显示初始化Proteus仿真又有自己的一套“理想化环境”陷阱。任何一个环节没想清楚出来的东西不是读数乱跳就是温度夸张要么就是直接在仿真里跑不通。下面我从方案选型开始把硬件、软件、仿真、物料和实物移植全部分开讲重点放在“为什么这么做”而不是单纯罗列代码。1. 项目拆解与技术方案选型51单片机做体重秤到底行不行1.1 需求拆解体重、体温、显示三件事的核心难点先把题目翻译成人话你要做一个设备人站上去能显示体重把测温探头夹在腋下或者放在额头能显示体温所有数据通过一块12864液晶屏展示出来最好还能去皮、有开机界面、能提示状态。听起来是三个功能实际上拆开之后是三条完全不同的技术链路体重链称重传感器输出的是毫伏级的差分电压必须经过仪表放大器放大、高精度ADC采样再经过软件标定才能变成“公斤”。这里的难点不是单片机而是小信号处理和标定。体温链温度传感器要么是数字单总线要么是NTC热敏电阻模拟量。难点在传感器本身的精度、采样稳定性和测量部位的合理性。很多人上来只写驱动忽略了“测出来的温度到底准不准”这件事结果温度永远是36.5℃或者39.8℃一看就是没校准。显示链12864要初始化、要管理DDRAM/GDRAM要显示汉字和ASCII混排。难点在于初始化时序和串行/并行模式的选择以及显示刷新和采样之间的节奏配合。把三条链路合到一个51里面难点反而变成“单片机资源怎么分配”定时器给谁用、采样要不要中断、显示刷新会不会卡住主循环、按键扫描什么时候做。这些才是真正有价值的设计决策。1.2 核心器件选型为什么是5112864HX711DS18B20先说结论这套选型放在今天不是性能最优解但是教学和课程设计场景下性价比最高的组合。51单片机STC89C52RC或者AT89C52都行8KB Flash、512字节RAM2个定时器、1个串口。做这个项目不超频、不加外部扩展刚刚好够用。选它的另外一个理由是资料多、Proteus模型成熟出问题容易查。12864液晶这里说的12864指的是带ST7920控制器的中文字库屏不是纯点阵驱动的那种。带中文字库意味着可以直接往DDRAM写GB2312汉字内码不需要自己做字模。这是它比1602强的地方显示“体重”“体温”“去皮成功”这些中文提示词非常方便。HX711重量采样不选ADC0832、不选PCF8591因为称重传感器的输出是差分毫伏信号普通ADC根本没有那么高的分辨率和输入调理。HX711集成了低噪声放大器、24位Σ-Δ ADC还有专门针对电桥传感器的时钟逻辑几块钱一片是低成本称重方案的事实标准。DS18B20温度采样用数字传感器主要是省掉了模拟采样和查表标定。单总线协议自己写一遍也不难代码量不大。但它的精度只有±0.5℃这个后面我会专门讲怎么补救。组合起来单片机负责逻辑HX711负责小信号采样DS18B20负责温度12864负责交互四个器件各管一摊互不干扰。硬件连线不多代码结构也很好拆。1.3 Proteus在这个项目里的角色仿真图的边界在哪里Proteus在这个项目里最大的价值不是让你“假装做了实物”而是让你在不用焊板子、不用买传感器的情况下先把整个系统逻辑跑通。它适合验证三件事单片机程序逻辑有没有明显bug比如会不会死循环、按键扫描有没有冲突、12864能不能正常显示。接口时序在默认配置下能不能工作比如HX711的SCK脉冲宽度、DS18B20的单总线时序。系统级的联调流程比如上电之后传感器采样、温度采样、显示的先后顺序。但Proteus的仿真环境是“理想化”的传感器不会飘零、电源没有纹波、不会有人真的站上去产生机械形变、DS18B20模型的温度你双击就能改。所以仿真图只能作为教学演示和逻辑验证绝对不等于实物能跑出同样效果。做实物时你需要面对的是噪声、应力、接触电阻、探头贴合度这些“脏活”。这一点心知肚明就好。2. 硬件电路设计称重、体温、显示三者如何接进512.1 称重通道悬臂梁传感器与HX711的完整信号链路称重传感器最常见的形态是悬臂梁式量程5kg、10kg都有多数模块会标“1mV/V”灵敏度。意思是你给它1V供电满量程时输出能力是1mV如果给它5V供电满量程输出就是5mV。实际没有重物时输出会在零位附近加载后差分电压线性增加。5mV是什么概念单片机自带ADC参考电压通常是5V哪怕有10位分辨率1个LSB也接近5mV直接采完全没意义。所以必须靠HX711HX711内置可编程增益放大器A通道可选64倍或128倍增益项目里一般用128倍。128倍增益后满量程5mV变成640mV。HX711内部不用传统的VREF引脚而是用带隙基准配合模块上的电阻网络典型的模拟参考电压约4.3V24位ADC的分辨率远超过这个场景的需求。接线方面称重传感器引出四根线通常颜色是传感器引线颜色接HX711模块电源正红E电源负黑E-信号正绿或白A信号负白或绿A-如果信号正负接反读出来的数据会往反方向走或者显示负数这个在上电测试时要先确认。HX711和51之间只需要两根线DOUT和SCK。SCK送脉冲DOUT输出数据。注意HX711模块的数字电源VDD、模拟电源AVDD要配好大多数模块自带稳压可以直接给5V但如果你手里的模块没有稳压就要严格把AVDD控制在芯片允许范围内不然读数会非常飘。2.2 体温通道DS18B20与NTC两种方案的取舍体温采集有两条路线。项目资料里常见的是DS18B20因为它只有三根线VCC、GND、DQDQ上拉4.7kΩ电阻到VCC接线极简。驱动时序分初始化、写数据、读数据三步数据格式是12位温度值分辨率0.0625℃读取后乘0.0625就是实际温度。但这里必须说清楚一个现实问题DS18B20的标称精度是±0.5℃而医用级体温计通常要求±0.1℃。如果你真拿它测体温读数会“看起来有零有整”却不一定对。课程设计里可以接受因为老师更关注系统功能完整性和代码逻辑但我建议程序里做一个两点校准把探头放冰水混合物记录当前读数和实际0℃的偏差。把探头放恒温水浴或者用一只医用体温计做参照记录另一个点的偏差。程序里做线性校正把整个温度区间拉平。这样做完误差能压到±0.2℃左右做一个桌面健康设备是够用的。如果你要求更高可以考虑NTC热敏电阻10kΩ B3950加分压电路再用单片机ADC采样配Steinhart-Hart方程或者查表拟合。NTC方案成本更低但电路多一个分压网络和一个电容滤波软件也要处理非线性对初学者不友好。所以我建议先按DS18B20做通后续再提高精度。体温测量的另一个坑是“接触稳定”。DS18B20探头往腋下一夹要等几十秒读数才稳定如果只放一两秒就刷新显示数字会一直缓慢往上爬你的第一反应往往是“传感器坏了”其实只是传热没到位。软件里要加一个“测温中”的提示状态连续几次读取差值小于阈值再显示最终结果。2.3 12864显示接口并行模式与串行模式的工程选择12864的ST7920控制器支持8位并行、4位并行、串行三种模式。很多初学者一上来就接8位并行DB0到DB7加上RS、RW、E一共11根线接线又多又容易错。其实这个项目数据量不大完全可以用串行模式只需要五根线12864引脚作用接51CS片选P1.2SIDMOSI串行数据P1.3SCLK串行时钟P1.4A0RS寄存器选择P1.5RST复位接复位电路或P1.6PSB引脚必须拉低表示进入串行模式如果悬空或拉高屏幕可能不显示。这个是最容易踩的硬件坑。选串行模式还有一个好处省下来的IO口可以给按键、蜂鸣器、DS18B20用。51本身IO资源紧张这个项目里传感器加显示一接IO口就差不多了布局时要有预算意识。2.4 最小系统、电源和复位电路的规范化处理无论仿真还是实物单片机最小系统都不能省11.0592MHz晶振配两个30pF负载电容复位电路用10kΩ电阻加10μF电容VCC和GND之间加上0.1μF去耦电容。这些在原理图上看起来不起眼却是系统稳定的基础。电源方面如果整个系统用一个USB 5V供电注意两点HX711和称重传感器最好用同一路经过稳压后的干净电源不要在HX711电源上并电机、继电器这类大电流负载。体温探头和单片机数字电路可以共用5V但探头线长时建议在探头VCC和GND之间加一个0.1μF电容抑制线缆引入的干扰。实物的电源地线最好做单点接地传感器和单片机各自回原点而不是串成一条长地线否则你会发现称重读数跟着温度数据跳动这就是地线噪声在作怪。3. 软件核心逻辑从ADC原始值到“斤两”和“摄氏度”3.1 HX711驱动时序24位数据的读取与补码处理HX711的数据手册时序非常清晰读一次24位数据的过程是DOUT在数据准备好后自动拉低。单片机检测到DOUT为低开始在SCK上发出25个脉冲。前24个脉冲每个上升沿读出一位数据从最高位到最低位。第25个脉冲让芯片进入下一次转换。核心读取函数直接照这个逻辑写sbit HX711_DOUT P2^0; sbit HX711_SCK P2^1; unsigned long HX711_Read(void) { unsigned long value 0; unsigned char i; HX711_SCK 0; while(HX711_DOUT); // 等待DOUT拉低表示数据就绪 for(i 0; i 24; i) { HX711_SCK 1; value value 1; HX711_SCK 0; if(HX711_DOUT) value; } HX711_SCK 1; // 第25个脉冲 HX711_SCK 0; return value; }注意一个细节HX711输出的是24位二进制补码。直接拿unsigned long去算重量会出错必须把最高位判断一下扩展成有符号数long HX711_GetRaw(void) { unsigned long val HX711_Read(); long result; if(val 0x800000) result (long)(val | 0xFF000000); // 符号扩展为32位 else result (long)(val 0x00FFFFFF); return result; }至于为什么要“while(HX711_DOUT)”等数据就绪是因为HX711的更新速率默认不高尤其是低增益档位下可能每隔几十毫秒才完成一次转换。不等待直接读前几位会读到无效数据。3.2 称重标定与滤波两点标定法加去极值平均单片机读到的原始值本身没有物理意义它只是一个和传感器受力呈线性关系的整数。要变成“公斤”必须做标定。最常见的做法是两点标定法第一步空秤时连续读取N次取平均值作为零点偏移zero_offset。第二步放一个已知重量的标准砝码比如2kg读取当前平均值为std_raw于是每公斤对应的计数增量是float scale (float)(std_raw - zero_offset) / 2.0f;第三步任意时刻的重量计算公式weight (float)(raw_value - zero_offset) / scale;这里要提醒一点不要把scale放到除法分母时又丢符号。如果传感器信号接反了raw_value会比zero_offset小算出来的重量是负数。此时不是改标定系数而是要回到硬件检查A和A-是不是接反了。滤波是第二条命脉。HX711虽然分辨率高但传感器受机械振动和人体站姿影响读数会在一个小范围内跳动。直接显示这个值会非常“神经质”。我用的是去极值平均滤波连续采样8次去掉最大值和最小值。剩余6次取平均作为本次显示值。写成一个函数就是long get_filtered_raw(void) { unsigned char i, j; long buf[8]; long sum 0; long max, min; for(i 0; i 8; i) buf[i] HX711_GetRaw(); max buf[0]; min buf[0]; for(i 1; i 8; i) { if(buf[i] max) max buf[i]; if(buf[i] min) min buf[i]; } for(i 0; i 8; i) { if(buf[i] ! max buf[i] ! min) sum buf[i]; } return sum / 6; }这个滤波在单片机上的开销非常小但效果明显。千万别省尤其当你做实物时人站上去的那一瞬间传感器读数会有很大冲击滤波能帮你稳住显示。3.3 DS18B20单总线驱动要点与体温精度校准DS18B20的驱动是整个项目里最考验时序精确度的部分。单总线协议要求严格的时间槽初始化、写0、写1、读位都有固定的延时窗口CPU主频不同延时参数都要对应调整。下面是一个标准的读取温度流程主机发送复位脉冲拉低至少480μs释放后等待60μs。DS18B20会拉低总线60~240μs作为存在脉冲主机检测到就说明设备在线。发送跳过ROM命令0xCC。发送启动温度转换命令0x44芯片转换时间默认约750ms期间可以去做显示刷新。再次复位发送跳过ROM发送读暂存器命令0xBE。连续读取低字节和高字节拼接成16位数据。温度换算代码float DS18B20_GetTemperature(void) { unsigned char low, high; short temp; float result; DS18B20_Reset(); DS18B20_WriteByte(0xCC); DS18B20_WriteByte(0x44); // 启动温度转换 DS18B20_Reset(); DS18B20_WriteByte(0xCC); DS18B20_WriteByte(0xBE); // 读暂存器 low DS18B20_ReadByte(); high DS18B20_ReadByte(); temp (high 8) | low; result temp * 0.0625f; return result; }如果你要做两点校准可以在main里加两个全局变量cal_offset补偿固定偏差。cal_ratio补偿线性误差。显示前先对结果做一次校正t_display (t_raw - cal_base) * cal_ratio cal_base cal_offset;其中cal_base是校准时的参考温度点。这种校准方式不算严格但对这个项目级别来说已经足够实用了。3.4 主程序流程与状态机流程图如何落地成代码项目的流程图可以概括为系统上电初始化定时器、12864、HX711、DS18B20。显示开机界面等待2秒。进入主循环按键扫描检测去皮键、标定键。重量采样读取HX711并滤波减去零点偏移换算成公斤。温度采样如果距离上次温度转换完成已超过750ms读取新温度。显示刷新更新12864上的体重和体温数字。状态判断超重或温度异常时蜂鸣器提示。这里不建议把全部代码塞在一个大while里最好拆成几个函数每个函数只干一件事。比如主循环里写成void main(void) { System_Init(); while(1) { Key_Scan(); Weight_Update(); Temperature_Update(); Display_Update(); } }每个函数内部自己管理标志位比如Weight_Update里判断“采样到滤波到显示”的周期Temperature_Update里判断“上一次温度转换是否完成”。这样逻辑不会绞在一起出问题也好排查。4. Proteus仿真搭建实录元件库、接线与三个绕不开的坑4.1 元件查找与放置Proteus里的51、12864、DS18B20打开Proteus 8 Professional新建工程后在元件模式里搜索AT89C52或STC89C52我用的是AT89C52功能兼容。12864液晶Proteus里常见的模型是AMPIRE128X64也是ST7920控制器引脚定义和实物模块基本一致。DS18B20直接搜DS18B20就能找到双击模型可以修改温度数值用来模拟体温变化非常方便。还需要电阻、电容、按键、晶振这些在元件库里直接搜RES、CAP、BUTTON、CRYSTAL。12864模型仿真时要注意PSB引脚必须接地设置为串行模式否则你用串行协议驱动它屏幕没有任何反应。4.2 HX711在仿真里的替代方案与电压模拟Proteus新版本元件库里可能没有HX711或者各版本封装名称不一致。如果你搜不到我建议不要卡在这上面直接换一种仿真思路用两个电位器POT-HG模拟称重传感器的差分输出分别接HX711的A和A-。如果连HX711模型都没有就用ADC0832或PCF8591配合变阻器把电阻分压电压读进来软件里按ADC值来做标定演示。这个替代方案在逻辑上等价你验证的其实是“采样→标定→显示”这条软件链路而不是HX711具体芯片的时序。等实物阶段再换回HX711驱动程序就行。如果你一定要在仿真里跑真实HX711时序可以尝试在Proteus的“Pick Devices”里搜HX711部分Proteus 8.9以上版本确实有模型但行为模型和真实芯片在时序边界上会有差别。遇到这种情况别死磕用替代方案反而效率更高。4.3 仿真阶段最容易被卡住的三个问题第一个是12864中文乱码或黑屏。Proteus里AMPIRE128X64模型默认支持ST7920中文字库但有的版本模型不完整写中文字符串会出现乱码。遇到这种情况先切换到英文/ASCII显示测试比如显示“Weight:”和“Temp:”如果英文正常说明指令没有问题是模型字库支持的问题不影响实物代码。第二个是DS18B20在仿真里温度改不动。修改DS18B20模型属性里的温度值后要重新运行仿真或重新上电温度变化才会生效。很多人双击改了温度发现屏幕不变其实是仿真进程还在用旧数据跑。第三个是仿真速度太慢导致DS18B20时序超时。Proteus仿真速度受CPU性能影响如果你在仿真里用了精确的750ms转换等待可能会卡到怀疑人生。仿真调试阶段可以临时把转换等待时间缩短到50ms、100ms先验证显示逻辑换到实物再改回真实延时。5. 物料清单与实物移植从仿真图到真实硬件的经验5.1 BOM明细与采购注意事项如果看完前面的内容你打算把这套东西做成实物下面的物料清单可以直接照单买。大部分东西在开发板上都有现成的单独采购也很便宜整套下来几十块钱。序号物料名称型号/规格数量备注1单片机STC89C52RC1DIP40封装可烧录2晶振11.0592MHz1无源晶振即可3电容30pF2晶振负载电容4电容10uF/16V1复位电路电容5电阻10kΩ1复位电阻6电阻4.7kΩ1DS18B20上拉7称重传感器5kg悬臂梁1注意四线颜色定义8称重ADC模块HX7111带稳压和晶振的成品模块9温度传感器DS18B201TO-92封装10液晶屏12864带中文字库1ST7920控制器11按键轻触开关2去皮、功能切换12蜂鸣器5V有源1可选超重或温度异常报警13电源USB 5V供电模块1优选带稳压输出采购时最容易踩的坑有两个称重传感器最好买“HX711模块传感器”套装模块已经做好信号调理和供电稳压你只需要接四根线和两根数据线比裸芯片自己搭外围电路省太多事。12864要选“带中文字库”的版本如果你买到的是纯点阵屏比如KS0108控制器那代码逻辑完全不同项目里的驱动是ST7920专用不能直接套。5.2 实物调试与仿真差异电源噪声、机械应力、接触稳定仿真跑通之后做实物很多问题才会浮出来。我最常遇到的有三类第一类是重量读数漂移。刚上电时读数稳定过几分钟慢慢变重或者每天开机零点都不一样。这多半是传感器自身的温度漂移和机械应力没有稳定下来。解决方法上电后等1~2秒再开始采样把零点标定放到稳定之后传感器安装要平整四个螺丝不要拧得有一侧特别紧否则底座带着应变梁变形零点一定飘。第二类是HX711读数跳动。按键按下或者温度探头插拔时重量数字跟着跳。这是地线串扰。仿真里完全不会出现实物上要检查电源走线确保HX711和传感器供电不要和蜂鸣器、继电器共用一根细导线。如果实在改不了布局就在HX711的电源引脚附近加一个100μF电解电容和0.1μF瓷片电容。第三类是体温读数慢半拍。DS18B20从空气换到皮肤表面温度爬升需要时间显示那个小数一直在跳看起来就不专业。解决办法不是说它坏了而是在软件里加“连续三次温度变化小于0.1℃再刷新显示”的稳定逻辑。给用户一个“测量中”的状态几秒后给一个尘埃落定的结果体验感会好很多。5.3 扩展方向蓝牙上传、语音播报、低功耗设计这套东西往上扩展的空间非常大结构上也很清晰加蓝牙把单片机串口接一个HC-05模块定时把体重、体温结构体通过串口发送给手机APP就是一个小型健康管理终端。加语音播报接一个SYN6288或SU-03T语音合成模块测量完成后直接播报“您的体重是六十五点二公斤体温三十六点五度”解决老人看屏幕费劲的问题。加低功耗STC89C52本身功耗不低如果你想做电池版本可以换成STC15系列或STC8系列再用HX711的掉电模式和DS18B20的待机模式每隔几秒唤醒一次采样平时休眠待机电流可以压到毫安级别。加更准的测温如果对体温精度实在不满意换成MLX90614红外测温模块非接触也能测而且精度可以到±0.1℃级别只是成本高一些。我在实际做这个项目的过程中体会最深的是读数是靠标定准的不是靠硬件堆出来的。很多人一上来就想着换传感器、换ADC、换更大屏其实真正影响体验的是标定流程和滤波策略。代码逻辑跑通了仿真图能转了先把这两个细节做好这套系统就能拿出一个挺像样的效果。祝顺利。本文还有配套的精品资源点击获取

相关新闻