Proteus 8086与LM35温度传感器的实时监控系统设计
1. 项目概述:从零搭建一个8086温度监控系统
大家好,我是老张,在嵌入式系统这块摸爬滚打了十几年,从8位单片机玩到现在的各种ARM内核,但每次带新人入门,我总喜欢让他们从经典的8086和Proteus仿真开始。为啥呢?因为这套组合能让你把计算机组成原理、接口技术、汇编语言这些枯燥的理论,一下子变得看得见、摸得着。今天咱们就来手把手搞一个实时温度监控系统,核心就是8086微处理器和LM35温度传感器,在Proteus这个强大的仿真环境里跑起来。
简单来说,这个项目要干这么几件事:让LM35感知环境温度,把它变成微弱的电压信号;这个模拟信号ADC0808这个“翻译官”听不懂,所以需要ADC0808模数转换芯片把它变成8086能处理的数字信号;最后,8086通过一段精简的汇编程序把数字信号读进来,处理一下,再显示出来。整个过程是实时的,你对着LM35哈口气,显示的数字立马就往上跳,成就感十足。这不仅是微机原理课程的经典实验,更是理解“物理世界”如何与“数字世界”对话的绝佳入门案例。无论你是学生想搞定课设,还是爱好者想重温经典,跟着我的步骤走,保准你能搭出一个能跑、能看、能学的完整系统。
2. 核心器件选型与原理浅析
工欲善其事,必先利其器。在动手画图、写代码之前,咱们得先吃透手里这几个“宝贝疙瘩”的脾气。别被它们的型号吓到,其实原理都很直观。
2.1 感知温度的“神经末梢”:LM35温度传感器
首先出场的是LM35,咱们系统的“感觉器官”。你可以把它想象成一个特别线性的“温度-电压转换器”。它有三个引脚:1脚接电源(VCC,通常是+5V),3脚接地(GND),最关键的是2脚(Vout),它输出的电压直接对应温度。
它的工作公式极其简单:Vout (mV) = 10 × T (°C)。也就是说,温度每升高1摄氏度,输出电压就增加10毫伏。比如,25℃室温下,输出电压就是250mV(0.25V);100℃沸水附近,输出就是1.0V。这种线性关系让后续的计算变得非常简单,不需要复杂的查表或计算补偿。我实测过很多次,LM35的精度和一致性在常规应用中完全够用,关键是它外围电路几乎为零,不用像热敏电阻那样还得配个精密电阻分压,对新手非常友好。
注意:LM35的输出是模拟小信号,非常微弱,也容易受到干扰。所以在实际布线时,传感器到ADC芯片的连线要尽量短,如果实在要拉长线,可以考虑加一个电压跟随器(运算放大器)做缓冲隔离,防止信号衰减。不过在咱们这个仿真项目里,Proteus环境比较理想,直接连就行。
2.2 数字世界的“翻译官”:ADC0808模数转换器
LM35输出的电压是连续变化的模拟量,但8086这位“数字大脑”只认识0和1。这时候就需要ADC0808登场了。它是个8位分辨率的逐次逼近型ADC,有8个模拟输入通道(IN0-IN7),我们只需要用一个。
它的核心参数是参考电压 Vref(+) 和 Vref(-)。ADC输出的数字量 D 和输入电压 Vin 的关系是:D = (Vin - Vref(-)) / (Vref(+) - Vref(-)) × 256。为了计算方便,我们通常将Vref(-)接地(0V)。那么,如何让ADC输出的数字量直接等于温度值呢?这里有个小技巧。
根据LM35的公式 Vin = 0.01 × T (V)。如果我们希望输出数字量D等于温度T,即 D = T,那么代入公式:T = (0.01 × T) / Vref(+) × 256。简化一下,得到 Vref(+) = 2.56 V。没错,只要把ADC0808的Vref(+)引脚接到+2.56V上,那么它转换出来的数字量,就正好是摄氏温度值!比如输入0.25V(25℃),转换结果就是25(十进制)或0x19(十六进制)。这个设计巧思能省去8086内部的大量乘法运算,在汇编编程时尤其方便。
2.3 系统的“大脑”:8086微处理器与地址译码
主角8086是16位微处理器的鼻祖。在Proteus里搭建最小系统,需要接上时钟(CLK)、复位(RESET)电路。数据总线(D0-D7)直接连到ADC0808的输出。关键是如何“选中”ADC0808这片芯片,这就是地址译码的工作。
我常用74LS138这个3-8译码器。8086的地址线A5, A6, A7接到138的输入,它的8个输出端(Y0-Y7)每个都代表一个地址区域,可以当作外围芯片的片选信号。比如,我们假设当A7A6A5 = 000时,Y0输出有效(低电平),并将Y0连接到ADC0808的输出使能端OE(Output Enable)。那么,只要8086访问地址线A7-A5为000的任意地址(例如00h,前提是低位地址线没做其他约束),Y0变低,OE有效,ADC0808的数据就会放到数据总线上,等待8086读取。这种译码方式在8086系统里非常经典,能有效管理多个外设。
3. Proteus仿真电路搭建全攻略
理论懂了,咱们就在Proteus里动手把它连起来。打开Proteus ISIS,新建一个工程。
3.1 元件清单与查找
首先,把需要的元件从库里面找出来:
- 微处理器:在库搜索“8086”,选择
8086模型。 - 温度传感器:搜索“LM35”,选择
LM35。 - 模数转换器:搜索“ADC0808”,选择
ADC0808。 - 地址译码器:搜索“74LS138”,选择
74LS138。 - 锁存器:搜索“74LS373”或“8282”,用于锁存地址,我们这里用
74LS373。 - 时钟与复位:搜索“CRYSTAL”找晶振,搜索“RES”找电阻,“BUTTON”找按钮,用于搭建最小系统。
- 显示器件:为了直观,我们可以用搜索“7SEG”找到七段数码管,比如
7SEG-MPX4-CA(共阳极四位一体数码管)。别忘了还需要一个段码驱动芯片,如74LS47(BCD到7段译码器)。 - 电源与地:在左侧终端模式选择“POWER”和“GROUND”。
- 调试工具:在左侧虚拟仪器模式选择“DC VOLTMETER”(直流电压表),用来观察LM35的输出电压。
3.2 一步步绘制电路图
- 搭建8086最小系统:放置8086、一个晶振(比如10MHz)连接CLK引脚,一个10k电阻和1uF电容构成上电复位电路接到RESET引脚。将8086的MN/MX引脚接高电平(+5V),设置为最小模式。
- 连接LM35:放置LM35,其VCC接+5V,GND接地。输出端Vout先接一个电压表(设置为直流电压档)用于观察,然后这根线就是我们的模拟信号线。
- 配置ADC0808:
- 将LM35的Vout连接到ADC0808的IN7通道(或其他任一通道,比如IN0)。
- 连接地址选择线ADD A, ADD B, ADD C。因为我们用了IN7,对应的二进制地址是111,所以把这三根线都接到高电平(+5V)。
- 设置参考电压:Vref(+)接一个精准的+2.56V电源(可以在Proteus中用“DC”信号源设置),Vref(-)接地。
- 连接时钟CLK:ADC0808需要时钟信号,可以从8086的系统时钟分频得到,或者用一个独立的信号发生器(在Proteus中搜索“CLOCK”)提供,频率典型值500kHz左右。
- 连接数据总线:ADC0808的输出数据线D0-D7直接连接到8086的数据总线D0-D7。
- 控制信号:这是关键!ADC0808的START(启动转换)和ALE(地址锁存使能)可以短接,由同一个信号控制。OE(输出使能)连接74LS138译码器的输出(例如Y0)。EOC(转换结束)信号可以连接到8086的某个可用中断引脚(如INTR),或者我们也可以用查询方式,把它接到数据总线经过缓冲器供8086读取状态。
- 设计地址译码电路:
- 放置74LS138。其使能端G1接高电平,/G2A和/G2B接地,使其始终有效。
- 将8086的地址线A5、A6、A7分别接到74LS138的输入A、B、C。
- 74LS138的输出Y0连接到ADC0808的OE引脚。这样,当8086访问A7A6A5=000的地址空间时,Y0变低,ADC0808的数据被允许输出到总线。
- 添加显示电路:
- 为了显示温度,我们可以把ADC0808输出的数据(已经是温度值)通过锁存器(如74LS373)送到数码管。
- 将8086数据总线经过一片74LS373锁存,锁存器的输出接到74LS47的输入。
- 74LS47的输出驱动共阳极数码管。记得给数码管的公共端接上限流电阻。
- 连接电源与地:确保所有芯片的VCC和GND都正确连接。Proteus中可以用电源终端和地终端批量连接。
画完图,大概的框架就出来了。8086通过地址译码选中ADC,启动转换,等待转换完成,读取数据,然后通过锁存器送到数码管显示。这个过程在软件控制下循环执行,就实现了实时监控。
4. 汇编语言编程:让系统“活”起来
硬件搭好了,是时候注入灵魂——编写8086的汇编程序了。汇编语言直接操作硬件,效率极高,是理解计算机底层运作的必经之路。
4.1 程序流程与核心思路
我们的程序主循环大概是这样:
- 启动转换:向ADC0808的“启动/地址锁存”端口写一个信号(实际上就是访问给它分配的特定地址),告诉它开始转换。
- 等待转换完成:循环查询ADC0808的EOC引脚状态,或者等待它发来的中断信号。这里我们用简单的查询方式。
- 读取数据:转换完成后,通过使能OE(也就是访问我们译码器分配的读地址),将ADC输出的8位温度数据读入8086的寄存器(比如AL)。
- 数据处理与显示:读进来的数据已经是温度值了。我们可以直接将它送到数码管显示端口。如果需要做进一步处理,比如判断是否超温报警,也在这步进行。
- 延时循环:加入一个适当的延时,然后跳回第1步,开始下一次采集。延时太短,显示会闪烁;太长,响应会迟钝。我一般用软件延时循环,调整循环次数来改变采样频率。
4.2 关键代码段详解
假设我们通过译码,将ADC0808的启动/锁存地址定为00h,读数据地址也定为00h(通过同一个片选信号,但用IOR和IOW来区分读和写操作。在8086最小模式下,需要利用IO/M、RD、WR信号来生成IOR和IOW。在Proteus中,我们可以简化,直接使用地址访问来触发)。
; 假设相关地址定义
ADC_START_PORT EQU 00h ; 启动转换的端口地址
ADC_DATA_PORT EQU 00h ; 读取数据的端口地址
DISPLAY_PORT EQU 10h ; 数码管显示锁存器的端口地址
MAIN PROC
MOV AX, @DATA ; 设置数据段(如果用到变量)
MOV DS, AX
READ_LOOP:
; 1. 启动ADC转换
MOV DX, ADC_START_PORT
OUT DX, AL ; 向该端口写任意数据,即可启动转换(ALE和START信号)
; 2. 短暂延时,等待EOC变低(转换开始)
CALL SHORT_DELAY
; 3. 查询等待转换结束 (EOC变高)
WAIT_EOC:
IN AL, DX ; 这里需要根据硬件连接,从特定端口读EOC状态位
AND AL, 80h ; 假设EOC连接数据总线D7位,检查其是否为1
JZ WAIT_EOC ; 如果为0,继续等待
; 4. 转换完成,读取温度数据
MOV DX, ADC_DATA_PORT
IN AL, DX ; 从数据端口读入温度值到AL寄存器
; 5. 送显示 (这里假设直接送原始值到数码管)
MOV DX, DISPLAY_PORT
OUT DX, AL
; 6. 延时一段时间,控制采样频率
CALL LONG_DELAY
JMP READ_LOOP ; 无限循环,持续监控
MAIN ENDP
; 延时子程序
SHORT_DELAY PROC
PUSH CX
MOV CX, 100H
LOOP $
POP CX
RET
SHORT_DELAY ENDP
LONG_DELAY PROC
PUSH CX
MOV CX, 0FFFFH
DELAY_LOOP:
LOOP DELAY_LOOP
POP CX
RET
LONG_DELAY ENDP
这段代码是一个极度简化的框架。在实际项目中,你需要根据具体的硬件连接来调整:
- EOC查询:如果EOC信号没有连接到数据总线,你可能需要通过8255这样的并行接口芯片来读取状态位。
- 显示处理:读进来的二进制数可能需要转换成BCD码,才能驱动74LS47和数码管正确显示十进制数字。这需要编写一个二进制到BCD的转换子程序。
- 中断方式:如果采用中断方式,你需要编写中断服务程序(ISR),并在主程序中设置中断向量表、打开中断。这样效率更高,CPU不用空等。
4.3 调试技巧与常见问题
在Proteus里仿真,调试汇编程序我习惯这么做:
- 源代码编译:用MASM或类似的汇编编译器,将
.ASM文件编译、链接成.EXE文件,再转换成.HEX或.BIN文件。 - 加载程序:在Proteus中双击8086元件,在“Program File”一栏选择你生成的
.HEX文件。 - 运行与观察:点击运行按钮。用鼠标右键点击LM35,可以修改其“Temperature”属性来模拟环境温度变化。观察电压表的读数是否按10mV/℃变化,数码管显示的数字是否与设定温度一致。
- 常见坑点:
- 数码管显示乱码:首先检查74LS47的输入是否是合法的BCD码(0000-1001)。如果不是,需要先进行二进制到BCD的转换。其次检查数码管是共阳还是共阴,驱动电路是否正确。
- ADC读数不准或不变:检查ADC0808的时钟信号是否正常;检查Vref(+)是否为精确的2.56V;检查START和ALE信号是否在读写时有效;检查OE信号是否在读数据时被正确激活(低电平)。
- 程序跑飞:检查8086的复位电路是否可靠;检查汇编程序中的堆栈设置是否正确;在关键跳转后设置断点,单步执行查看程序流向。
5. 功能扩展与实战优化
基础系统跑通后,你就可以在这个骨架上添砖加瓦,把它变得更实用、更强大。这里分享几个我常做的扩展方向。
5.1 添加温度报警与阈值控制
单纯的显示不够,加上报警才像样。硬件上,增加一个蜂鸣器(BUZZER)和一个LED,通过一个简单的驱动电路(如用三极管或74LS06反相器)连接到8086的另一个IO端口上。软件上,在读取温度值后,增加一个比较指令。
; ... 读取温度值到AL后 ...
CMP AL, UPPER_LIMIT ; 与上限值比较,UPPER_LIMIT是一个定义好的常数,比如30
JA TEMP_TOO_HIGH ; 如果高于上限,跳转到报警处理
CMP AL, LOWER_LIMIT ; 与下限值比较
JB TEMP_TOO_LOW ; 如果低于下限,跳转到报警处理
; 温度正常,关闭报警
MOV DX, ALARM_PORT
MOV AL, 00H ; 输出0,关闭蜂鸣器和LED
OUT DX, AL
JMP DISPLAY_TEMP
TEMP_TOO_HIGH:
MOV DX, ALARM_PORT
MOV AL, 01H ; 输出1,打开报警
OUT DX, AL
JMP DISPLAY_TEMP
TEMP_TOO_LOW:
; ... 类似处理 ...
你还可以让报警更有层次,比如温度接近阈值时LED慢闪,超过阈值时LED快闪且蜂鸣器响。
5.2 升级显示界面:从数码管到LCD
四位数码管显示范围有限(0-99℃)。可以换成LCD1602字符液晶,能显示字符和数字,信息量更大。LCD1602通过并行接口与8086连接,需要接数据线(D0-D7)和三条控制线(RS, RW, E)。编程上需要编写LCD初始化、写命令、写数据的子程序。虽然比数码管复杂,但一旦驱动成功,你就可以显示“Temp: 25.6 C”这样的字符串,直观多了。
5.3 实现多通道数据采集与循环显示
ADC0808有8个通道,我们只用了IN7。你可以把其他通道也利用起来,比如接上光敏电阻(测光照)、电位器(模拟其他信号)等。程序上,在每次启动转换前,通过设置ADD A, B, C来选择不同的通道。然后轮流采集各个通道的数据,并在LCD上分屏或滚动显示。这能让你深刻理解多路复用ADC的工作方式。
5.4 引入上位机通信(进阶)
让系统不再是一个信息孤岛。通过给8086扩展一个8251A或8250串行通信芯片,就可以通过串口(在Proteus中用虚拟终端VIRTUAL TERMINAL模拟)将温度数据发送到电脑。你可以在电脑上用串口助手接收数据,甚至用Python、LabVIEW等编写一个简单的上位机软件,绘制温度变化曲线,实现历史数据记录。这一步跨出去,就从单纯的单片机学习,进入了“物联网”的范畴。
6. 总结与项目心得
回顾整个项目,我们从理解LM35、ADC0808、8086每个芯片的数据手册开始,在Proteus里一根线一根线地搭建起硬件电路,再用最底层的汇编语言去指挥它们协同工作,最终让一个温度数字实时地显示出来。这个过程,就是把课本上的“接口技术”、“微机原理”变成了指尖下看得见的逻辑和现象。
我带着很多学生做过这个项目,最常见的困惑不是连线或语法,而是对“时序”和“控制流”的理解。比如,明明代码写了启动转换,为什么读回来的数据总是0?很可能是因为没有等待EOC信号,转换还没结束就去读了。汇编语言强迫你去关注每一个时钟周期,理解CPU如何与外设“握手”。这种训练,是后来使用任何高级语言和复杂框架都替代不了的。
这个基于Proteus的8086温度监控系统,麻雀虽小,五脏俱全。它涵盖了传感器应用、模拟数字转换、微处理器接口、汇编编程、人机交互等嵌入式系统的核心概念。把它吃透,你再去看Arduino、STM32那些用C语言写的库函数,就会明白那些封装好的analogRead()、digitalWrite()背后到底发生了什么。
更多推荐
所有评论(0)