
简介这份实验指导书面向高校电子信息、自动化等专业学生及嵌入式初学者系统梳理了嵌入式系统课程实验的完整流程与规范要求。压缩包内为1个doc文档约965KB内容围绕6个实验展开从实验目的、设备、原理环境到内容、步骤及报告格式均有明确说明。其中实验一以Keil C51汇编语言为切入点讲解工程建立、源文件添加、编译连接与软硬件仿真调试并给出在P1.0、P1.1输出1Hz方波的具体任务后续实验涉及十六进制与十进制转换等顺序结构编程训练。文档还细化了预习报告、程序清单与实验总结的撰写要求便于读者按步骤完成实验并规范记录调试过程。目前已有338人学习下载适合作为课程配套练习与自学参考。1. 零基础也能上手的嵌入式实验从点亮一个引脚开始很多人第一次听到“嵌入式系统”这四个字脑子里冒出来的画面是电路板、示波器、一堆看不懂的汇编指令然后本能地觉得自己学不会。其实换个角度想你家里的洗衣机、微波炉、空调遥控器里面都藏着一颗小小的单片机它们做的事情无非是“读一个输入、做一个判断、控制一个输出”。这份《嵌入式系统实验指导书6个实验》就是把这件事拆成了六个可以动手的小任务从最简单的“让一个引脚输出方波”开始一步步带你摸到门道。它适合完全没有接触过单片机、但愿意动手敲几行代码的新手也适合刚开课、面对实验箱不知道从哪按起的学生。你不需要先学完什么高深理论跟着实验顺序走第一个实验就能让你看到自己写的程序真正跑起来。2. 为什么值得从这份指导书入手先弄懂它在练什么2.1 它练的不是“背指令”而是“建立完整开发闭环”很多新手学嵌入式容易陷入一个误区抱着教材从指令系统开始背背了半个月连一个工程都没建过。这份指导书的编排逻辑恰好相反它把每个实验都拆成“预习写程序 → 建工程编译 → 软件仿真 → 硬件运行 → 写实验报告”这样一条完整的链路。你从实验 1 开始就要走一遍这个流程走完六个实验你脑子里形成的是一套肌肉记忆拿到一个需求知道先建工程、选芯片、写源文件、编译排错、再上硬件验证。这个闭环比记住多少条汇编指令都值钱因为后面你换任何一款单片机流程都是同一套。实验 1 用的是 Keil C51 环境加汇编语言目标是在 P1.0 引脚上输出一个 1Hz 的方波。听起来简单但它逼着你把“工程怎么建、芯片怎么选、晶振频率怎么设、HEX 文件怎么生成”这些最琐碎也最容易卡住新手的环节全部走一遍。我第一次学的时候光是在 Keil 里找到“生成 HEX 文件”那个勾选项就翻了半天菜单这种血泪经验只有亲手做过才会变成自己的。2.2 六个实验是一条递进线不是六个孤立任务你如果只看单个实验会觉得“十六进制转十进制”“LED 动态显示”“矩阵键盘”“A/D 转换”各干各的。但顺着做下来会发现实验 3 写的 LED 显示子程序实验 4 的键盘扫描程序要直接调用它实验 5 的 A/D 转换结果又要送到实验 3 的显示器上去显示。也就是说这份指导书在悄悄教你一件事嵌入式程序是攒出来的子程序是可以复用的。实验 4 的正文里明确写了“显示子程序使用实验 3 中的显示子程序”实验 5 也写了“显示子程序可以用实验 3 中的子程序”。这种复用意识是新手从“能跑一个例子”过渡到“能做一个东西”的关键一步。2.3 软件仿真兜底没有硬件也能先跑起来新手最怕的情况是手头没有实验箱或者硬件连好了但不亮根本不知道是程序错了还是线接错了。这份指导书在实验 1 的原理部分就讲清楚了Keil C51 既可以连硬件跑也可以不连硬件、纯在电脑上做虚拟仿真。实验 2 更是直接注明“可以不用硬件连接以软件仿真的方法即可进行”。这意味着你完全可以先在自己的电脑上把前两个实验跑通看到存储器窗口里 30H、31H、32H、33H 的值随着单步执行而变化确认程序逻辑没问题再去碰硬件。这个“先软后硬”的顺序能帮你把大部分语法错误和逻辑错误挡在接电线之前少走很多弯路。3. 第一个例子怎么跑从建工程到 P1.0 输出方波3.1 先把开发环境搭起来你需要两样东西一台装了 Keil C51 的电脑以及可选一台单片机实验箱。如果暂时没有实验箱完全不影响你跑通第一个例子因为实验 1 的前半段用软件仿真就能验证。打开 Keil 之后第一步是建工程点 Project → New Project选一个你记得住的文件夹比如 E:\TEST工程名起成 test。接着会弹出一个选芯片的窗口厂家选 Atmel型号选 89C51。选完之后在工程选项里把晶振频率改成 12MHz并且在 Output 标签页里勾上“生成 HEX 文件”。这两步别漏晶振频率影响后面延时的计算HEX 文件是烧到硬件上要用的格式。提示工程路径尽量用英文不要带空格和中文否则编译时偶尔会报一些莫名其妙的错这是很多人踩过的坑。3.2 写第一段汇编程序新建一个源文件File → New把下面这段代码敲进去。这段程序做的事情就是让 P1.0 这个引脚的电平不停地翻转翻转之间加一段延时从而形成一个 1Hz 左右的方波。ORG 0000H ; 程序从 0000H 地址开始执行 AGAIN: CPL P1.0 ; 对 P1.0 取反高变低、低变高 MOV R0, #10 ; 外层延时计数配合内层循环凑出约 0.5 秒 LOOP1: MOV R1, #100 LOOP2: MOV R2, #250 DJNZ R2, $ ; R2 减到 0 之前原地循环 DJNZ R1, LOOP2 DJNZ R0, LOOP1 SJMP AGAIN ; 跳回 AGAIN无限循环 END逐行解释一下关键点。ORG 0000H是告诉编译器程序从地址 0 开始放这份指导书里每个实验都要求起始地址为 0000H。CPL P1.0是核心动作把 P1.0 的电平取反原来高就变低、原来低就变高。后面三层MOV加DJNZ构成一个嵌套循环靠消耗指令周期来“拖时间”让每次翻转之间隔大约 0.5 秒两次翻转就是一个完整周期所以频率约 1Hz。SJMP AGAIN让程序跑完一轮又跳回开头永不停止。写完之后用 File → Save As 存成 test.asm注意扩展名是 .asm不是 .txt。3.3 把源文件加进工程并编译源文件存好了还不算工程的一部分得手动加进去。在左侧工程窗口里点 Target 1 前面的加号看到 Source Group 1右键它选 Add Files to Group找到刚才的 test.asm 加进来然后关掉对话框。接着点 Project → Build target 开始编译。如果代码没敲错下面的输出窗口会显示 0 Error(s)并且生成 OBJ、LST、HEX 等文件。如果报错最常见的原因是标点符号用了中文全角比如把英文逗号敲成了中文逗号或者数字 0 和字母 o 混了。指导书的重要提示里专门强调了这一点别不当回事这种错编译器给的提示往往很含糊找起来特别费劲。3.4 软件仿真看结果编译通过后点 Debug → Start/Stop Debug Session 进入仿真模式。这时候你可以单步执行观察 P1.0 的状态怎么变。想看端口状态打开 View → Memory Window在地址栏输入p1或者直接看左侧的寄存器/端口面板。每按一次单步CPL 执行后 P1.0 就翻转一次。虽然软件仿真看不到真实的 LED 亮灭但你能确认程序逻辑是对的引脚确实在翻转延时循环确实在跑。这一步过了再连硬件就有底气了。3.5 上硬件验证有实验箱的话把串口线连好、通电拨位开关 K10 拨到 B 端用导线把 P1.0 接到 L00LED 指示灯P1.1 接到 L01。然后在工程选项的 Debug 标签页里把调试方式改成硬件实时仿真重新进入调试连续运行就能看到 L00 对应的灯以大约 1 秒的节奏亮灭。实验 1 的最后一个内容是让你改程序让 P1.0 和 P1.1 输出频率相同但电平相反的方波思路很简单在 CPL P1.0 后面再加一条 CPL P1.1两个引脚就会始终保持相反状态。这个改动虽小但它是你第一次“改需求、改代码、再验证”的完整练习。4. 中间几个实验怎么跟显示、按键与采样的递进练法4.1 实验 2用单步调试看懂数据在内存里怎么搬实验 2 要求把片内 RAM 30H 里的一个两位十六进制数转换成三位十进制数按高位到低位放进 31H 到 33H。原理不复杂依次除以 100、除以 10商和最后的余数就是各位十进制数字。但这个实验的真正价值在于它强制你用单步方式运行并且打开存储器窗口观察每个单元的变化。操作上先建工程、加入你预习时写好的 .asm 文件然后 View → Memory Window 调出存储器编辑窗口在地址栏输入d:30H就能看到片内 RAM 从 30H 开始的内容。右键某个数据选 Modify Memory at可以把 30H 改成你想测试的值比如 0FFH。然后在关键指令上设断点Debug → Insert/Remove Breakpoint运行到断点停下来再一步步单步走盯着 31H、32H、33H 的值怎么被写进去。这个实验不需要硬件纯软件仿真就能完成特别适合手头没设备的时候练手。它教你的其实是一个通用技能当程序结果不对时不要靠猜打开存储器窗口看数据到底变成了什么这是嵌入式调试里最朴素的“后悔药”。4.2 实验 3动态扫描显示理解“看起来同时亮”的真相实验 3 是六个实验里信息量最大的一个。实验箱上有 6 位 8 段 LED 显示器采用动态驱动同一时刻其实只有一位在亮但因为切换速度足够快刷新频率不低于 50Hz人眼看起来就是六位同时亮着。这个原理新手一定要先想通否则写程序时会困惑“为什么我要一位一位地送数据”。硬件连接上8255 的 B 口驱动各段低电平发光A 口驱动各位低电平选中A、B、C、控制口的地址分别是片外 RAM 的 4000H、4001H、4002H、4003H。显示子程序的入口约定是待显示的数放在 20H 到 25H 这六个单元里每个单元的值是 00H 到 1FH对应字形表里的 0 到 F、0. 到 F.、横杠和灭。子程序要做的是取 20H 的值查字形表得到段码送到 4001H同时把位选码送到 4000H 选中第一位延时约 0.5 毫秒关掉所有位指针移到 21H位选码左移一位选第二位重复直到六位都刷完一遍再返回。字形表在指导书里给全了比如数字 0 的段码是 C0H数字 1 是 F9H照着抄进程序就行。主程序负责初始化 8255A 口、B 口方式 0 输出然后反复调用显示子程序。实验内容 3 还要求做一个“0 到 F 向左移动”的效果每过大约 1 秒把 20H 到 25H 的内容整体左移一位最低位补一个新数字再继续调用显示。这里有个容易翻车的地方移动用的循环计数单元不能和显示子程序里用到的 R0、R1、R2 冲突否则显示会乱。指导书的重要提示里专门点了这一条我第一次做的时候就因为复用了 R1屏幕上的数字跳得毫无规律查了半天才发现是寄存器打架。4.3 实验 4矩阵键盘把“按了哪个键”翻译成数字实验 4 的键盘是 4 行乘 4 列行接 8255 的 PC0 到 PC3列接 PC4 到 PC7。扫描思路是每次只让一列为低电平、其余列为高然后读行状态如果某一行变成低电平说明那一行和当前列交叉处的键被按下了。为了防抖读到低电平后要延时 20 毫秒再读一次两次一致才认。查键值子程序把“列驱动码 行状态”这个组合翻译成 00H 到 0FH 的键值指导书里直接给了一段可用的 KEY20 子程序入口是累加器 A 高 4 位放列驱动码、低 4 位放行状态出口 A 里就是键值。主程序的结构是初始化 8255A 口、B 口方式 0 输出C 口高 4 位输出、低 4 位输入然后循环调用显示子程序和键盘扫描子程序。扫描返回 FFH 表示没按键返回其他值就把这个值移进显示缓冲区的最右端实现“按一个键、显示器右端移入一个数”的效果。这里的关键细节是判断有没有键按下看的是行状态对应位是不是 0读行状态直到键松开时只有低 4 位有效高 4 位是不定的必须滤掉否则会误判成一直有键按着。4.4 实验 5A/D 转换把电压变成看得懂的数字实验 5 用 ADC0809 把电位器分压出来的 0 到 5V 模拟电压转成数字量。接口参数很明确写任意数到 8004H 启动 IN4 通道的转换读 8004H 取结果转换结束信号 EOC 经过一个反相器接到 P1.0。所以程序流程是先写 8004H 启动转换然后查询 P1.0等它变成有效电平说明转换结束再读 8004H 拿到 8 位数字量。拿到之后套用实验 2 的十六进制转十进制思路把这个数拆成三位十进制送到显示缓冲区第四到第六位用实验 3 的显示子程序显示出来。这个实验把前面几个实验的成果串在了一起转换逻辑来自实验 2显示靠实验 3是整份指导书里最能体现“攒程序”思路的一个。5. 新手最容易踩的坑排查清单5.1 编译报一堆错提示还看不懂现象Build 之后输出窗口红字一片提示的行号对不上或者根本看不懂。原因九成是标点符号用了中文全角比如逗号、分号、冒号或者数字 0 和字母 o 混用。汇编器对这类字符非常敏感但报错信息往往指向下一行让人误以为是别的地方错了。解决把输入法切到英文再敲代码或者写完之后全局搜一遍中文标点养成习惯指令和操作数之间的分隔符一律用英文半角。5.2 改了程序硬件上跑出来还是旧结果现象明明改了代码、编译也通过了连上硬件运行效果和改之前一模一样。原因改完程序后没有退出硬件连接就重新编译或者编译了但没有重新建立连接硬件里跑的还是上一次烧进去的旧程序。解决指导书的重要提示里反复写了对程序修改后必须退出连接、重新编译、再重新连接才能生效。养成“改代码 → 退出调试 → 编译 → 重新进调试”的固定动作别偷懒。5.3 显示乱跳或者键盘不响应现象LED 显示的数字毫无规律地闪或者按键盘完全没反应。原因多半是寄存器或内存单元冲突。显示子程序占用了 R0、R1、R2主程序里的延时循环如果也用这几个寄存器两边就会互相踩。键盘实验里如果扫描程序和显示程序共用同一个计数单元也会出现类似问题。解决给每个子程序划定专用的工作寄存器组或内存单元主程序的循环计数换用别的寄存器或者在调用子程序前把用到的寄存器压栈保护。5.4 硬件连好了但灯不亮、屏不显示现象程序编译没问题仿真也正常一接硬件就没反应。原因可能是接线没接对比如 P0.0 到 P0.7 没有和 JD0 到 JD7 对应连上可能是拨位开关 KC 没有倒向上方也可能是连接前没有按复位键 SS10。解决按指导书的步骤逐条核对接线确认 KC 的位置连接前和退出前都按一次 SS10 复位。硬件问题排查的顺序永远是先看线、再看开关、最后怀疑程序。5.5 延时时间对不上方波频率差很多现象程序里按 12MHz 算的延时实际跑出来方波快很多或慢很多。原因晶振频率在工程选项里没有设成 12MHz或者延时循环的层数和初值是照抄的、没有根据实际指令周期核算。解决回到 Project → Options for Target在 Target 标签页确认晶振频率是 12MHz延时循环的初值可以先用仿真单步估算再上硬件微调别指望一次就精确。6. 做完六个实验之后下一步往哪走六个实验跟下来你手里其实已经攒了一套能复用的东西一个显示子程序、一个键盘扫描子程序、一个十六进制转十进制的转换思路、一个 A/D 采样的查询流程。下一步最值得做的事不是急着去学新的芯片而是把这几个模块拼成一个稍微完整一点的小系统。比如做一个“按键设定数值、显示器实时显示、电位器调节另一路数值”的小作品主程序里同时调用键盘扫描和显示刷新中间用标志位协调。这个练习会逼你面对一个新问题多个任务怎么在一个主循环里轮流跑而不互相卡死。这正是从“做实验”过渡到“做项目”的门槛。具体的学习路径可以这样安排先把实验 3 的显示子程序改写成带参数入口的版本让调用者指定显示缓冲区的位置而不是写死在 20H再把实验 4 的键盘扫描改成带返回值的函数式写法主程序根据返回值做不同分支然后尝试把实验 5 的 A/D 采样从“查询等待”改成“定时采样”用一个定时器中断去触发。每一步改动都不大但每一步都在把你从“照着指导书敲”往“自己设计程序结构”推。我第一次带新人做这些实验的时候犯过一个很典型的错误总想着一次把主程序写完整结果调试时一出问题就不知道是哪一块的锅。后来我养成了一个习惯每加一个新模块先单独验证它能跑再合进主程序合进去之后如果出问题至少能确定是新模块引入的。从那以后我每次拼程序都强制走一遍“单独验证再合并”的流程翻车次数少了很多。希望这份指导书也能帮你把第一步迈稳先从实验 1 的那个方波开始跑通了再往下走别贪快。本文还有配套的精品资源点击获取