简介:面向初学单片机或期末复习的读者,这份AT89C51汇编学习笔记压缩包,基于斐多课堂网课截图整理而成,覆盖除串口通信外的多数知识点,适合系统掌握8051单片机汇编编程。资源共174个文件,以164张PNG截图为主体,搭配2个md笔记文档、2个txt说明及许可证等辅助文件,压缩包大小83.9MB,文件命名按时间有序排列,便于对照课程章节浏览。已有111人学习,笔记包含定时器/计数器、中断系统、LED控制及按键输入等模块化讲解,并附有笔记.md快速预览和PDF导出版本,方便打印复习或离线查阅。整体而言,这套资料能帮助初学者在补天或课程设计中快速建立汇编编程的完整框架,减少看视频时反复暂停记笔记的负担。
1. 期末“补天”前,先把 AT89C51 单片机汇编笔记变成自己的索引
期末补天这件事,大多数人不是没听课,而是听完了等于没听。网课里讲 51 单片机的寻址方式,老师在屏幕上把 MOV 指令列表翻了三页,你截了四张图,关掉窗口就再没回去翻过。直到考前一周打开相册,面对几百张截图,才意识到你根本没建立知识点之间的连接。这个问题的根源在于截图是按时间线堆积的,可考试是按功能线出题的:寄存器配置、定时器初值、中断入口、查表算法,每一类都要能独立调用。所以正确的“补天”姿势,应该是先把所有截图重新分类,再按类别生成自己的速查索引,最后用汇编在 Keil5 里把每一种题型跑通。这篇笔记就是按这条思路展开的。
2. AT89C51 汇编笔记重建:先分清 ROM、RAM 和 SFR
网课第一节到第二节,一定会讲存储器结构。如果你只截下来一张图,那这张图就是整个汇编复习的根。AT89C51 汇编里几乎所有指令都在和三个区域打交道:ROM 放程序,RAM 放临时数据,SFR 控制片内外设。顺序搞反,后面的定时器、中断、串口全都会跟着乱。
2.1 把截图按“存储器地图”重排,而不是按网课顺序
AT89C51 片上有 4KB Flash、128B RAM 和一组 SFR 特殊功能寄存器。Flash 放编译后的机器码,复位后从 0000H 开始取指;RAM 的低 128 字节用来放变量、堆栈和位寻址区,地址范围 00H~7FH;SFR 区占据 80H~FFH,P0~P3、TMOD、TCON、IE、IP、SCON、SBUF 全住在里面。
整理截图时我一般不做课本章节复制,而是把所有涉及存储器分配的截图归为一组,自己压成一张总表。以下是期末复习最常用到的 SFR,考试考到寄存器配置时,先定位到这张表再动手写代码。
| SFR 名称 | 字节地址 | 主要作用 | 考试出镜率 |
|---|---|---|---|
| P0~P3 | 80H/90H/A0H/B0H | 4 个 8 位并行 I/O 口 | 极高 |
| TMOD | 89H | 定时器工作方式选择 | 极高 |
| TCON | 88H | 定时器运行控制与中断标志 | 高 |
| TH0/TL0 | 8CH/8AH | 定时器 0 初值高/低字节 | 高 |
| SCON | 98H | 串口控制寄存器 | 中 |
| SBUF | 99H | 串口收发缓冲寄存器 | 中 |
这张表是从几十张网课截图里提炼出来的最终形态。对照它去复习,比反复翻 PPT 截图有用得多,因为考试答题时需要的是“TMOD 地址是多少、里面每一位是什么含义”这种确定信息,而不是一张模糊的课堂板书照片。
2.2 寻址方式速记:用一条 MOV 串起七种写法
汇编语法里最容易丢分的就是寻址方式。考试经常给一条指令,问源操作数的寻址方式,或者直接让你用不同寻址方式写同一条数据访问。AT89C51 的七种寻址方式可以全部用 MOV 指令串起来复习:
MOV A, #3CH ; 立即数寻址:3CH 就是数据本身 MOV A, 30H ; 直接寻址:取 RAM 30H 单元的值 MOV A, R0 ; 寄存器寻址:R0 里的内容就是数据 MOV A, @R0 ; 寄存器间接寻址:R0 里存的是地址 MOV DPTR, #2000H ; 16 位立即数装入数据指针 MOV C, 20H ; 位寻址:操作对象是 RAM 20H 的某一位 MOVC A, @A+DPTR ; 变址寻址:查表专用指令@R0和R0的区别是新手翻车频率最高的一对。@R0表示 R0 里保存的是一个地址,读的是这个地址指向的存储单元;R0直接使用寄存器保存的值本身。位寻址区域有两块:RAM 的 20H~2FH 共 16 个字节,以及 SFR 中字节地址能被 8 整除的寄存器,比如 P0(80H)、TCON(88H)。答题时先判断操作数地址能不能被 8 整除,位寻址的题基本不会错。
注意:Keil 汇编器把十六进制数后忘写
H的值当作十进制处理,30H和30是两个完全不同的地址,考试写代码和上机仿真都要养成补H的习惯。
2.3 按真题频率重排指令表,而不是背网课目录
网课里指令系统按功能分类:数据传送、算术运算、逻辑运算、控制转移、位操作。期末复习必须把这个顺序倒过来,按真题出题频率排。我把常见指令分成三档,笔记里只详细整理高中频,低频指令考前浏览一遍即可。
高频指令:MOV、ADD、SUBB、CLR、SETB、LCALL、RET、DJNZ、CJNE、RL、RR、CPL、ANL、ORL。这些要能白纸默写,并且知道执行后对 PSW 中 CY、AC、OV、P 四个标志位的影响。中频指令:INC、DEC、SWAP、XCH、PUSH、POP、AJMP。低频指令容易出成判断和选择,比如 JB、JNB、JZ、JNZ,只需要记住“哪个位为 1 跳转”“哪个标志为 0 跳转”即可。
纸面背指令记不牢,我的习惯是每背一组就在 Keil5 里敲一行、编译一下,再看 Simulation 窗口里 A、PSW 寄存器的变化。汇编语法检查通过只代表拼写没错,不等于逻辑对,只有单步执行观察寄存器变化,指令行为才会真正变成长期记忆。
2.4 从网课截图里抽出“一句话注释”,重写执行结果
网课里的指令注释基本都是“将立即数送入累加器”这种官方说法,它没有告诉你执行后标志位变成了什么。处理截图时,我会强制自己把每条注意的指令改写成一个带执行结果的注释,这个动作比截图本身重要得多。
MOV A, #80H ; 改写后的注释:A=80H,Z=0 ADD A, #80H ; 改写后的注释:A=00H,CY=1,OV=1,Z=1改写注释的价值在碰到类似指令时才会体现:如果你只写“累加器加立即数”,溢出和进位对你毫无警示;一旦用自己的手算结果把标志位标在旁边,做判断类题目时就不会再错。网课截图里老师顺手写的“注意进位”,信息密度远不如自己算一遍写下的CY=1。
3. 把网课截图的流水灯代码在 Keil5 里跑成最小 .asm
听懂了网课和跑通了工程是两回事。流水灯是 AT89C51 汇编里第一道必须自己上机过的程序,它同时覆盖 I/O 输出、循环跳转、子程序调用和软件延时四个考点。我建议直接在 Keil5 里建一个最小工程,从新建文件到生成 HEX 全流程走一遍,这比对着截图背十遍都有效。
3.1 先把人话翻译成伪代码,再转汇编
网课老师在黑板上画流水灯电路图,P1 口每根引脚接一个 LED 和限流电阻,通常是低电平点亮。电气接线先不管,解题思路直接写伪代码:
上电: 累加器 A 中放入 1111 1110,最低位是 0 循环: 把 A 的值输出到 P1 延时约 100ms A 循环左移一位伪代码的好处是忽略寄存器细节,先把算法定下来。确定“最低位点亮”之后,下一步才是选指令。延时部分可长可短,为了观察方便取 100ms 左右;数据左移用 RL 指令,它不带进位循环左移,正好符合流水灯从 P1.0 到 P1.7 循环点亮的需求。
3.2 最小可编译的流水灯汇编程序,带注释
完整代码可以直接复制进 Keil5,从复位入口到无限循环,包含全部必需段:
ORG 0000H ; 复位后第一条指令的地址 LJMP START ; 长跳转到主程序,跳过中断向量区 ORG 0030H ; 主程序起始地址 START: MOV A, #0FEH ; 1111 1110,P1.0 先输出低电平 LOOP: MOV P1, A ; 把 A 的内容送到 P1 口 LCALL DELAY ; 调用延时子程序 RL A ; A 循环左移一位,点亮下一盏 LED SJMP LOOP ; 无限循环 DELAY: MOV R7, #200 ; 外循环计数值 D1: MOV R6, #250 ; 内循环计数值 D2: DJNZ R6, D2 ; R6 减 1,不为 0 继续内循环 DJNZ R7, D1 ; R7 减 1,不为 0 继续外循环 RET ; 子程序返回 END ; 源程序结束ORG 0000H保证复位后从零地址开始执行;LJMP START必须用长跳,因为从 0000H 到主程序之间要留出 8 个中断向量入口,普通短跳转跳不到 0030H 那么远。MOV P1, A属于直接寻址,P1 是 SFR,地址在 90H;LCALL DELAY是长调用,子程序在 64KB 空间任意位置都能被调用。DJNZ R6, D2一条指令完成减一和条件跳转两个操作,是汇编循环的支柱指令。
3.3 Keil5 工程五个步骤和三个隐藏坑
Keil5 安装教程网上很多,这里只记建 51 工程时容易出错的步骤:
- New µVision Project,芯片型号选 AT89C51,也可以选 AT89C52,寄存器定义完全兼容。
- 新建源文件,保存时扩展名必须写成
.asm,写成.c或.txt都不会被编译。 - Options for Target → Output 勾选 Create HEX File,否则烧录时找不到目标文件。
- 在左侧文件树把源文件添加到 Source Group。
- 按 F7 编译,看到 0 Error(s) 后进入 Debug 模式单步执行。
三个隐藏坑:第一,漏勾 Create HEX File,这是期末上机最常见的翻车点;第二,ORG 0030H被写成ORG 30,Keil 按十进制处理,程序入口直接偏到 1EH,中断向量区被踩烂;第三,芯片型号选成 STC89C52,增强型 SFR 多出不少,虽然基础代码能运行,但和 AT89C51 的题目要求存在细微信号差别,上机考试建议严格按题目选型。
3.4 12MHz 晶振下延时精度到底怎么算
延时计算是期末考场上最常见的填空和简答题。AT89C51 的机器周期是 12 个晶振周期,外部晶振 12MHz 时,一个机器周期正好是 1µs。常用指令的执行时间需要背熟:
| 指令 | 机器周期数 | 12MHz 晶振下耗时 |
|---|---|---|
| MOV A, #data | 1 | 1µs |
| MOV direct, #data | 2 | 2µs |
| DJNZ Rn, rel | 2 | 2µs |
| LCALL addr16 | 2 | 2µs |
| RET | 2 | 2µs |
用前面的流水灯代码估算:内层MOV R6,#250耗时 1µs,DJNZ R6,D2每次 2µs,250 次约 500µs;外层再乘 200,总延时约 100ms。这个数值足够肉眼观察。如果你用 Proteus 仿真 51 单片机测量,会看到实际延时略大于理论值,因为调用LCALL和返回RET本身占用的周期没有计入。需要精确延时的场合,优先用后面第 4 章讲的定时器,而不是加大软件循环圈数。
4. 从截图笔记到可执行程序:定时器和矩阵键盘的考试高频写法
定时器和矩阵键盘是《单片机原理及应用》考得最密的两块。前者考配置流程,后者考 I/O 读写顺序,两者在网课截图里出现的频率也最高。考试时这两道题能拿满分的同学,通常不是背代码最熟的人,而是会把配置步骤拆成固定顺序的人。
4.1 定时器配置五步,一步都不能少
配置定时器 0 的方式 1,也就是 16 位定时模式时,核心顺序是:选方式、装初值、开中断、启动、重装初值。漏掉第五步是考场丢分最大的源头。下面是一段 50ms 定时中断的完整代码:
ORG 0000H LJMP MAIN ORG 000BH ; 定时器 0 中断入口地址 LJMP T0_ISR ORG 0030H MAIN: MOV TMOD, #01H ; T0 工作方式 1,16 位定时 MOV TH0, #3CH ; 初值高字节 MOV TL0, #0B0H ; 初值低字节,整体 3CB0H SETB ET0 ; 允许定时器 0 中断 SETB EA ; 开放总中断 SETB TR0 ; 启动定时器 0 SJMP $ ; 主程序空转,等待中断 T0_ISR: CPL P1.0 ; P1.0 取反,输出方波 MOV TH0, #3CH ; 方式 1 没有自动重装,必须手动恢复初值 MOV TL0, #0B0H RETI ; 中断返回 END初值计算逻辑要写在代码旁边:方式 1 是 16 位计数器,最大计数值 65536。定时 50ms 需要计数 50000 个机器周期,因为 12MHz 晶振下 1 个机器周期是 1µs,所以初值等于 65536 减 50000,结果是 15536,转十六进制就是 3CB0H。MOV TMOD,#01H里的 01H 表示定时器 0 工作在方式 1,定时器 1 保持默认方式 0,两个定时器共享一个 TMOD 字节,改写时不要互相覆盖。
中断服务程序里重新装初值是方式 1 的硬性要求。计数器溢出后 TH0/TL0 会自动回到 0000H,不重新赋值的话,下一次溢出时间就变成 65536 个周期,方波频率立刻跑偏。如果改用方式 2 的 8 位自动重装,只需写 TH0,TL0 溢出后自动从 TH0 加载,省掉重装指令,但定时范围只有 256µs。
4.2 中断向量表和优先级,考前背这张表就够
AT89C51 有 5 个中断源,中断入口地址是期末默写题的高频考点。中断系统需要关心中断入口和允许位的对应关系,以及重置后的优先级顺序:
| 中断源 | 入口地址 | 使能位 | 默认优先级 |
|---|---|---|---|
| 外部中断 0 | 0003H | EX0 | 1,最高 |
| 定时器 0 | 000BH | ET0 | 2 |
| 外部中断 1 | 0013H | EX1 | 3 |
| 定时器 1 | 001BH | ET1 | 4 |
| 串口 | 0023H | ES | 5,最低 |
考试碰到“写出某个中断服务程序的入口地址”这类题,直接对照这张表。还要记住 IP 寄存器可以调整优先级,复位后默认为全低优先级;多个同级中断同时请求时,查询顺序按表中编号从前到后。判断先响应哪条中断,要先看 IP 配置,而不是只看入口地址谁靠前。
4.3 矩阵键盘行列扫描的汇编写法,避开两个典型错
矩阵键盘常用 P1 口的 8 根线接 4×4 键盘,行接高四位、列接低四位。扫描思路是:先让所有行为低,读列判断是否有键按下;确认有键后,逐行置低、逐列读回,确定按键坐标。
; 假设 P1 高四位接行,低四位接列 KEY_SCAN: MOV P1, #0FH ; 高四位输出低电平,低四位设为输入 MOV A, P1 ANL A, #0FH ; 屏蔽高四位,只保留列电平 CJNE A, #0FH, KEY_DEBOUNCE ; 有列变低说明有键按下 MOV R7, #0FFH ; 返回 0FFH 表示无按键 RET KEY_DEBOUNCE: LCALL DELAY ; 调用 10ms 延时消抖 MOV A, P1 ANL A, #0FH CJNE A, #0FH, KEY_CONFIRM ; 二次确认确实有键 MOV R7, #0FFH RET KEY_CONFIRM: ; 到这里确认有键按下 ; 后续逐行扫描:P1.4 置 0,读 P1.0~P1.3 判断行号 ...两个典型错:第一,MOV P1,#0FH之后立刻读引脚,没有给电平稳定时间,在 Proteus 仿真 51 单片机时可能读到上一次的输出值,需要插入几条 NOP 空操作延时;第二,写循环逐行扫描时,容易把已经输出过的行状态带到下一次读列,导致键号判断错乱。每次扫描前都要重新设置行输出值,不要复用上一次的 P1 状态。
4.4 数码管段码查表:把截图里的表存成 ROM 查表结构
数码管显示部分是网课截图出现频率最高的内容之一,核心就是一张 0~9 的段码表。共阴七段数码管的段码常见如下:
TAB: DB 3FH, 06H, 5BH, 4FH, 66H ; 0 1 2 3 4 DB 6DH, 7DH, 07H, 7FH, 6FH ; 5 6 7 8 9查表时先用 A 保存数字索引,DPTR 载入表格起始地址,再执行MOVC A, @A+DPTR,A 里得到的才是要送出到 P0 或 P2 口的段码。MOVC的 C 代表 Code,访问的是程序存储器,不是 RAM 或 SFR,这是变址寻址方式在考试中的标准用法。表里放错一位数字,数码管就会显示成错位字符。考前把 0~9 的段码手写一遍,再和网课截图比对,通常能发现原图本身就有一两处错误。
5. 把截图整理成能带走的 zip:考前 30 小时把素材合进一棵目录树
5.1 截图命名用“考点_引脚_行为”三段式
补天的最后阶段,最浪费时间的动作是在几十张命名相同的Screenshot_20241201_142358.png里翻找某张定时器截图。我一般把相册里的截图全部导到一个临时文件夹,用三段式重命名:考点名称、引脚或寄存器名、预期行为。举几个例子:定时器_TCON_TR0_启动计数.png、流水灯_P1_循环左移效果图.png、中断_入口地址_0003H外部中断0.png。
这样文件管理器排序出来的结果就是按知识点的逻辑顺序,而不是按拍摄时间。批量重命名可以用 Everything 工具,或者写一个简单的 Python 脚本递归改名,先把文件名中的日期戳替换成知识点前缀。命名这一步做完,zip 里的目录本身就是一份复习大纲。
5.2 压缩成 zip 前做一次“减重”
不是所有截图都值得留在压缩包里。网课截图中属于“老师手写演算”和“PPT 整页文字”的两类,考前几天复习价值很低,只各留一张串联章节即可。真正值得保留的是:指令表截图、寻址方式对照、中断向量表、定时器初值计算过程、数码管段码、电路接线原理图。
整理完成后,按下面的结构打包:
AT89C51期末补天/ ├── 00-考前速查/ ├── 01-存储器与寻址方式/ ├── 02-指令表与延时/ ├── 03-流水灯与I/O口/ ├── 04-定时器与中断/ ├── 05-矩阵键盘与数码管/ └── 06-真题错题/zip 内置的目录结构加上三位数字编号,保证在任何设备上解压后都能按顺序浏览。不要在压缩包里放网课视频的转码文件,那不是索引,是备份。
5.3 考前 3 小时的复查动作
zip 建好之后,考前 3 小时的用法不是再看一遍截图,而是带着问题验证。打开 Keil5,挑三个高频代码片段:流水灯、定时器翻转、矩阵键盘读列。对着 zip 里的截图,口述每一条指令的机器周期数和标志位变化。能口述清楚的截图保留,卡壳的就是最后一轮复习的突破点。最后打开 Proteus,把流水灯程序重新仿真一遍,观察 P1 口的波形频率是否和笔记里计算的延时一致。一致,说明这套笔记闭环了;不一致,马上回查延时公式和初值计算,问题通常出在漏算了调用指令本身的周期。
本文还有配套的精品资源,点击获取