简介:基于51单片机与Proteus仿真的热敏电阻温度计设计系统,面向电子类专业学生、嵌入式初学者及仿真爱好者,用于掌握热敏电阻PT100的采集转换、ADC数据处理及数码管显示等完整流程。系统以51单片机为主控,配合PT100热敏电阻和ADC采集芯片,将模拟温度信号转换为数字信号,并通过数码管实时显示温度值。整套设计包含Proteus仿真工程、51单片机C语言与汇编源代码、Hex烧录文件及编译中间文件,共24个文件,压缩包仅372KB,轻量紧凑,便于下载与本地运行。仿真图与源代码相互对应,读者可先打开仿真工程观察电路连接,再结合C语言源代码理解温度采集到显示的实现思路;ADC芯片选型、PT100转换电路等关键环节均在工程中有直观呈现。目前已有161人学习,适合课程设计、毕业设计参考或入门单片机测温项目实践,也便于课堂演示与自主实验。
1. 51单片机热敏电阻温度计仿真与源码:先跑通电路再谈测温准不准
很多做过51课设的人都有这种翻车经历:NTC热敏电阻、分压电阻、ADC芯片买了一大堆,焊好板子一上电,LCD要么黑屏要么温度显示一个离谱的值,最后查来查去是分压电阻选型不对或者ADC时序写错。这套基于51单片机+proteus仿真的热敏电阻温度计设计系统,把整个测温链路——热敏电阻分压、ADC0809采集、单片机换算、LCD1602显示——全部在proteus里跑通,配套仿真图和源代码一起打包。它的价值在于:你不用先买元器件、不用焊接,就能在电脑上把电路和程序验证一遍,确定没问题了再动手做实物。适合做课设的学生、刚入门51想完整走一遍模拟采集链路的爱好者,以及被DS18B20这类数字传感器“黑匣子”搞烦了、想真正搞懂电阻测温原理的从业者。
2. 热敏电阻测温原理与器件选型:B值公式、分压电路与ADC精度
2.1 NTC阻值和温度什么关系:B值公式与分压采样
NTC是负温度系数热敏电阻,温度升高、阻值下降。最常用的型号是25℃时阻值10kΩ、B值3950的NTC,资源包里的仿真和代码基本都按这个参数来设计。阻值与温度的数学关系可以用B值公式描述:
R(T) = R25 × exp(B × (1/T - 1/T25))
其中R25是25℃时的标称阻值,T和T25都用开尔文温度。这个公式看着复杂,但实际用的时候只需要做一次浮点运算,Keil C51的math.h库提供了自然对数函数log(),可以直接解出温度。
单片机不能直接测电阻,得先把电阻变化转成电压变化,常见做法是分压电路:一个固定电阻R_FIXED(10kΩ)做上拉接VCC,NTC做下臂接地,中间节点接ADC输入。分压点电压为:
Vout = VCC × R_NTC / (R_FIXED + R_NTC)
温度升高→NTC阻值下降→Vout下降,ADC读到的数值随之变小,程序里再反解出NTC阻值、代入B值公式算出温度。这个链路的关键参数是R_FIXED的取值,它决定了测温量程内分压曲线的线性度。10kΩ的NTC配10kΩ固定电阻,在0~50℃区间内电压变化比较大,ADC分辨率利用得也最好。如果换上20kΩ固定电阻,高温段电压变化会变缓,整条曲线往低温方向偏,实际调试时不要随便换固定电阻,换了就得重新标定。
2.2 为什么用NTC+51+ADC0809:与DS18B20、PT100的对比
很多新手会问:为什么不直接用DS18B20?它单总线、数字输出、程序还好写。答案在于教学目标和项目定位。DS18B20内部已经把测温电路封装好了,仿真里你只能看到一个器件,温度数据从一条线上读出来,整个模拟前端对你完全是黑匣子,做完这个项目你对电阻测温还是一无所知。而这套设计用的是NTC+ADC0809,从敏感元件、分压电路到逐次逼近型ADC,每个环节都能在proteus里看到波形和数值,这才是课设和毕设真正要考察的能力点。
三种方案的实际对比:
| 方案 | 测温原理 | 精度 | 电路复杂度 | 仿真教学价值 | 成本 |
|---|---|---|---|---|---|
| NTC+ADC0809 | 分压+AD采集+软件换算 | 1℃左右 | 中 | 高,链路完整可见 | 低 |
| DS18B20 | 内部集成测温+单总线 | 0.5℃ | 低 | 低,黑匣子 | 低 |
| PT100+运放 | 电桥+仪表放大器+AD | 0.1℃ | 高 | 高但门槛高 | 较高 |
标准51单片机内部没有ADC,所以这套设计外扩了ADC0809,8位、8通道、逐次逼近型。8位分辨率对应256个量化等级,5V参考电压下每档约19.6mV。对10kΩ NTC来说,在室温附近每1℃大约对应几十毫伏变化,8位精度能分辨到1℃左右,用来做温度计和温控演示完全够用。ADC0809在proteus里的模型很成熟,仿真行为跟真实芯片基本一致,这也是它大量出现在课设里的原因。
3. 在proteus里搭这套温度计电路:元件查找、接线表与电位器模拟NTC
3.1 元件清单与proteus搜索关键字
打开proteus,第一步是找元件。这块有个最常见的翻车点:proteus元件库里的命名跟教材不完全一样,比如LCD1602在库里叫LM016L,很多人输LCD1602搜不到就开始怀疑库没装全。下面是这套电路用到的元件和准确的搜索关键字:
| 元件 | proteus搜索关键字 | 说明 |
|---|---|---|
| 单片机 | AT89C51 | 也可以用AT89C52,引脚兼容 |
| 模数转换器 | ADC0809 | 8位8通道逐次逼近型ADC |
| LCD | LM016L | proteus里的LCD1602 |
| 热敏电阻模拟件 | POT-HG | 用可调电阻模拟NTC阻值变化 |
| 固定电阻 | RES | 10kΩ×1、1kΩ×1等 |
| 排阻 | RESPACK-8 | P0口上拉,必须加 |
| 晶振 | CRYSTAL | 12MHz |
| 电容 | CAP | 33pF×2,复位用10uF电解电容 |
| 电源 | POWER/VCC、GROUND | 仿真里直接放5V电源符号 |
POT-HG是proteus里的可调电阻,仿真运行中可以手动调节阻值。用它代替NTC的核心逻辑是:单片机和ADC根本不知道你接的是热敏电阻还是电位器,它们只看到一个随“温度”变化的电压值。你转动电位器,分压节点的电压就变化,ADC读数跟着变,LCD上的温度数字自然变化。这正是仿真这种传感器系统时最常用的手段,比在proteus里纠结怎么构造一个温度场环境要实际得多。
提示:proteus里找不到LM016L时,检查一下元件库关键字的大小写,或者直接输入“LM016L”,不要输“LCD1602”。新版proteus 8.x的元件库比老版本全,但命名习惯没变。
3.2 接线步骤与关键参数设定
这套电路的接线逻辑分四块:NTC模拟分压、ADC0809、LCD1602、单片机最小系统。下面把每一块的连接关系列清楚,照着接基本不会错。
第一块是NTC模拟分压。VCC接10kΩ固定电阻一端,电阻另一端接POT-HG的一个固定端,POT-HG的滑动端接GND,另一个固定端悬空。这样固定电阻和电位器就构成了一个串联分压支路,分压节点在电阻与电位器相连的那个点。调节电位器阻值,节点电压在0到接近5V之间变化。这个节点接到ADC0809的IN0通道。
第二块是ADC0809。VREF+接VCC(5V),VREF-接GND,IN0接分压节点。时钟CLK接DCLOCK信号源,设500kHz。数据线D0-D7接单片机P1口。START、EOC、OE分别接P3.3、P3.4、P3.5。通道选择A/B/C三脚可以一起接地,固定使用IN0通道,代码里把通道号写死。如果要预留多通道,可以把A/B/C接到P2.3-P2.5,由程序控制选通道。
第三块是LCD1602。数据线D0-D7接P0口,同时P0口必须接RESPACK-8排阻上拉到VCC,否则LCD显示会出乱码或残影。RS、RW、EN分别接P2.0、P2.1、P2.2。VO对比度引脚接一个10kΩ可调电阻的抽头,电位器两端接VCC和GND,用来调节LCD显示对比度,这个脚不接的话仿真里屏幕经常是全黑的。
第四块是单片机最小系统。12MHz晶振接XTAL1和XTAL2,两端各接33pF电容到地。RST引脚接10uF电解电容到VCC、10kΩ电阻到GND,构成上电复位。EA引脚必须接VCC,让单片机从片内ROM启动,漏接的话程序跑不起来,这是proteus仿真里很隐蔽的一个坑。
整体参数配置一句话总结:固定电阻10kΩ,电位器调到10kΩ时就是模拟25℃的标准NTC状态,分压点正好2.5V,ADC读数约127,LCD显示25℃左右。电位器阻值增大,温度显示降低;电位器阻值减小,温度显示升高,方向跟NTC一致——NTC阻值大对应低温,阻值小对应高温。
3.3 仿真运行前的检查:时钟、上拉、对比度
接完线先不要急着点运行,按这个顺序快速检查一遍。第一,ADC0809的CLK一定要有时钟信号,用设计工具栏里的DCLOCK发生器,双击把频率改为500kHz。500kHz是ADC0809的典型工作时钟,proteus仿真给太高会让仿真速度变慢,给太低又可能转换异常。第二,P0口的RESPACK-8排阻有没有接上、有没有连到VCC,这一步决定LCD能不能正常显示字符。第三,LCD的VO脚电位器有没有放,不放的话把对比度调到中间位置再启动仿真。
proteus里调节电位器有两种方式:仿真运行中直接用鼠标拖动电位器滑块,阻值会实时变化;或者暂停仿真,双击POT-HG,在属性对话框里直接输入精确阻值。拖动滑块适合直观观察温度随阻值连续变化,输入精确阻值适合做定点验证,两种方式搭配用。
4. 源代码怎么读:ADC采集时序、温度换算与LCD1602显示
4.1 ADC0809读取函数:启动、等待EOC、读取一次数据
这套资源的源代码核心是ADC0809的读取时序,时序写不对,后面所有换算都是空谈。ADC0809的启动时序是:START引脚先低电平,拉高产生上升沿复位内部逐次逼近寄存器,再拉低产生下降沿启动一次转换。转换期间EOC引脚输出低电平,转换完成后EOC变为高电平。程序必须等待EOC拉高之后,再把OE拉高使能三态输出,从P1口读出转换结果。
下面这段是标准的单通道读取函数,也是源码包里最常见的样子:
// 定义控制引脚 sbit START = P3^3; sbit EOC = P3^4; sbit OE = P3^5; unsigned char get_adc(unsigned char ch) { unsigned char val; P2 &= 0xC7; // 清除P2.3-P2.5,不影响LCD控制位 P2 |= (ch & 0x07) << 3; // 通道选择:ch低3位送到A/B/C START = 0; START = 1; // 上升沿复位 START = 0; // 下降沿启动转换 while (EOC == 0); // 等待转换完成,EOC变高 OE = 1; // 打开三态输出锁存 val = P1; // 读取8位结果 OE = 0; // 关闭输出 return val; }这段代码的逻辑顺序是固定的:先选通道,再启动转换,然后死等EOC,最后读数据。通道选择那里用了P2.3-P2.5三个引脚,跟LCD的P2.0-P2.2控制引脚分离,互不干扰,这个引脚分配可以在仿真图里直接对照。如果实际接线把A/B/C接地固定用IN0,那get_adc(0)和get_adc(1)读到的都是IN0通道,因为地址线一直是0,不影响使用。
看完江科大51单片机笔记的朋友对这段会很熟悉,ADC0809的时序跟外部中断、定时器这些外设不一样,它靠的是电平判断而不是中断响应,所以主循环里等待EOC时程序会阻塞在这里。好在温度采样不需要高实时性,阻塞200微秒完全无感。
4.2 把ADC值换算成温度:浮点B值公式与查表法怎么选
拿到ADC值之后要换算温度,这一步有两个方案:浮点B值公式和查表法。资源源码包一般默认用浮点公式,因为它改参数方便、逻辑直观。换算分两步:先由ADC值反解NTC阻值,再代入B值公式求温度。
#include <math.h> #define R_FIXED 10000.0 // 分压上拉电阻 10kΩ #define R25 10000.0 // NTC在25℃时的阻值 #define B_VALUE 3950.0 // NTC的B值 #define T25 298.15 // 25℃对应的开尔文温度 float adc_to_temp_c(unsigned char adc_val) { float vout, r_ntc, t_k; vout = (float)adc_val * 5.0 / 255.0; // 反解分压点电压 r_ntc = vout * R_FIXED / (5.0 - vout); // 反解NTC阻值 t_k = 1.0 / (1.0 / T25 + log(r_ntc / R25) / B_VALUE); return t_k - 273.15; // 开尔文转摄氏 }注意一个前提:这个公式对应的是电路里NTC在下臂的接法,也就是Vout = VCC × R_NTC / (R_FIXED + R_NTC),所以反解时是vout × R_FIXED / (5 - vout)。如果仿真图里NTC被接到了上臂,这个公式返回的温度就是错的,需要把分子分母对调。拿到别人的源码第一件事就是先确认仿真图里热敏电阻的接法,再决定用哪个公式,这是踩过坑的人都会养成的习惯。
浮点方案的问题是Keil C51的浮点库和log函数会占用不少ROM,AT89C51的4KB程序空间可能吃紧。如果编译时提示“CODE SIZE LIMIT EXCEEDED”,有两个出路:换AT89C52在proteus里重新放置芯片,引脚完全兼容;或者改用查表法,把ADC值和温度的对应关系预先算好存到code区,运行时查表加线性插值。
查表法的表格可以按0~100℃每10℃取一个ADC采样点。假设固定电阻10kΩ、参考电压5V、8位ADC,各温度对应的ADC值参考如下:
| 温度℃ | NTC阻值(kΩ) | 分压点电压(V) | ADC读数 |
|---|---|---|---|
| 0 | 33.6 | 3.85 | 196 |
| 10 | 20.2 | 3.34 | 170 |
| 20 | 12.5 | 2.78 | 142 |
| 30 | 8.0 | 2.23 | 114 |
| 40 | 5.3 | 1.73 | 88 |
| 50 | 3.6 | 1.32 | 67 |
| 60 | 2.5 | 1.00 | 51 |
| 70 | 1.8 | 0.75 | 38 |
| 80 | 1.3 | 0.56 | 29 |
| 90 | 0.9 | 0.43 | 22 |
| 100 | 0.7 | 0.33 | 17 |
注意这里ADC值是按递减方向排列的,因为NTC阻值随温度升高而下降,分压电压也跟着下降。做查表时要注意方向,程序里是倒着找区间,不是正着找。这组数据是理论计算值,proteus仿真里因为元件参数容差,实测读数会略有偏差,但差异不会超过几个LSB。
查表的线性插值代码比浮点版省ROM得多,性能也快一个量级:
// 查表:ADC读数对应0~100℃,每10℃一个点 code unsigned char adc_table[11] = {196, 170, 142, 114, 88, 67, 51, 38, 29, 22, 17}; unsigned int adc_to_temp(unsigned char val) { unsigned char i; for (i = 0; i < 10; i++) { if (val >= adc_table[i] && val < adc_table[i + 1]) break; } if (i >= 10) i = 9; // 线性插值:温度 = 区间起点温度 + 比例 × 10℃ return i * 10 + (unsigned int)((unsigned int)(val - adc_table[i]) * 10 / (adc_table[i + 1] - adc_table[i])); }表格的物理意义是“每个ADC读数落在哪两个温度点之间,就按比例算出温度”。因为NTC的阻值-温度曲线本身接近指数分布,10℃一个点做线性插值,中间点的误差大概在1℃以内,跟8位ADC本身的量化误差在同一量级。要注意的是查表法只对同一套分压电路和参考电压有效,如果你把固定电阻改成20kΩ,这张表就得重算。
4.3 LCD1602驱动与主循环:均值滤波怎么加
LCD1602的驱动是标准套路:初始化、写命令、写数据、显示字符串。下面给出够用的精简版,完整的花样代码在资源包里:
sbit RS = P2^0; sbit RW = P2^1; sbit EN = P2^2; void lcd_write_cmd(unsigned char cmd) { RS = 0; RW = 0; EN = 1; P0 = cmd; delay_us(50); EN = 0; delay_us(50); } void lcd_write_data(unsigned char dat) { RS = 1; RW = 0; EN = 1; P0 = dat; delay_us(50); EN = 0; delay_us(50); } void lcd_init(void) { delay_ms(20); lcd_write_cmd(0x38); // 8位数据、2行、5×7点阵 lcd_write_cmd(0x0C); // 显示开、光标关 lcd_write_cmd(0x01); // 清屏 delay_ms(2); lcd_write_cmd(0x80); // 光标回第一行 }LCD1602的控制时序是“E引脚高电平时写入,低电平时锁存”,所以每次操作都是拉高EN、写数据、拉低EN。RS决定是命令还是数据,RW在写操作时固定为0。proteus仿真里的LCD响应很快,但51的IO操作还是需要一点延时让模块稳定,这里给50微秒的量级就够。
主循环里要做的事很明确:读ADC、均值滤波、换算温度、刷新LCD、延时。ADC0809在仿真环境里的读数会有±1~2个LSB的抖动,直接换算成温度显示的话,个位数字会来回跳,所以加了一个去极值平均滤波。连续采样8次,去掉一个最大值和一个最小值,剩下6个求平均:
unsigned char filter_adc(void) { unsigned char i; unsigned char buf[8]; unsigned char max, min; unsigned int sum = 0; for (i = 0; i < 8; i++) buf[i] = get_adc(0); max = min = buf[0]; for (i = 0; i < 8; i++) { if (buf[i] > max) max = buf[i]; if (buf[i] < min) min = buf[i]; } for (i = 0; i < 8; i++) sum += buf[i]; sum -= max + min; return (unsigned char)(sum / 6); }这个滤波对温度这种缓变量性价比很高:8次采样本身耗时很短,去掉极值又能有效抑制毛刺。硬件上如果你把电位器滑动端接触调得不好,仿真里也能看到ADC读数的毛刺,用这个函数能直接压掉。
显示温度的格式建议保留一位小数,代码里把浮点温度乘以10转成整数再逐位拆出来显示,避免直接格式化浮点数浪费ROM。但这里必须说清楚:显示精度是0.1℃,测量精度只有1℃左右,显示小数只是让你看到温度变化的趋势更平滑,不要当真以为这套系统能精确到0.1℃,8位ADC的硬件上限摆在那里,这是两码事。
主循环每次刷新间隔建议200ms以上。温度变化本身慢,刷新太快反而让LCD不停地闪烁,200ms的节奏既能及时跟随温度变化,又能让显示稳定。
5. 仿真常见问题排查:从LCD黑屏到温度乱跳的六个典型坑
5.1 电路连接层:LCD显示与ADC读数的典型案例
第一个坑:LCD1602上电后一整排黑色方块。
现象:proteus运行后LCD显示区域全是黑色实心方块,或者偶尔有几个方块闪动。
原因:VO对比度引脚没有接分压电位器。LM016L的VO脚电压决定了显示对比度,悬空时初始电压状态不确定,很多情况下显示模块进入“全亮”状态。
解决:在VO脚接一个10kΩ电位器,两端分别接VCC和GND,抽头接VO。仿真运行中调节这个电位器,直到黑色方块消失、字符清晰显示。记住这个电位器和模拟NTC的那个电位器不是同一个,别把两个搞混,否则你调温度显示的时候顺便把对比度也改了,现象会非常诡异。
第二个坑:LCD字符显示乱码、残缺,或者第一行和第二行内容串位。
现象:能显示字符,但是显示的内容是乱码,有的字符变成横条或方块,位置也不对。
原因:P0口没有加上拉排阻,或者排阻的公共端没有接到VCC。AT89C51的P0口是开漏结构,内部没有上拉,直接驱动LCD数据总线时电平不稳定,数据线高电平电压不够,LCD就会误判指令和数据。
解决:放一个RESPACK-8排阻,公共端接VCC,8个引脚分别接到P0.0-P0.7和LCD D0-D7相连的网络上。这一步在proteus仿真里不是可选项,是必选项,不接你就等着看乱码。
第三个坑:ADC读数永远是0xFF或0x00,温度显示固定在99℃或0℃。
现象:LCD上温度数值不动,锁定在最大值或最小值,转动电位器没有任何反应。
原因:八成是ADC0809的电源和参考电压没接全。VREF+没接VCC的话内部DAC没有参考基准,转换结果没有意义;VREF-悬空同样会导致读出全0。另一个常见原因是START引脚没有产生有效的上升沿+下降沿,代码时序不对的话芯片根本没启动转换。
解决:检查VREF+接VCC、VREF-接GND,这两个引脚在proteus仿真里经常被漏掉,因为元件图上它们的位置不起眼。再检查OE引脚,仿真中可以直接把OE接VCC常使能,这样可以省掉代码里操作OE的那一行,把P1口的读取简化成一条指令。最后确认代码里START有没有完整的0-1-0翻转。
5.2 仿真设置与软件层:时钟、滤波与编译问题
第四个坑:proteus仿真运行极慢,秒表基本不走。
现象:点了运行按钮,LCD刷新像卡死一样,几秒钟才变一次。ADC转换计数也慢得离谱。
原因:ADC0809的CLK时钟给太高了。很多人直接把DCLOCK设为12MHz或干脆用单片机的ALE引脚的2MHz信号,导致proteus为模拟ADC的逐次逼近过程产生海量仿真步进。
解决:把DCLOCK降到500kHz,这个是ADC0809数据手册里的典型值,既能保证仿真速度,又不影响转换逻辑。温度计的输入本身是缓变信号,500kHz的采样速率绰绰有余。改成500kHz后你会发现仿真速度肉眼可见地变快。
第五个坑:电位器轻轻一碰,温度数字跳好几度。
现象:电位器滑块停在同一个位置,LCD温度却在小数位甚至个位上来回跳,感觉像是随机数。
原因:8位ADC的量化噪声和proteus仿真步进带来的抖动叠加在一起。在温度曲线的两端,尤其是低温段,NTC阻值变化率大,同样1个LSB的ADC误差对应好几摄氏度的温度误差。
解决:程序里加滤波,前面写的8次采样去极值平均就是为这个场景准备的。如果滤完之后跳得还明显,可以在显示层再加一个滞回处理:温度只在变化超过0.5℃时才刷新显示,否则维持上一次的值。这样显示效果马上稳定下来。这道坎是模拟采集系统的通病,不是代码能完全消掉的,硬件上用更高精度的ADC才治本。
第六个坑:Keil编译报错,或者编译通过但烧进仿真里程序不跑。
现象一:编译时提示unable to open file reg51.h,或大量未定义标识符错误。这是Keil工程选错了编译器。很多人电脑上装了Keil5的MDK版,默认用ARM编译器编译C51工程,51的头文件和语法它根本不认。解决:用Keil C51的工程类型新建工程,或者安装C51支持包后重新选择编译器版本。
现象二:编译通过,代码量提示超出芯片ROM容量。AT89C51只有4KB程序空间,浮点运算和log库加起来很容易超。解决:把单片机换成AT89C52(8KB)或STC89C52,在proteus里直接替换芯片型号即可,引脚和外围电路完全不用动。还有一个备选是把温度换算换成查表法,查表版代码能省掉将近1.5KB的浮点库开销。
现象三:proteus打开下载的仿真图,元件大面积显示为空白或问号。这是proteus版本和元件库不匹配导致的,老版本工程在新版proteus里打开经常丢元件。解决:下载资源时先看仿真文件是用哪个proteus版本生成的,优先用对应版本打开;如果只有新版proteus,那就准备好元件库对照表,把丢失的元件按第3章的搜索关键字重新放置一遍,电路逻辑不受影响。
6. 拿到手怎么验证:阻值-温度对照表与三个可落地的扩展
仿真图和源码都跑起来之后,先别急着当成品交付,花十分钟做一次定点验证,确认整个链路是准的。验证方法很简单:双击电位器POT-HG,在属性对话框里把阻值设定为某个固定值,然后把LCD显示的温度跟理论值对比。用第2章的分压电路和B值公式,可以算出这样一张对照表:
| 电位器模拟阻值(kΩ) | 对应NTC温度(℃) | 理论ADC读数 | LCD理论显示 |
|---|---|---|---|
| 2 | 66.2 | 0xD2(210) | 66.2℃ |
| 5 | 41.5 | 0x86(134) | 41.5℃ |
| 8 | 30.1 | 0x72(114) | 30.1℃ |
| 10 | 25.0 | 0x7F(127) | 25.0℃ |
| 20 | 10.2 | 0xAA(170) | 10.2℃ |
| 50 | -7.3 | 0xC4(196) | -7.3℃ |
这里ADC读数用的是10位格式的一个十进制和十六进制参考值,注意它算的是NTC在下臂、固定电阻上臂的接法。验证时把电位器调到10kΩ,显示应当在25℃附近,偏差超过1.5℃说明分压电路或换算公式里的某一步不对。低温档调到50kΩ时显示会变成负温度,这时候检查你的代码里温度变量是不是用int而不是unsigned int,很多人的翻车现场就是负温度变成一个大正数。
验证通过之后,这套系统再做三个小扩展就能直接升级成功能更完整的温控装置。第一个是上下限报警:在P3.6和P3.7上接一个LED和一个蜂鸣器,代码里设定报警阈值,温度超过上限或低于下限时拉高引脚,这是课设里最常见的加分项。第二个是串口输出:把温度值通过串口发送到proteus的虚拟终端,每秒钟打印一次,这个扩展只需要在main函数里初始化串口然后用printf格式化输出,适合想看实时曲线的人。第三是改成双通道测温:ADC0809的IN1再接入一个电位器,代码里在通道0和通道1之间轮询,LCD两行分别显示两个点的温度,这对后续做多点温度采集是很好的起点。
从那以后我每次拿到这套仿真图,都会先拿阻值表把电位器和LCD显示对一遍,确认测温方向正确、ADC时序没写反,再去动原件和外壳。这个习惯帮我避免了好几次分压电路设计错误导致的“返工重焊”,也让我在给别人看代码时不用反复解释为什么显示的温度方向是反的。希望帮到你。
本文还有配套的精品资源,点击获取