简介:《TDX-PITE-80X86微机接口应用技术实验教程》面向微机原理与接口技术课程的学习者及实验指导教师,聚焦80X86微处理器与外部硬件设备的接口实践,可用于课程实验、自学补强和实验平台调试参考。压缩包内共1个PDF文件,约909KB,围绕FPGA单元资源展开,先说明50MHz有源晶振、全局时钟、JTAG下载口及扩展插座引脚分配,再依次收录键盘扫描与显示、电子发声、点阵LED显示、双机通讯、步进电机、温度闭环控制和直流电机闭环调速等实验。内容兼顾接口芯片逻辑、引脚对应关系和实验原理,便于读者按目录快速定位实验模块,理解8259、8255、8254、8251、8237等单元的应用方式,并对照硬件连接梳理实验流程,也可借助文档中的唐都公司网址、技术支持邮箱与QQ获取排错支持。目前已有667人学习,适合作为微机接口实验课的配套资料,帮助学习者在理论与板级操作之间建立连接。
1. 从「接线全对、程序不出结果」说起
80X86 微机接口这门课,实验报告交得出来的人不少,能把线接对、程序跑通、现象对上的不多。卡点很少在原理,而在硬件资源和软件动作没对齐:8255 的 A 口到底接行还是接列,8254 的 CLK0 从哪来,16×16 点阵的字模为什么按左上、右上、左下、右下取模——教材上一句话,实验台上就是一下午。
这份 TDX-PITE-80X86 微机接口应用技术实验教程作为一份完整的课程资源,把 FPGA 单元、五块接口芯片和七组实验串成一条线:键盘扫描与数码显示、电子发声、点阵 LED、双机通讯、步进电机、温度闭环、直流电机闭环调速。它适合两类读者:正在做微机原理课程设计、接口技术毕设的学生,和要给实验室排一套可复现流程的老师或助教。下面按「平台怎么用 → 交互类怎么做 → 闭环类怎么调 → 哪里会翻车 → 怎么验收」拆。
2. 平台资源盘点与地址映射:FPGA 单元、五块接口芯片和一片 I/O 空间
实验台跑不通,八成问题出在「我以为它接在那儿」。这一章先把硬件账本摊开:FPGA 板上有什么、五块接口芯片的逻辑是怎么塞进一片 FPGA 的、引脚到端口号之间还隔着哪一层译码。这三件事理清楚,后面七个实验的代码才有落点。
2.1 FPGA 板上的时钟、下载口与扩展插座
FPGA 板提供一路 50MHz 有源晶振,接到芯片的 PIN_25(CLK3),可以当全局时钟用。这个频率是整个平台的时间基准,后面 8254 的分频、点阵的刷新率、串口的波特率,追根溯源都跟它或者它分出来的时钟有关。板上还有 JTAG 下载口,位置在 8251 单元和 8237 单元中间,用来下载和调试逻辑。
扩展插座是 FPGA 板跟外界打交道的出口。引脚分配在教程的引脚图里给全了:左侧一列是 8255 的 PA、PB、PC 口,中间是地址线和数据线,右侧是各芯片的片选、时钟、中断和 I/O 读写信号。刚开始看这张图容易懵,其实可以按三组记:数据组(D7~D0,接各芯片数据线)、地址组(A15~A0,接各芯片地址线)、控制组(IOW、IOR、RST#、各片选)。记住这三组,接线时就不会把 PA7 当成数据线用。
一个容易被忽略的点:这块板出厂时就烧好了接口芯片逻辑,8259、8255、8254、8251、8237 是「逻辑上存在」而不是「物理上插着」。所以它没有传统实验箱那种拔插芯片的步骤,但也意味着你不能靠换芯片排查故障——芯片不正常,先怀疑接线和片选,别怀疑芯片坏了。
2.2 五块接口芯片的逻辑构成与引脚对应关系
出厂逻辑包含五个单元:8259 中断控制器、8255 并行接口、8254 定时/计数器、8251 串行接口、8237 DMA 控制器。每个单元的片选、时钟、中断线都在 FPGA 引脚上有一一对应,下表是教程里最常查的几组,接线前扫一眼能省很多返工。
| 功能 | FPGA 引脚 | 说明 |
|---|---|---|
| 8255 PA7~PA0 | 1、3、10、31、33、38、42、44 | A 口,键盘实验里接行扫描 |
| 8255 PB7~PB0 | 49、51、53、55、59、65、67、69 | B 口,常接数码管段码 |
| 8255 PC7~PC0 | 11、32、34、39、43、46、50、52 | C 口,低 4 位读列线 |
| D7~D0 | 119、121、125、127、129、133、136、138 | 各芯片数据总线 |
| A15~A8 | 83、85、87、141、143、99、101、105 | 地址高 8 位 |
| A7~A0 | 111、113、115、120、124、126、128、132 | 地址低 8 位 |
| 8255_cs、8254_cs、8251_cs | 23、30、24 | 三块常用芯片片选 |
| 8237_cs、8259_cs | 86、28 | DMA 与中断控制器片选 |
| IOW、IOR、RST#、sys_clk | 73、71、84、25 | 读写、复位、系统时钟 |
表里最该盯住的是片选那一行。8255_cs 落在 PIN_23,8254_cs 落在 PIN_30,8251_cs 落在 PIN_24,三个片选分别对应实验箱上的三个 I/O 译码输出(IOY0、IOY1、IOY2 之类)。接线图上写「8255 单元 CS 接 IOY0」,你就得实打实把线插到 IOY0 那一位上,插错一位,程序里端口地址全对也读不出数据,这类问题在实验室里出现频率最高。
2.3 从引脚到端口号:地址译码怎么写进程序
引脚只到芯片,程序要的是端口号。中间这一层是实验箱上的地址译码电路:CPU 送出的 A15~A0 经过译码,在某一段地址范围内拉低对应片选,于是这块芯片的寄存器就落在这一段地址里。教程里各实验的例程都按实验箱给定的基址写死了端口宏,你要做的是把宏改成自己这块板上的实际基址。
; 端口定义:基址按实验箱 IOY0 的译码结果确定,此处以 280H 为例 IOY0_BASE EQU 0280H P8255_PA EQU IOY0_BASE + 00H ; A 口 P8255_PB EQU IOY0_BASE + 01H ; B 口 P8255_PC EQU IOY0_BASE + 02H ; C 口 P8255_CTL EQU IOY0_BASE + 03H ; 控制口 ; 8255 初始化:A 口方式0输出、C 口高4位输出、B 口方式0输出、C 口低4位输入 ; 方式字 = 1000 0001B = 81H MOV DX, P8255_CTL MOV AL, 81H OUT DX, AL这段代码只有四行有效动作,但每一行都有讲究。IOY0_BASE是整块 8255 的起点,A0、A1 两根地址线在片内做二次译码,于是基址 +0 到 +3 分别对应 A、B、C 口和控制口,顺序不能乱。方式字 81H 拆开看:D7 置 1 表示这是方式字而不是位操作字,D6D5=00 选 A 口方式 0,D4=0 让 A 口输出,D3=0 让 C 口高 4 位输出,D2=0 选 B 口方式 0,D1=0 让 B 口输出,D0=1 让 C 口低 4 位输入。键盘实验里 A 口要输出行扫描码、C 口低 4 位要读回列线、B 口要输出段码,正好对上这组配置。
提示:换一块实验箱、换一台机器,第一步永远是确认基址。写个小程序往基址 +3 写 81H 再读回,读不出预期值就说明片选或基址错了,别急着往下写功能。
3. 人机交互三实验:键盘扫描、8254 发声与 16×16 点阵取模
这三个实验看起来是三个不相干的东西——按键、声音、汉字,底层其实是同一套动作:CPU 通过并行口或定时器输出时序,外设按时序回应。把这层共性抓住,三个实验的代码结构会高度相似:初始化接口、循环输出、读回或等待、更新显示缓冲。差别只在时序的松紧和数据的组织方式。
3.1 4×4 键盘扫描与数码管动态显示的配合
实验要求是:4×4 键盘编号 0~F,按下一个键,把编号显示在一个数码管上;再按一个,显示在下一个数码管上,最多保留最近 4 次按键。硬件上 8255 的 A 口低 4 位接键盘行线、C 口低 4 位接列线、B 口接数码管段码,位选由 C 口高 4 位或独立译码给出。
扫描逻辑是标准的逐行拉低法:每次只让一行为低,读回四根列线,如果某列为低,说明该行该列的交叉点被按下。关键在于去抖和显示刷新要放在同一个循环里,否则按键一按下去数码管就闪,或者一次按键被识别成好几次。
; 逐行扫描:行码从 FE 开始左移,读列线判断是否有键按下 SCAN_KEY PROC MOV CL, 0FEH ; 行扫描码,最低位先拉低 MOV BL, 00H ; 键值基数,每换一行加 4 ROW_LOOP: MOV DX, P8255_PA MOV AL, CL OUT DX, AL ; 输出行扫描码 MOV DX, P8255_PC IN AL, DX ; 读回列线 AND AL, 0FH CMP AL, 0FH JNE HIT_ROW ; 有列线为低,本行有键 ADD BL, 04H ; 换下一行,键值基数加 4 ROL CL, 1 CMP CL, 0EFH ; 四行扫完? JNE ROW_LOOP RET ; 无键返回 HIT_ROW: ; 列线中为低的那一位决定列号,行号×4 + 列号 = 键值 ... SCAN_KEY ENDP这段扫描程序有两个参数需要按实际接线调:0FEH这个初值决定第一根拉低的是哪一行,如果接线时行序反了,键值映射表就得整体镜像;ADD BL, 04H里的 4 是列数,换成 4×4 以外的键盘要同步改。键值算出来后不是直接送显示,而是先写进一个 4 字节的显示缓冲区,缓冲区整体左移一位再把新键值放到末位,这样才实现「显示最近 4 次」。
数码管这边是动态扫描:4 个数码管轮流点亮,每个停留一两毫秒,靠视觉暂留看起来是同时亮的。刷新频率不能太低(低于 50Hz 会看到抖动),也不能太高(亮度不够)。我的习惯是把刷新放在定时中断里或者主循环里固定节拍调用,按键扫描则每轮只扫一行,两者交替执行,谁都不阻塞谁。
3.2 电子发声:计数初值计算与音符时间表
发声的原理一句话能说完:把某个音符对应频率的方波送到扬声器,就发出这个音;把一串音符的方波按顺序送出去,就是一段曲子。8254 的方式 3 是方波发生器,往计数器里写一个初值,OUT 引脚就输出对应频率的方波。
初值算法是计数初值 = 输入时钟 ÷ 输出频率。教程里输入时钟取 1MHz,要得到 800Hz,初值就是 1000000 ÷ 800 = 1250。这个除法在程序里是预先算好写成表的,运行时直接查表更省事,也避免 16 位除法拖慢节奏。
; 8254 计数器0,方式3(方波),先写低字节再写高字节 MOV DX, P8254_CTL MOV AL, 00110110B ; SC1SC0=00 选计数器0,RW=11 先低后高,方式3,二进制 OUT DX, AL MOV DX, P8254_C0 MOV AX, [SI] ; SI 指向频率表,表内存的是算好的计数初值 OUT DX, AL ; 低字节 MOV AL, AH OUT DX, AL ; 高字节方式字 36H 的每一位都要能解释清楚:D7D6=00 选计数器 0,D5D4=11 表示读写都按先低字节后高字节,D3D2D1=011 是方式 3,D0=0 表示二进制计数(写 1 是 BCD)。这里最容易翻车的是读写顺序——8254 要求先低后高,写成先高后低,初值就变成一个完全不相干的数,声音频率对不上,你还以为是频率表算错了。
时间表跟频率表一一对应,存的是每个音符的相对时长。教程给的参考程序用DL传单位延时个数,一个单位延时是一段固定次数的空循环。这段空循环的循环次数跟 CPU 主频强相关,换一台机器必须重新标定,否则整首曲子会快放或者慢放。我的做法是先用一个已知时长的循环跑一遍、掐表算出实际单位延时,再反推每个音符该给几个单位。
注意:频率表最后一项写 0 作为结束标志,程序判断到 0 就回到表头重放。曲子里如果真有一个频率算出来是 0,会提前结束,这种情况得换一个结束标志值。
3.3 点阵显示:字模取法与行列驱动的时序
16×16 点阵由四块 8×8 拼成,点亮规则是「行为 1、列为 0」时对应的 LED 亮。听起来简单,实际接线和取模顺序一错,显示出来就是乱码或者镜像字。
列驱动用 SM16206,它是恒流驱动芯片,内部有移位寄存器和锁存器,串行数据进去、并行输出出来,时钟频率能到 25MHz,带多级串联也没问题。行驱动用 SM5166,内部带 3-8 译码器,8 路输出每路最大 2.5A,还内置了钳位电路抑制拖影、短路保护防烧板。这两颗芯片的分工要记住:列管数据、行管选通,写代码时列数据要先移位再锁存,行选通则是给个 3 位地址。
字模的取法是这个实验最容易出岔子的地方。教程指定的规则是:横向 8 个连续点构成一个字节,最左边的点是 BIT0、最右边是 BIT7;16×16 的汉字按每行 2 字节、共 16 行取,一个汉字 32 字节;四块点阵的取字顺序是左上角 → 右上角 → 左下角 → 右下角。这条规则必须和实际接线方向严格一致,取模时是「左起」,接线时要是把点阵转了个方向,字就是反的。
/* 一帧显示:先送 16 行数据(每行 2 字节),再逐行选通 */ void Led16_ShowFrame(const unsigned char *frame) { int row; for (row = 0; row < 16; row++) { /* 列数据:每行两个字节,高位字节对应右侧 8 列 */ Led_ShiftByte(frame[row * 2]); /* 左半 8 列 */ Led_ShiftByte(frame[row * 2 + 1]); /* 右半 8 列 */ Led_Latch(); /* 锁存,列数据生效 */ Led_SelectRow(row); /* 行选通,只亮当前行 */ DelayUs(200); /* 停留时间,太短会暗,太长会闪 */ } }DelayUs(200)这个停留时间是调出来的:16 行扫一遍大约 3.2ms,刷新率 300Hz 左右,肉眼看不到闪烁;要是把延时砍到 20μs,亮度会掉一半,因为每行点亮的时间占比太低。Led_SelectRow(row)送的是行号,实际芯片接收的是 3 位译码地址,中间还要走一次 3-8 译码,所以传参前要把 16 行映射成两片 5166 的地址。卷动显示的做法是每帧把整个字模缓冲区整体移一位、跨字节拼接,再重新送一帧,移位速度决定卷动快慢。
4. 闭环控制与串行链路:步进电机、直流调速、温度闭环与双机通讯
前三个实验是「输出对就行」,这四个是「输出要往目标靠」。闭环类实验的难点不在写代码,而在把物理量换算成程序能算的数字:一步走多少度、一个脉冲代表多少转、一次采样代表多少度。量纲搞错,PID 参数怎么调都是振荡。
4.1 步进电机:脉冲分配表与加减速曲线
步进电机的控制本质是按时序给各相绕组通电。四相电机常见三种通电方式:单四拍(A-B-C-D)、双四拍(AB-BC-CD-DA)、四相八拍(A-AB-B-BC-C-CD-D-DA)。八拍方式步距角最小、运行最平稳,但同样的转速需要两倍的脉冲频率。
| 拍序 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|---|---|---|---|---|---|---|---|---|
| 控制字(A B C D) | 0001 | 0011 | 0010 | 0110 | 0100 | 1100 | 1000 | 1001 |
控制字通常直接做成表,程序里用指针循环取。这里有个细节:正转是表指针递增,反转是递减,别用「取反控制字」的方式做反转,那样得到的是另一种通电方式,力矩和步距角都变了。
/* 四相八拍控制字表,正转指针递增,反转指针递减 */ static const unsigned char step_tab[8] = { 0x01, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x09 }; void Step_Run(int steps, int dir) { static int idx = 0; for (int i = 0; i < steps; i++) { idx = (idx + dir + 8) % 8; /* 环形索引,避免越界 */ OutPort(P_STEP, step_tab[idx]); /* 输出到驱动口 */ DelayUs(g_step_delay); /* 步间延时决定转速 */ } }g_step_delay是调速的唯一旋钮:延时越短转得越快,但低于电机响应时间就会失步——表现为电机嗡嗡响却不转。我的经验是先在低速下把行程走通,再逐步缩短延时找到临界值,实际运行取临界值的 1.5 倍留余量。需要快速定位的场合,起步阶段用长延时、走十几步后再切到短延时,就是最简单的加减速曲线。
4.2 直流电机闭环调速:PWM、测速与反馈量纲
直流电机的开环调速只要改 PWM 占空比,但占空比固定时转速会随负载漂移,闭环的意义就是把这个漂移压下去。系统结构是:PWM 输出驱动电机,测速传感器(光电码盘或霍尔)输出脉冲,定时器在固定窗口内计数,算出实际转速,跟设定值比较后调整占空比。
量纲换算是这个实验的核心。假设码盘每转输出 N 个脉冲,采样窗口 T 毫秒,窗口内计到 C 个脉冲,那么转速就是C × 60000 ÷ (N × T)转/分。T 取 100ms、N 取 20 的话,一个脉冲对应 30 转/分,分辨率就是这么来的。窗口太短分辨率不够,窗口太长响应变慢,100ms 到 200ms 是常见折中。
/* 增量式 PI:只算增量,天然抗积分饱和,实现也简单 */ int Speed_Control(int target, int actual) { static int last_err = 0; int err = target - actual; int delta = KP * (err - last_err) + KI * err; last_err = err; pwm_duty += delta; if (pwm_duty > PWM_MAX) pwm_duty = PWM_MAX; /* 限幅必须有 */ if (pwm_duty < 0) pwm_duty = 0; return pwm_duty; }参数上,先只留 KP 把系统调到「有静差但稳定」,再慢慢加 KI 消除静差。KI 加太猛会出现转速过冲然后来回摆,这时候别急着降 KP,先把 KI 减半看看。还有个隐蔽的坑:PWM 周期和测速采样窗口如果没有整数倍关系,采样窗口里会截到不完整的 PWM 周期,测出来的转速带周期性噪声,看着像机械振动,其实是采样节拍的问题。
4.3 温度闭环:采样周期与 PID 参数整定
温度系统的特点是惯性大、滞后明显。加热器通电到传感器读数变化,中间可能差几秒甚至十几秒,这决定了采样周期不能太短(短了算出来的微分项全是噪声),也不能太长(长了响应跟不上)。工程上常用的是「采样周期取滞后时间的 1/10 左右」,实验台上一般落在 500ms 到 1s。
温度控制一般用位置式 PID,输出直接是加热功率或者通断占空比。整定顺序跟直流电机不同:先把 I 和 D 归零,加 P 到出现小幅等幅振荡,记下此时的临界比例度和振荡周期,再按经验公式折算出三个参数,最后手动微调。这个套路比盲试快得多,尤其是实验台这种一次实验只有两三个小时、没时间慢慢凑参数的场景。
积分饱和是温度控制里最常见的翻车点:设定值从室温跳到 80℃,误差长时间为正,积分项一路累加,等温度快到目标时积分已经大得离谱,结果冲过头再慢慢回落。解决办法是积分限幅——给积分项设一个上下界,或者误差超过某个阈值时暂停积分。微分项则要加一阶滤波,否则传感器的一点跳变会被放大成输出的大幅抖动。
4.4 双机通讯:8254 分频定波特率与 8251 初始化序列
双机通讯实验用两台实验装置,一台发一台收,发送机把 3000H~3009H 十个内存单元的数据发出去,接收机收到后直接在屏幕上显示。硬件上是 8251 串行接口加 8254 定时器:8251 的 CLK 由板上 1.8432MHz 时钟提供,8254 对这时钟分频后送 8251 的收发时钟引脚,分频比决定波特率。
波特率算起来很直接。设目标 9600bps,8251 方式字里选波特率因子 ×16,那么收发时钟需要 9600 × 16 = 153.6kHz;1.8432MHz ÷ 153.6kHz = 12,8254 的计数初值就是 12。8254 工作方式 2(分频器),初值 12 意味着每 12 个输入时钟出一个脉冲,正好是 153.6kHz。
; 8251 初始化:软复位 -> 方式字 -> 命令字,顺序不能颠倒 MOV DX, P8251_CTL MOV AL, 00H OUT DX, AL ; 连续写三个 00H OUT DX, AL OUT DX, AL MOV AL, 40H OUT DX, AL ; 内部复位命令 MOV AL, 0A1H ; 异步 ×16、8 位数据、无校验、1 位停止 OUT DX, AL MOV AL, 37H ; TxEN=1、DTR=1、RxEN=1、错误标志复位、RTS=1 OUT DX, AL方式字 A1H 的构成:D7D6=10 选异步 ×16,D5=1 表示 8 位数据,D4=0 关闭校验,D3D2=00 无校验,D1D0=01 一位停止位。命令字 37H 里 D4 那一位是错误标志复位,收发过程中出现溢出或帧错误,读状态字会看到对应位置 1,必须用这个命令清掉,否则错误标志一直挂着。
收发流程靠状态字轮询:D0 是 TxRDY(发送缓冲空),D1 是 RxRDY(收到一个字节),D2 是 TxEMPTY(发送移位寄存器空)。发送端等 TxRDY 置位再写数据口,接收端等 RxRDY 置位再读数据口。
WAIT_TX: MOV DX, P8251_CTL IN AL, DX TEST AL, 01H ; TxRDY JZ WAIT_TX MOV DX, P8251_DATA MOV AL, [SI] OUT DX, AL两台机器必须用同一组参数,而且地线要共。串口实验里最高频的故障是「一端能发一端收不到」,八成是波特率因子或者分频初值两边不一致,只剩不到两成是线接反了(TXD 对 TXD 而不是对 RXD)。
5. 避坑与排查:五个最容易在实验室里翻车的点
这些坑不是理论推导出来的,是一个个从实验台上踩出来的。写在这一章,是想让你在第一次接线上电之前就知道该往哪看。
5.1 接线与片选类
现象一:程序编译通过,读写端口毫无反应,读回值恒为 FF 或 00。原因多半是片选接错。实验箱上有 IOY0、IOY1、IOY2 几个译码输出,8255 的 CS 接 IOY0、8254 的 CS 接 IOY1,这是例程的约定,接反一位,程序里对 280H 的写操作跑到别的芯片上去了,8255 根本没被选中。排查办法很土但有效:把片选线拔下来,用万用表量实验箱上 IOY0 在访问 280H 段时是否拉低,不拉低就是地址段不对或者 CPU 没真正发出这个地址。
现象二:数码管全亮或者全灭,换段码表也没用。原因是共阴共阳搞反了。实验箱上的数码管多数是共阴,段码给高电平点亮;如果误当成共阳,写什么都是反的,看起来像全亮。另一个可能是位选接反——本该拉低选中的位选端,被接成了拉高,结果四个位永远同时亮,显示的是四个数的叠加。处理办法是先只点亮一位、给固定段码,确认单位能亮再扩展到四位。
现象三:点阵显示的字是镜像的,或者上下颠倒。原因是取模顺序和实际接线方向不匹配。教程规定最左边的点是 BIT0、四角顺序是左上右上左下右下,如果接线时把点阵的排线插反了,或者取模软件里选了「纵向取模」「高位在前」,字就是反的。别改程序去迁就,直接回取模工具把规则调成跟接线一致,然后重新生成字模,改程序只会越改越乱。
5.2 程序与时序类
现象四:8254 输出频率不对,发声跑调或者完全没声音。常见两个原因。一是控制字里的读写顺序位写错,8254 要求先低字节后高字节,写成先高后低,装进去的初值就完全不是算出来的那个数。二是方式选错,发声必须用方式 3(方波),选了方式 2(分频)输出的是窄脉冲,驱动扬声器声音很轻甚至听不见。排查时先用示波器看 OUT 引脚有没有波形,有波形但频率不对就是初值问题,没波形就是控制字或者片选问题。
现象五:键盘按一次,显示缓冲区里进了三四个数。机械按键的抖动持续几毫秒到十几毫秒,扫描程序跑得快,一次按下会被采样到好几次。解决办法是软件去抖:检测到有键按下后延时 10~20ms 再读一次,两次一致才算数;按键释放也要等一次。更稳的做法是加状态机——「空闲 → 疑似按下 → 确认按下 → 等待释放」,每个状态只在满足条件时迁移,比单纯延时可靠得多。
5.3 闭环与测量类
现象六:直流电机闭环一上电就来回振荡,参数怎么调都稳不住。先别怀疑 PID,怀疑采样。PWM 周期和测速窗口如果没有整数倍关系,每次采样截到的 PWM 周期数是变的,测出来的转速自带周期性误差,反馈信号本身就在抖,控制器怎么调都是抖的。把测速窗口设成 PWM 周期的整数倍,这个噪声就没了。另外测速脉冲的计数要用硬件计数器或者边沿中断,用轮询数脉冲在大占空比时会漏计。
6. 验收与答辩:怎么证明这套实验真的跑通了
答辩现场最容易出现的场景是:现象跑出来了,一问「这个初值怎么算的」就卡住。评委不看你的代码有多长,看的是现象、参数、原理三者能不能对上。所以验收准备应该倒着做——先从现象出发,反推需要用哪几个参数解释它。
下面这张表是我习惯用的验收清单,每一项都对应一个可以当场演示、当场解释的观测点。
| 实验项 | 观测点 | 合格判据 | 答辩要能答的参数 |
|---|---|---|---|
| 键盘扫描与显示 | 按键后数码管更新 | 连按 4 键,显示顺序正确、无重复触发 | 扫描周期、去抖时长 |
| 电子发声 | 扬声器输出乐曲 | 音高与曲谱一致,节拍均匀 | 计数初值公式、单位延时时长 |
| 点阵 LED | 汉字卷动显示 | 字形无镜像、无缺行、卷动连续 | 取模规则、每行停留时间 |
| 双机通讯 | 接收端屏幕打印 10 个数 | 数值与发送端内存一致,无乱码 | 波特率、分频初值、方式字 |
| 步进电机 | 按设定步数转动 | 转角误差在一步以内,无失步 | 拍序表、步间延时 |
| 直流电机调速 | 加载后转速回到设定值 | 阶跃响应无持续振荡 | 采样窗口、KP/KI 取值 |
| 温度闭环 | 温度稳定在设定值附近 | 超调小于设定值的 10% | 采样周期、积分限幅值 |
准备答辩有个技巧:把每个实验的「一个数」找出来。键盘实验的一个数是去抖延时,发声的一个数是计数初值,通讯的一个数是分频比 12,步进的一个数是步间延时。评委追问时,你把这个数怎么来的、改大了会怎样、改小了会怎样讲清楚,比背一遍原理管用得多。
还有一个我踩过的坑:演示顺序别按实验编号来,按「现象最直观」来。点阵显示汉字、扬声器放曲子、双机通讯打印数据,这三个现象一眼能看懂,先演这三个把印象立住,再演闭环类——闭环的调节过程需要时间,放在后面即使被追问也不慌。
我那之后每次带实验,都强制自己在上电前先走一遍「片选—基址—方式字」三查:片选线插在哪、端口基址是多少、控制字每一位什么意思。这三样对了,八成的问题根本不会发生。希望帮到你。
本文还有配套的精品资源,点击获取