ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

微机原理课程设计:8086+8255/8253+ADC0809温度控制

2026/9/20 2:06:31 拓冰建站 浏览量
微机原理课程设计:8086+8255/8253+ADC0809温度控制 简介《微机原理及其应用》课程设计报告面向微机原理与接口技术课程的在校学生及需要完成硬件类课程设计的读者围绕微型计算机温度控制系统这一典型课题给出完整设计方案。报告以工业现场075℃温度监测为背景先介绍系统功能与总体框图再分硬件设计与软件设计两部分展开硬件侧讲解CPU与8255并行接口、8253定时/计数器、ADC0809模数转换器及DAC0832数模转换器的地址分配与协同工作方式软件侧梳理8255、8253初始化、定时采样、数字滤波、温度换算、LED数码管显示与超限报警的流程与思路并给出主程序流程图和关键程序段清单。其中温度每0.1秒连续采集三次取平均值作为有效值超过上限60℃或低于下限30℃时分别以红、黄发光二极管配合蜂鸣器报警。资源为单个doc文档压缩包约32KB篇幅紧凑、结构清晰便于对照移植与答辩准备已有208人学习下载。1. 微机原理及其应用课程设计里温度控制系统为什么能把接口芯片一网打尽答辩台上最有杀伤力的问题不是「你这个系统能做什么」而是「8255 的方式字 98H 是怎么推出来的」。温度控制系统之所以在微机原理及其应用这门课的选题里年年被选中就是因为它一条信号链上挂了太多东西传感器把温度变成电压ADC0809 把它变成 8 位数字量8255 把数字量搬进 CPU8253 提供采样节拍8086 算完增量式 PID 再把结果变成加热丝的占空比。做流水灯只练输出做键盘扫描只练输入只有闭环控制系统会逼着你把输入、输出、定时、中断按同一套时序对齐任何一个环节差一个机器周期温度曲线就会抖给你看。这套方案适合已经学完 8086 指令系统、8255 和 8253 三个章节需要交一份能讲清信号链路报告的人。2. 微型计算机温度控制系统的硬件链路传感器、ADC0809 与 8255 的地址译码硬件这一层的核心不是「接上就行」而是每一级都要算清楚量程和分辨率否则后面 PID 参数怎么调都救不回来。下面按信号流的方向拆成三段传感器怎么选、ADC 与 8255 怎么接线、端口地址怎么译码。2.1 温度传感器选型模拟链路和数字链路的取舍选传感器之前先想清楚一个问题这份课程设计想展示的是模拟接口能力还是时序控制能力。LM35 输出 10mV/℃0℃ 对应 0V线性度好接一个运放放大 5 倍就能把 0~100℃ 映射到 0~5V正好喂给 ADC0809 的满量程。代价是你要自己算运放的反馈电阻、自己处理零点漂移。DS18B20 直接把温度变成数字量一根 IO 口读出来就是 0.0625℃ 分辨率但它考的是单总线时序跟「微机原理与接口技术」里的并行接口知识关系不大。器件输出形式接到微机还缺什么8 位量化下的分辨率适合展示什么LM3510mV/℃ 电压运放放大 ADC0809约 0.39℃模拟通道全链路AD5901μA/K 电流I/V 转换 ADC取决于 ADC长线电流传输DS18B20单总线数字一个 IO 口 严格时序0.0625℃数字时序PT100电阻变化电桥 仪表放大器 ADC取决于 ADC宽温区工业场景分辨率这笔账要当场算出来。0~100℃ 对应 0~5V8 位 ADC 满量程 255 个刻度每个刻度代表 100/255 约等于 0.39℃。也就是说稳态误差小于 0.4℃ 的诉求8 位 ADC 是给不了的报告里必须写清这个边界而不是把稳态误差标成 0.1℃。提示LM35 的输出脚对地容性负载敏感长导线要串 75Ω 电阻再进运放否则读数会自激振荡。2.2 ADC0809 与 8255 的接线A 口读数据、B 口发通道号和 STARTADC0809 是 8 通道、8 位逐次逼近型转换器转换时间约 100μs工作时钟典型 640kHz。它的控制信号只有三根需要 CPU 操心ALE 用来锁存通道地址START 的上升沿启动转换真正启动靠的是 START 的下降沿EOC 转换期间为低、结束后拉高OE 有效时把转换结果送上数据总线。常见做法是把 ALE 和 START 并在一起用一个 IO 位控制B 口的 PB3 就干这个活。通道选择 A、B、C 三根接到 PB0~PB2。8255 的 A 口配成方式 0 输入专门读转换结果C 口的 PC0 输出给 OEPC7 作输入读 EOCPC1 留出来驱动加热执行机构。把这几条落到方式字上D7 固定为 1 表示方式选择D6D5 等于 00 表示 A 组方式 0D4 等于 1 表示 A 口输入D3 等于 1 表示 C 口高 4 位输入因为 PC7 要读 EOCD2 等于 0 表示 B 组方式 0D1 等于 0 表示 B 口输出D0 等于 0 表示 C 口低 4 位输出因为 PC0 要驱动 OE。拼起来就是 1001 1000B也就是 98H。答辩时把这段推导写在报告上比背一个答案有用得多。注意8255 方式 0 下读 C 口返回的是引脚实际电平写 C 口会整字节覆盖。所以 OE 和加热控制不要用「整字节输出」的写法否则会互相把对方清零。2.3 端口地址译码74LS138 把 060H 到 066H 分给 82558086 用独立的 IO 空间端口地址 16 位大于 255 必须用 DX 间接寻址。译码常用一片 74LS138A9、A8、A7 接使能端A6、A5、A4 接 C、B、A 三个选择端译出 8 个片选信号。8255 的片内寄存器选择接 CPU 的 A2、A1A0 不接这样四个寄存器落在 060H、062H、064H、066H 四个偶地址上避开 8086 低 8 位总线只挂偶地址的麻烦。器件与端口地址方向用途8255 A 口060H输入读 ADC0809 的 8 位转换结果8255 B 口062H输出PB0~PB2 通道号PB3 作 ALE/START8255 C 口064HPC0 输出 / PC7 输入PC0 控制 OEPC7 读 EOCPC1 驱动加热8255 控制口066H写方式字 98H或位控制字8253 计数器 0070H读写10ms 采样定时8253 控制口073H写控制字 34H把地址写成符号常量后面改译码接线时只动一处; ---- 端口地址常量与 74LS138 译码输出一一对应 ---- PA55 EQU 060H ; 8255 A 口ADC 数据输入 PB55 EQU 062H ; 8255 B 口通道选择 ALE/START PC55 EQU 064H ; 8255 C 口PC0OEPC7EOCPC1加热 CTRL55 EQU 066H ; 8255 控制口 CNT0 EQU 070H ; 8253 计数器 0 数据口 CTRL53 EQU 073H ; 8253 控制口这段常量表的价值在于把「硬件接线」和「软件寻址」解耦。如果你在 Proteus 里把译码器的 C、B、A 三根线接反了片选顺序会变但程序里的符号不用改只需要重新对照译码表改一次常量比满篇翻找裸地址靠谱。3. 采样与控制的软件实现8253 定时中断下的汇编采样骨架与增量式 PID硬件通路打通之后真正的难点在时间维度和数值精度上。采样太快没有意义热惯性动辄几十秒采样太慢又会把 PID 变成继电器式的通断控制。这一章把 8253 定时、ADC 查询式采样、增量式 PID 定点实现这三段代码写清楚。3.1 8253 计数器 0 初始化出 100Hz 采样节拍设系统给 8253 的时钟是 2MHz希望每 10ms 触发一次采样计数初值就是 2MHz 乘以 0.01s 等于 20000没有超出 16 位计数范围可以用先低字节后高字节的写入方式。工作方式选方式 2分频器输出是一串负脉冲接 8259 的中断请求引脚比方式 3 的对称方波更干净边沿触发不会有毛刺。控制字推导D7D6 等于 00 选计数器 0D5D4 等于 11 表示先读低字节再读高字节D3D2D1 等于 010 是方式 2D0 等于 0 表示二进制计数得到 0011 0100B 即 34H。; ---- 8253 计数器 02MHz 输入10ms 周期方式 2 ---- INIT_8253 PROC NEAR MOV DX, CTRL53 MOV AL, 34H ; 计数器0先低后高方式2二进制 OUT DX, AL MOV DX, CNT0 MOV AX, 20000 ; 2e6 * 0.01 20000 OUT DX, AL ; 先写低字节 MOV AL, AH OUT DX, AL ; 再写高字节 RET INIT_8253 ENDP逻辑说明控制字必须先写因为它决定了后续两个字节的读写顺序计数初值必须按先低后高的顺序写写反了会得到 20000 高低字节互换后的错误分频比中断频率会变成 3Hz 左右。参数说明把 20000 改成 40000采样周期就变成 20ms改成 2000 则变成 1ms但热惯性下 1ms 采样纯属浪费 CPU。写完之后不要忘记开中断指令 STI以及把 8259 的对应中断屏蔽位清零。3.2 ADC0809 采样子程序查询 EOC 而不是死等延时很多报告里的采样程序是「启动转换循环 200 次空操作然后直接读结果」在 Proteus 里能跑通换到真实硬件上就随机出错因为 ADC 的转换时间有离散性。稳妥的写法是查 EOC 引脚电平。; ---- 采样一个通道入口 BL 通道号(0~7)出口 AL 转换结果 ---- ADC_READ PROC NEAR MOV DX, PB55 MOV AL, BL OUT DX, AL ; PB0~PB2 送出通道号 OR AL, 08H OUT DX, AL ; PB3 拉高ALE 锁存通道地址 NOP NOP AND AL, 0F7H OUT DX, AL ; PB3 拉低START 下降沿启动转换 WAIT_EOC: MOV DX, PC55 IN AL, DX TEST AL, 80H JZ WAIT_EOC ; EOC 为低表示仍在转换继续等 MOV DX, CTRL55 MOV AL, 01H OUT DX, AL ; 位控制字PC0 1OE 有效 MOV DX, PA55 IN AL, DX ; 读回 8 位转换结果 MOV AH, AL ; 暂存到 AH MOV DX, CTRL55 MOV AL, 00H OUT DX, AL ; 位控制字PC0 0撤销 OE MOV AL, AH ; 结果恢复到 AL 返回 RET ADC_READ ENDP逻辑说明PB3 的拉高拉低之间插两个 NOP是为了满足 ALE 和 START 的最小脉宽要求8086 在 5MHz 下一个总线周期 200ns两个 NOP 足够。OE 的控制特意改用位控制字而不是整字节输出因为 C 口同一字节上还挂着 PC1 的加热控制整字节写会把加热状态一起清掉。参数说明BL 的取值范围是 0 到 7对应 IN0 到 IN7 八个通道如果只用一个通道测温把 BL 固定成 0 即可。EOC 查询是死循环等待若担心硬件故障导致程序卡死可以在循环里加一个计数器超过 200 次未结束就返回错误标志。3.3 增量式 PID 用 Q8 定点数在 8086 上跑起来温度控制对象是一阶惯性加纯滞后位置式 PID 需要累加历史偏差容易积分饱和而且输出直接对应绝对占空比切换手动自动时会跳变。增量式 PID 只算输出增量公式是Δu(k) Kp·[e(k) − e(k−1)] Ki·e(k) Kd·[e(k) − 2e(k−1) e(k−2)]8086 没有浮点单元用 Q8 定点把系数乘以 256 存成字节算完再右移 8 位还原。偏差 e 限制在 ±100℃ 以内任何一个乘积都不会超过 16 位有符号数的范围。; ---- 增量式 PIDQ8 定点系数已乘 256 ---- KP_Q8 DB 64 ; Kp 0.25 KI_Q8 DB 16 ; Ki 0.0625 KD_Q8 DB 0 ; Kd 先不投等 P、I 调稳再加 E0 DB 0 ; e(k) E1 DB 0 ; e(k-1) E2 DB 0 ; e(k-2) PWM_DUTY DW 0 ; 占空比 0~100单位 % PID_INC PROC NEAR MOV SI, 0 ; --- P 项 --- MOV AL, E0 SUB AL, E1 MOV BL, KP_Q8 IMUL BL ; AX (e0-e1) * Kp_Q8 SAR AX, 8 ADD SI, AX ; --- I 项 --- MOV AL, E0 MOV BL, KI_Q8 IMUL BL SAR AX, 8 ADD SI, AX ; --- D 项 --- MOV AL, E0 SUB AL, E1 MOV BL, AL ; BL e0 - e1 MOV AL, E1 SUB AL, E2 SUB BL, AL ; BL e0 - 2e1 e2 MOV AL, BL MOV BL, KD_Q8 IMUL BL SAR AX, 8 ADD SI, AX ; --- 累加并限幅到 0~100 --- ADD PWM_DUTY, SI CMP PWM_DUTY, 0 JGE PID_HI MOV PWM_DUTY, 0 PID_HI: CMP PWM_DUTY, 100 JLE PID_END MOV PWM_DUTY, 100 PID_END: MOV AL, E1 MOV E2, AL ; 更新 e(k-2) MOV AL, E0 MOV E1, AL ; 更新 e(k-1) RET PID_INC ENDP逻辑说明IMUL 是无符号以外的有符号 8 位乘法结果放在 AXSAR 是算术右移保留符号位负数右移后才能得到正确的负增量。PWM_DUTY 的限幅不能省它同时承担两个职责防止占空比超出 0~100 的物理范围以及抑制积分饱和——当输出已经顶到 100 还在涨时限幅会把多余部分截掉。参数说明KP_Q8 等于 64 对应 Kp 为 0.25想改成 0.5 就写 128KI_Q8 等于 16 对应 Ki 为 0.0625这是 Q8 格式下比较合适的下限再小会被截断成 0需要更小的 Ki 就把整个数据通路扩到 16 位 Q12 格式。注意增量式 PID 的记忆量只有 e(k−1) 和 e(k−2) 两个数上电初始化时必须清零否则第一次控制会输出一个莫名其妙的增量。4. 温度控制系统联调从阶跃响应看 PID 参数、PWM 占空比与积分饱和参数不是拍脑袋定出来的。先在 PC 上用一个十几行的脚本把阶跃响应跑出来看清楚超调和振荡长什么样再把系数换算成 Q8 写进汇编比反复烧写程序试参数快得多。4.1 软件 PWM 把 PID 输出变成加热占空比加热丝的功率调节不需要昂贵的 D/A用软件 PWM 就够了。热惯性通常几十秒1 秒的 PWM 周期完全不会让温度产生可感知的波动。做法是在 10ms 定时中断里累加一个计数变量计满 100 次是一个周期计数值小于占空比就开加热否则关。; ---- 软件 PWM由 10ms 中断调用100 次为一个周期(1s) ---- PWM_CNT DW 0 PWM_TICK PROC NEAR INC PWM_CNT CMP PWM_CNT, 100 JL PWM_CMP MOV PWM_CNT, 0 ; 满一个周期回零 PWM_CMP: MOV DX, CTRL55 MOV AX, PWM_DUTY CMP PWM_CNT, AX JGE PWM_OFF MOV AL, 03H ; 位控制字PC1 1加热开 OUT DX, AL RET PWM_OFF: MOV AL, 02H ; 位控制字PC1 0加热关 OUT DX, AL RET PWM_TICK ENDP逻辑说明位控制字 D7 等于 0 表示按位操作D3D2D1 等于 001 选 PC1D0 等于 1 置位、等于 0 复位所以置位是 03H、复位是 02H。这种写法的好处是只动 C 口一个位不会碰 PC0 的 OE 状态。参数说明把 100 改成 50 就把 PWM 周期缩到 0.5 秒周期太短会让固态继电器频繁动作、寿命下降太长则温度波动明显300 到 1000 毫秒是这类系统的常用区间。4.2 用 Python 先把阶跃响应跑一遍再回写汇编参数对象模型用一阶惯性加纯滞后近似K 是增益、T 是时间常数、τ 是滞后时间这三个数可以从实际加热实验的阶跃响应里量出来也能先用经验值试。# 一阶惯性 纯滞后对象的增量式 PID 仿真 # 目的在写汇编之前把 Kp/Ki/Kd 的量级定下来 import numpy as np K, T, tau 2.5, 60.0, 8.0 # 增益 %/℃、时间常数 s、滞后 s dt 1.0 # 采样周期 s对应 10ms 中断每 100 次算一次 N 600 # 仿真时长 600s n_tau int(tau / dt) y np.zeros(N n_tau 2) # 温度 Kp, Ki, Kd 0.8, 0.03, 0.0 # 保守起点Kd 先为 0 e1 e2 0.0 duty 0.0 for k in range(N): e0 50.0 - y[k n_tau] # 设定值 50℃ du Kp * (e0 - e1) Ki * e0 Kd * (e0 - 2 * e1 e2) duty min(max(duty du, 0.0), 100.0) # 占空比限幅 y[k n_tau 1] y[k n_tau] (K * duty - y[k n_tau]) * dt / T e2, e1 e1, e0 peak y.max() print(超调量 %.1f%% % ((peak - 50) / 50 * 100)) print(稳态值 %.2f℃ % y[-1])逻辑说明每算一次就更新一次占空比并限幅再推进对象模型一步滞后用数组平移实现。参数说明Kp 从 0.5 到 1.0 之间试Ki 从 0.01 到 0.05 之间试Kd 一开始保持 0等 P、I 调出稳定上升曲线后再加 0.1 到 0.5 抑制超调。把最终定下来的 Kp 乘以 256 取整写进 KP_Q8Ki 同理就完成了从仿真参数到汇编写真值的换算。4.3 Proteus 联调排错温度不收敛的六个检查点仿真和实物之间隔着一堆时序细节下面这张表是调试时按顺序排查最省时间的路径。现象大概率原因检查动作读回的 ADC 值恒为 00H 或 FFHOE 时序不对或数据线没接到 A 口用示波器看 PC0 是否在 EOC 变高后才拉高EOC 永远不跳ADC 时钟没给或 START 脉宽不够Proteus 里把 ADC 的 CLOCK 属性设为 640kHz定时中断根本不进8253 控制字写错或没执行 STI用逻辑分析仪看 OUT0 有没有 100Hz 脉冲温度一直往上冲不回输出限幅缺失积分饱和检查 PWM_DUTY 的上下限判断是否被跳过温度高频抖动采样周期太短微分项没滤噪把采样周期从 10ms 改成 100ms 再看稳态误差始终存在Ki 太小被 Q8 截断成 0把 KI_Q8 从 16 提高到 32 再试第一项和第二项占了实际调试时间的大半原因都是控制信号没有被观测到而是凭感觉改代码。养成先用示波器确认 EOC、ALE、OUT0 三个波形的习惯剩下的就是参数问题参数问题只要仿真模型对得上在 PC 上改比在电路里改快十倍。5. 从仿真数据到课程设计报告曲线、数据表和答辩追问仿真跑通了只是完成一半报告里那些数字才是评分点。阶跃响应的数据不要只贴一张截图要整理成表每个指标都要写清测量方法。超调量等于峰值减设定值再除以设定值调节时间取温度首次进入并保持在设定值正负 2% 带内的时间点稳态误差取最后 100 秒的平均值与设定值之差。这三句话写进报告比画十条曲线都有说服力。答辩追问的命中率极高提前把答案写成技术细节而不是概念复述。被问到「为什么用增量式 PID」回答的重点是位置式需要累加全部历史偏差、输出对应绝对占空比切换到手动时会产生跳变而增量式只保留 e(k−1) 和 e(k−2) 两个记忆量天然抗积分饱和。被问到「8 位 ADC 精度够不够」就把 100℃ 除以 255 算出 0.39℃ 这个量化台阶摆出来说明系统稳态误差的物理下限由它决定。还有一个容易被忽略的收尾技巧报告里的温度值不要直接存 ADC 原始码而是采样后立刻换算成摄氏度再送显示和 PID。换算方法就是把 ADC 码乘 100 再右移 8 位得到的就是摄氏温度的整数部分用 8086 的 MUL 和 SHR 两条指令就能完成得到的整数值同时解决了定点 PID 的输入格式问题也让报告里所有数据表的口径统一成摄氏度。本文还有配套的精品资源点击获取