news 2026/3/15 3:19:57

51单片机数字电压表

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
51单片机数字电压表

51单片机的数字电压表(数码管显示)–可提供C程序、proteus仿真、原理图、PCB、元件清单 功能说明 主要由51单片机最小系统、四位共阴数码管、ADC0832模数转换芯片组成。 可测DC5V以内的电压,显示精度为0. 001V

玩单片机的小伙伴应该都想过自己做个电压表吧?今天咱们来搞个简单粗暴的版本——用51单片机+数码管显示的数字电压表。别看这玩意现在满大街都是,自己动手做一遍才能真正理解ADC转换和动态显示的门道。

先说硬件配置:STC89C52单片机打底,四位共阴数码管负责显示,ADC0832扛起模数转换的大旗。整个系统能测0-5V直流电压,显示精度能到小数点后三位。重点是这个分压电路得整明白,输入端用两个精密电阻(建议10k+10k)把被测电压折半,毕竟ADC0832最大只能测5V,这样就能扩展到测10V了(不过咱们程序里会限制在5V显示)。

先看ADC部分的核心代码:

unsigned int Get_AD_Result(uchar channel) { uchar i; uint dat = 0; ADC_CLK = 0; ADC_CS = 0; // 启动信号 ADC_DIO = 1; ADC_CLK = 1; _nop_(); ADC_CLK = 0; _nop_(); ADC_DIO = 1; ADC_CLK = 1; _nop_(); // 选择通道 ADC_CLK = 0; ADC_DIO = channel; // 通道0或1 ADC_CLK = 1; _nop_(); ADC_CLK = 0; _nop_(); ADC_DIO = !channel; ADC_CLK = 1; _nop_(); // 读取数据 for(i=0; i<8; i++) { ADC_CLK = 1; _nop_(); ADC_CLK = 0; _nop_(); dat <<= 1; if(ADC_DIO) dat |= 0x01; } ADC_CS = 1; return dat; }

这段代码有几个关键点:首先通过CLK和DIO线的配合发送启动脉冲,然后配置通道选择(单端输入时要注意高低电平组合)。重点在数据读取环节——ADC0832是MSB先出的,所以每次循环都要先左移再按位或。注意nop()的延时不能省,这个空操作保证了时序的准确性。

数码管显示部分采用经典的动态扫描方式,这里有个小技巧:用定时器中断做扫描比死循环更靠谱。看这个中断服务函数:

void Timer0() interrupt 1 { static uchar pos = 0; TH0 = 0xFC; // 1ms定时 TL0 = 0x66; P0 = 0xFF; // 消隐 switch(pos) { case 0: P2 = 0x01; P0 = LedChar[volt[0]]; break; // 个位 case 1: P2 = 0x02; P0 = LedChar[volt[1]] | 0x80; break; // 十位带小数点 case 2: P2 = 0x04; P0 = LedChar[volt[2]]; break; // 百位 case 3: P2 = 0x08; P0 = LedChar[volt[3]]; break; // 千位 } if(++pos >=4 ) pos = 0; }

这里有几个注意点:每次切换位选前先给P0口送0xFF做消隐,防止鬼影。小数点处理很有意思——直接在段码数据上或0x80(对应DP段)。定时器配置成1ms中断一次,这样四位扫描周期是4ms,刷新率250Hz,完全不会有闪烁感。

校准环节才是真正的玄学现场。假设ADC参考电压是精准的5V,那理论计算应该是:

实际电压 = (ADC值 / 255)5.02 // 乘2是因为分压电路

但现实中的参考电压可能有偏差,这时候就要上可调电源实测。比如输入3.000V时显示2.985V,就需要在程序里加个校准系数:实际电压 = 原始计算值 * 1.005

Proteus仿真时有个坑——ADC0832模型对时序要求比真实芯片更严格。如果发现转换结果不对,试着把ADCCLK的翻转速度调慢点,加几个nop_()试试。另外数码管共阴/共阳属性要和原理图严格对应,不然要么不亮要么全亮。

最后上电测试时如果发现测量值跳变严重,可以在软件里加个滑动平均滤波:

#define FILTER_LEN 8 uint adc_buf[FILTER_LEN]; uint filter_adc() { static uchar index = 0; uint sum = 0; adc_buf[index++] = Get_AD_Result(0); if(index >= FILTER_LEN) index = 0; for(uchar i=0; i<FILTER_LEN; i++) { sum += adc_buf[i]; } return sum / FILTER_LEN; }

这个环形缓冲区滤波算法能有效平滑数据,又不占用太多内存。实测发现滤波次数8次左右效果最佳,既不会明显滞后又能滤除大部分毛刺。

整个项目做下来,最深的体会是:硬件电路要干净,数字地模拟地分开走线;软件算法要稳健,该有的滤波校准不能少。源码包里已经准备好了带详细注释的程序、仿真文件和PCB工程,拿走不谢!

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

vue3生成的word中图片是空白

问题分析在Vue3项目中生成Word文档时出现图片空白的情况&#xff0c;通常是由于图片处理方式不当或文档生成工具的限制导致的。常见原因包括&#xff1a;图片路径问题、异步加载未完成、Base64编码错误或Word生成库对图片的支持不足。解决方案检查图片路径和加载状态 确保图片路…

作者头像 李华
网站建设 2026/3/11 5:41:27

为什么联合索引会优先使用前导字段,而不是非前导字段

好的&#xff01;我们用通俗的例子和索引的底层原理来解释为什么优化器会优先使用联合索引的前导字段&#xff08;即联合索引的第一个字段&#xff09;&#xff0c;以及为什么这种设计更高效。一、索引的底层结构&#xff1a;B树数据库索引&#xff08;如InnoDB的B树索引&#…

作者头像 李华
网站建设 2026/3/14 19:39:52

华为HiSuite评测:功能、优点、缺点及最佳替代方案

华为HiSuite是华为官方开发的桌面管理工具&#xff0c;旨在帮助用户在电脑上管理华为手机。借助它&#xff0c;您可以备份数据、恢复文件、更新系统软件以及在手机和电脑之间传输内容。但华为HiSuite真的容易上手吗&#xff1f;它是否支持用户关心的所有数据类型&#xff1f;如…

作者头像 李华
网站建设 2026/3/12 15:36:35

风光储并网发电系统仿真模型 共直流母线式风光储:风力发电+光伏发电+储能+三相逆变并网 ①光伏...

风光储并网发电系统仿真模型 共直流母线式风光储&#xff1a;风力发电光伏发电储能三相逆变并网 ①光伏Boost:采用电导增量法来实现光伏板最大功率跟踪 ②风机&#xff1a;拓扑采用三相整流电路&#xff0c;控制采用MPPT控制 ③蓄电池储能&#xff1a;采用双向Buck_Boost电路&a…

作者头像 李华
网站建设 2026/3/11 18:06:24

调研分享 | 面向异构集群环境的分布式训练并行方案调研

大规模的神经网络模型需要依托分布式集群环境完成载入和训练。技术演进不仅让模型规模膨胀&#xff0c;支撑算力的硬件也迭代升级&#xff0c;如何充分利用异构算力将成为难题。调研分享在异构集群下并行训练的近期研究。 1 模型分布式训练的并行策略 训练神经网络模型就像是在…

作者头像 李华
网站建设 2026/3/13 3:13:12

正弦波高频注入仿真模型

正弦波高频注入仿真模型最近在研究正弦波高频注入的仿真模型&#xff0c;感觉这东西挺有意思的。高频注入技术在很多领域都有应用&#xff0c;比如电机控制、电力系统等。今天就来聊聊怎么用Python实现一个简单的正弦波高频注入仿真模型。首先&#xff0c;我们需要生成一个正弦…

作者头像 李华