作者 | 将狼才鲸 |
---|---|
创建日期 | 2022-04-09 |
Gitee文档源码地址:embedded-knowledge-wiki/ documents / 2.3.1.1_c51编程.md
CSDN文章阅读地址:
B站视频讲解(待完成):才鲸嵌入式
这篇文章是一系列文章中的一部分,文章根入口:才鲸嵌入式 / 嵌入式知识图谱WiKi
为什么51单片机的地址总线是16位的,但是它却是8位机?
不想使用盗版Keil的话,可以尝试使用SDCC开源编译器,只是没有IDE,还需要自己编写Makefile进行编译。
C51 开源编译器SDCC学习笔记-安装
开源SDCC编译器(一)–基本介绍
还在用Keil做51单片机开发吗?快来试试开源的SDCC吧
SDCC下载地址
SDCC使用说明
如果你只是自己学习,也可以控制将程序编译在2k的范围内(c51总共也才只支持64k的代码容量),去keil官方下载软件试用。
Keil C51官方下载地址(评估版只能编译2k的代码)
启动流程:
8051 MCU学习之分析单片机的启动过程
C51资源:
51单片机知识重点汇总一,干货分享,学习单片机必懂知识
51单片机CPU的基本构成及作用
mcs-51单片机CPU的内部结构及工作原理
51单片机CPU结构各部件的原理详细分析
第一章C51系列单片机的硬件结构
51单片机的内部硬件结构(CPU工作原理,储存器结构,51,52和89C51,89S51型号对比)
典型芯片:AT89C51
C51寄存器:
C51 特殊功能寄存器
51单片机寄存器一览表
【实用】51单片机寄存器功能一览表
寄存器一般使用格式
地址分为ROM地址和RAM地址,最大16位64K。
RAM:
地址 | 大小 | 描述 | 备注 |
---|---|---|---|
0x00~0x2F | 32 | 工作寄存器地址 | 4组R0~R7寄存器 |
0x20~0x2F | 16 | 位寻址 | 为了让寄存器可直接位寻址,用SBIT设置 |
0x30~0x7F | 48 | 内部RAM | IRAM,可设置为堆栈 |
0x80~0xFF | 128 | 内部RAM和特殊寄存器共用 | IRAM、SFR |
0x0100~0xFFFF | 65280B | 外部RAM | RAM |
地址 | 大小 | 描述 | 备注 |
---|---|---|---|
0x0000~0x0FFF | 4KB | 内部ROM | IROM |
0x1000~0xFFFF | 60KB | 外部ROM | ROM |
C51单片机的寄存器 | ||
---|---|---|
符号 | 地址 | 功能介绍 |
R0~R7 | 0x00~0x2F | 工作寄存器地址 |
位寻址 | 0x20~0x2F | 你操作0x00~0x7F这128个的位地址, 实际上操作的就是这里16个字节里面的位 |
堆栈或内部RAM | 0x30~0x7F | |
P0 | 80H | P0口锁存器 |
SP | 81H | 堆栈指针 |
DPL | 82H | 数据地址指针(低8位) |
DPH | 83H | 数据地址指针(高8位) |
PCON | 87H | 电源控制寄存器 |
TCON | 88H | T0、T1定时器/计数器控制寄存器 |
TMOD | 89H | T0、T1定时器/计数器方式控制寄存器 |
TL0 | 8AH | 定时器/计数器0(低8位) |
TL1 | 8BH | 定时器/计数器0(高8位) |
TH0 | 8CH | 定时器/计数器1(低8位) |
TH1 | 8DH | 定时器/计数器1(高8位) |
P1 | 90H | P1口锁存器 |
SCON | 98H | 串行口控制寄存器 |
SBUF | 99H | 串行口锁存器 |
P2 | A0H | P2口锁存器 |
IE | A8H | 中断允许控制寄存器 |
P3 | B0H | P3口锁存器 |
IP | B8H | 中断优先级控制寄存器 |
PSW | D0H | 程序状态字 |
ACC | E0H | 累加器 |
B | F0H | B寄存器 |
51单片机寄存器功能一览表
C51/C52 特殊功能寄存器表
指令代码 | 指令长度 | 指令周期 | 助记符 | 操作对象 | 描述 | 举例 |
---|---|---|---|---|---|---|
00 | 1 | 1 | NOP | 无 | 延时1个指令周期的时间 | NOP ; 延时 |
01 | 2 | 2 | AJMP | addr11 | 短跳转,绝对转移,地址范围0xXX±0x000~07FF,转移范围为当前指令地址高5位相同的2K范围 | AJMP ADDR1 |
02 | 3 | 2 | LJMP | addr16 | 全域跳转,可以跳转到64K范围所有绝对地址,后面常用自定义的标号跳转 | LJMP ADDR2 |
03 | 1 | 1 | RR | A | 累加器循环右移,实际上也是除以2 | |
04 | 1 | 1 | INC | A | 累加器自增1 | 可用作循环处理 |
05 | 2 | 1 | INC | direct | 将给出地址当中的数据自增1(自增完后放回原处) | 同上 |
06 | 1 | 1 | INC | @R0 | 将R0中的数据当作地址,将这个地址中的数据自增1 | 同上 |
07 | 1 | 1 | INC | @R1 | 同上 | 同上 |
08 | 1 | 1 | INC | R0 | 将R0中的数据自增1 | 同上 |
09 | 1 | 1 | INC | R1 | 同上 | 同上 |
0A | 1 | 1 | INC | R2 | 同上 | 同上 |
0B | 1 | 1 | INC | R3 | 同上 | 同上 |
0C | 1 | 1 | INC | R4 | 同上 | 同上 |
0D | 1 | 1 | INC | R5 | 同上 | 同上 |
0E | 1 | 1 | INC | R6 | 同上 | 同上 |
0F | 1 | 1 | INC | R7 | 同上 | 同上 |
10 | 3 | 2 | JBC | bit, offset | 如果某个可位寻址的位地址值为1,则清零后跳转到offset这个地址继续执行,否则顺序执行下一条指令 | JBC BIT C |
11 | 2 | 2 | ACALL | addr11 | 短函数调用,函数中最后一条要是RET。绝对跳转,地址范围0xXX±0x000~07FF,跳转范围为当前指令地址高5位相同的2K范围,有参数的话子函数中还需要压栈和弹栈。调用完成后接着顺序执行本指令的下一条 | ACALL FUNC1 |
12 | 3 | 2 | LCALL | addr16 | 全域函数调用,函数中最后一条要是RET。地址范围0x0000~FFFF,有参数的话子函数中还需要压栈和弹栈。调用完成后接着顺序执行本指令的下一条 | LCALL FUNC2 |
13 | 1 | 1 | RRC | A | 带进位累加器循环右移,也就是除以2 | |
14 | 1 | 1 | DEC | A | 累加器自减1 | 可用作循环处理 |
15 | 2 | 1 | DEC | direct | 将给出地址当中的数据自减1(自增完后放回原处) | 同上 |
16 | 1 | 1 | DEC | @R0 | 将R0中的数据当作地址,将这个地址中的数据自减1 | 同上 |
17 | 1 | 1 | DEC | @R1 | 同上 | 同上 |
18 | 1 | 1 | DEC | R0 | 将R0中的数据自增1 | 同上 |
19 | 1 | 1 | DEC | R1 | 同上 | 同上 |
1A | 1 | 1 | DEC | R2 | 同上 | 同上 |
1B | 1 | 1 | DEC | R3 | 同上 | 同上 |
1C | 1 | 1 | DEC | R4 | 同上 | 同上 |
1D | 1 | 1 | DEC | R5 | 同上 | 同上 |
1E | 1 | 1 | DEC | R6 | 同上 | 同上 |
1F | 1 | 1 | DEC | R7 | 同上 | 同上 |
20 | 3 | 2 | JB | bit, offset | 如果某个可位寻址的位地址值为1,则跳转到offset这个地址继续执行,否则顺序执行下一条指令,该bit不清零 | 实现if else switch |
21 | 2 | 2 | AJMP | addr11 | 重复1 | |
22 | 1 | 2 | RET | 从子函数中返回 | ||
23 | 1 | 1 | RL | A | 累加器循环左移,也相当于乘以2 | |
24 | 2 | 1 | ADD | A, #immed | 累加器和一个立即数(常数)相加,结果放回到A | ADD A, #080H |
25 | 2 | 1 | ADD | A, direct | 累加器和内存地址里的值相加,结果放回到A | |
26 | 1 | 1 | ADD | A, @R0 | 累加器和R0里面存的内存地址里面指向的值相加,结果放回到A | |
27 | 1 | 1 | ADD | A, @R1 | 同上 | |
28 | 1 | 1 | ADD | A, R0 | 累加器和R0里面的值相加,结果放回到A | ADD A, R0 |
29 | 1 | 1 | ADD | A, R1 | 同上 | |
2A | 1 | 1 | ADD | A, R2 | 同上 | |
2B | 1 | 1 | ADD | A, R3 | 同上 | |
2C | 1 | 1 | ADD | A, R4 | 同上 | |
2D | 1 | 1 | ADD | A, R5 | 同上 | |
2E | 1 | 1 | ADD | A, R6 | 同上 | |
2F | 1 | 1 | ADD | A, R7 | 同上 | |
30 | 3 | 2 | JNB | bit, offset | 如果直接寻址位为0则转移 | 实现if else switch |
31 | 2 | 2 | ACALL | addr11 | 重复2 | |
32 | 1 | 2 | RETI | 中断程序返回 | ||
33 | 1 | 1 | RLC | A | 带进位累加器循环左移,也就是乘以2 | |
34 | 2 | 1 | ADDC | A, #immed | 带进位求和 | |
35 | 2 | 1 | ADDC | A, direct | ||
36 | 1 | 1 | ADDC | A, @R0 | ||
37 | 1 | 1 | ADDC | A, @R1 | ||
38 | 1 | 1 | ADDC | A, R0 | ||
39 | 1 | 1 | ADDC | A, R1 | ||
3A | 1 | 1 | ADDC | A, R2 | ||
3B | 1 | 1 | ADDC | A, R3 | ||
3C | 1 | 1 | ADDC | A, R4 | ||
3D | 1 | 1 | ADDC | A, R5 | ||
3E | 1 | 1 | ADDC | A, R6 | ||
3F | 1 | 1 | ADDC | A, R7 | ||
40 | 2 | 2 | JC | offset | 如果进位位为1 则跳转 | |
41 | 2 | 2 | AJMP | addr11 | 重复3 | |
42 | 2 | 1 | ORL | direct, A | 后面的与前面的相或,结果放到前面,*direct &= A | |
43 | 3 | 1 | ORL | direct, #immed | ||
44 | 2 | 1 | ORL | A, #immed | ||
45 | 2 | 1 | ORL | A, direct | ||
46 | 1 | 1 | ORL | A, @R0 | ||
47 | 1 | 1 | ORL | A, @R1 | ||
48 | 1 | 2 | ORL | A, R0 | ||
49 | 1 | 2 | ORL | A, R1 | ||
4A | 1 | 2 | ORL | A, R2 | ||
4B | 1 | 2 | ORL | A, R3 | ||
4C | 1 | 2 | ORL | A, R4 | ||
4D | 1 | 2 | ORL | A, R5 | ||
4E | 1 | 2 | ORL | A, R6 | ||
4F | 1 | 2 | ORL | A, R7 | ||
50 | 2 | 2 | JNC | offset | 如果进位位为0 则转移 | |
51 | 2 | 2 | ACALL | addr11 | 重复4 | |
52 | 2 | 1 | ANL | direct, A | 累加器“与”到直接地址 | |
53 | 3 | 2 | ANL | direct, #immed | ||
54 | 2 | 1 | ANL | A, #immed | ||
55 | 2 | 1 | ANL | A, direct | ||
56 | 1 | 1 | ANL | A, @R0 | ||
57 | 1 | 1 | ANL | A, @R1 | ||
58 | 1 | 1 | ANL | A, R0 | ||
59 | 1 | 1 | ANL | A, R1 | ||
5A | 1 | 1 | ANL | A, R2 | ||
5B | 1 | 1 | ANL | A, R3 | ||
5C | 1 | 1 | ANL | A, R4 | ||
5D | 1 | 1 | ANL | A, R5 | ||
5E | 1 | 1 | ANL | A, R6 | ||
5F | 1 | 1 | ANL | A, R7 | ||
60 | 2 | 2 | JZ | offset | 累加器为0 则转移 | |
61 | 2 | 2 | AJMP | addr11 | 重复5 | |
62 | 2 | 1 | XRL | direct, A | 累加器“异或”到直接地址 | |
63 | 3 | 1 | XRL | direct, #immed | ||
64 | 2 | 1 | XRL | A, #immed | ||
65 | 2 | 1 | XRL | A, direct | ||
66 | 1 | 1 | XRL | A, @R0 | ||
67 | 1 | 1 | XRL | A, @R1 | ||
68 | 1 | 2 | XRL | A, R0 | ||
69 | 1 | 2 | XRL | A, R1 | ||
6A | 1 | 2 | XRL | A, R2 | ||
6B | 1 | 2 | XRL | A, R3 | ||
6C | 1 | 2 | XRL | A, R4 | ||
6D | 1 | 2 | XRL | A, R5 | ||
6E | 1 | 2 | XRL | A, R6 | ||
6F | 1 | 2 | XRL | A, R7 | ||
70 | 2 | 2 | JNZ | offset | 累加器为1 则转移 | |
71 | 2 | 2 | ACALL | addr11 | 重复6 | |
72 | 2 | 2 | ORL | C, bit | 直接寻址位“或”到进位位 | |
73 | 1 | 2 | JMP | @A+DPTR | 相对DPTR 的无条件间接转移 | |
74 | 2 | 1 | MOV | A, #immed | ||
75 | 3 | 1 | MOV | direct, #immed | ||
76 | 2 | 1 | MOV | @R0, #immed | ||
77 | 2 | 1 | MOV | @R1, #immed | ||
78 | 2 | 2 | MOV | R0, #immed | ||
79 | 2 | 2 | MOV | R1, #immed | ||
7A | 2 | 2 | MOV | R2, #immed | ||
7B | 2 | 2 | MOV | R3, #immed | ||
7C | 2 | 2 | MOV | R4, #immed | ||
7D | 2 | 2 | MOV | R5, #immed | ||
7E | 2 | 2 | MOV | R6, #immed | ||
7F | 2 | 2 | MOV | R7, #immed | ||
80 | 2 | 2 | SJMP | offset | 无条件相对转移 | |
81 | 2 | 2 | AJMP | addr11 | 重复7 | |
82 | 2 | 2 | ANL | C, bit | 直接寻址位“与”到进位位 | |
83 | 1 | 2 | MOVC | A, @A+PC | 代码字节传送到累加器 | |
84 | 1 | 4 | DIV | AB | 累加器除以B 寄存器 | |
85 | 3 | 2 | MOV | direct, direct | ||
86 | 2 | 2 | MOV | direct, @R0 | ||
87 | 2 | 2 | MOV | direct, @R1 | ||
88 | 2 | 1 | MOV | direct, R0 | ||
89 | 2 | 1 | MOV | direct, R1 | ||
8A | 2 | 1 | MOV | direct, R2 | ||
8B | 2 | 1 | MOV | direct, R3 | ||
8C | 2 | 1 | MOV | direct, R4 | ||
8D | 2 | 1 | MOV | direct, R5 | ||
8E | 2 | 1 | MOV | direct, R6 | ||
8F | 2 | 1 | MOV | direct, R7 | ||
90 | 3 | 1 | MOV | DPTR, #immed | 16 位常数加载到数据指针 | |
91 | 2 | 2 | ACALL | addr11 | 重复8 | |
92 | 2 | 2 | MOV | bit, C | 进位位位传送到直接寻址 | |
93 | 1 | 2 | MOVC | A, @A+DPTR | 代码字节传送到累加器 | |
94 | 2 | 1 | SUBB | A, #immed | 累加器减去立即数(带借位) | |
95 | 2 | 1 | SUBB | A, direct | ||
96 | 1 | 1 | SUBB | A, @R0 | ||
97 | 1 | 1 | SUBB | A, @R1 | ||
98 | 1 | 1 | SUBB | A, R0 | ||
99 | 1 | 1 | SUBB | A, R1 | ||
9A | 1 | 1 | SUBB | A, R2 | ||
9B | 1 | 1 | SUBB | A, R3 | ||
9C | 1 | 1 | SUBB | A, R4 | ||
9D | 1 | 1 | SUBB | A, R5 | ||
9E | 1 | 1 | SUBB | A, R6 | ||
9F | 1 | 1 | SUBB | A, R7 | ||
A0 | 2 | 2 | ORL | C, /bit | 直接寻址位的反码“或”到进位位 | |
A1 | 2 | 2 | AJMP | addr11 | 重复9 | |
A2 | 2 | 1 | MOV | C, bit | 直接寻址位传送到进位位 | |
A3 | 1 | 2 | INC | DPTR | 数据指针加1 | |
A4 | 1 | 4 | MUL | AB | 累加器和B 寄存器相乘 | |
A5 | reserved | |||||
A6 | 2 | 1 | MOV | @R0, direct | ||
A7 | 2 | 1 | MOV | @R1, direct | ||
A8 | 2 | 2 | MOV | R0, direct | ||
A9 | 2 | 2 | MOV | R1, direct | ||
AA | 2 | 2 | MOV | R2, direct | ||
AB | 2 | 2 | MOV | R3, direct | ||
AC | 2 | 2 | MOV | R4, direct | ||
AD | 2 | 2 | MOV | R5, direct | ||
AE | 2 | 2 | MOV | R6, direct | ||
AF | 2 | 2 | MOV | R7, direct | ||
B0 | 2 | 2 | ANL | C, /bit | 直接寻址位的反码“与”到进位位 | |
B1 | 2 | 2 | ACALL | addr11 | 重复10 | |
B2 | 2 | 1 | CPL | bit | 取反直接寻址位 | |
B3 | 1 | 1 | CPL | C | 取反进位位 | |
B4 | 3 | 2 | CJNE | A, #immed, offset | 比较直接地址和累加器,不相等转移 | |
B5 | 3 | 2 | CJNE | A, direct, offset | ||
B6 | 3 | 2 | CJNE | @R0, #immed, offset | ||
B7 | 3 | 2 | CJNE | @R1, #immed, offset | ||
B8 | 3 | 2 | CJNE | R0, #immed, offset | ||
B9 | 3 | 2 | CJNE | R1, #immed, offset | ||
BA | 3 | 2 | CJNE | R2, #immed, offset | ||
BB | 3 | 2 | CJNE | R3, #immed, offset | ||
BC | 3 | 2 | CJNE | R4, #immed, offset | ||
BD | 3 | 2 | CJNE | R5, #immed, offset | ||
BE | 3 | 2 | CJNE | R6, #immed, offset | ||
BF | 3 | 2 | CJNE | R7, #immed, offset | ||
C0 | 2 | 2 | PUSH | direct | 直接地址压入堆栈 | |
C1 | 2 | 2 | AJMP | addr11 | 重复11 | |
C2 | 2 | 1 | CLR | bit | 清直接寻址位 | |
C3 | 1 | 1 | CLR | C | 清进位位 | |
C4 | 1 | 1 | SWAP | A | 累加器高、低4 位交换 | |
C5 | 2 | 1 | XCH | A, direct | 直接地址和累加器交换 | |
C6 | 1 | 1 | XCH | A, @R0 | ||
C7 | 1 | 1 | XCH | A, @R1 | ||
C8 | 1 | 1 | XCH | A, R0 | ||
C9 | 1 | 1 | XCH | A, R1 | ||
CA | 1 | 1 | XCH | A, R2 | ||
CB | 1 | 1 | XCH | A, R3 | ||
CC | 1 | 1 | XCH | A, R4 | ||
CD | 1 | 1 | XCH | A, R5 | ||
CE | 1 | 1 | XCH | A, R6 | ||
CF | 1 | 1 | XCH | A, R7 | ||
D0 | 2 | 2 | POP | direct | 直接地址弹出堆栈 | |
D1 | 2 | 2 | ACALL | addr11 | 重复11 | |
D2 | 2 | 1 | SETB | bit | 置位直接寻址位 | |
D3 | 1 | 1 | SETB | C | 置位进位位 | |
D4 | 1 | 1 | DA | A | 累加器十进制调整 | |
D5 | 3 | 2 | DJNZ | direct, offset | 直接地址减1,不为0 则转移 | |
D6 | 1 | 1 | XCHD | A, @R0 | 间接RAM 和累加器交换低4 位字节 | |
D7 | 1 | 1 | XCHD | A, @R1 | ||
D8 | 2 | 2 | DJNZ | R0, offset | 寄存器减1,不为0 则转移 | |
D9 | 2 | 2 | DJNZ | R1, offset | ||
DA | 2 | 2 | DJNZ | R2, offset | ||
DB | 2 | 2 | DJNZ | R3, offset | ||
DC | 2 | 2 | DJNZ | R4, offset | ||
DD | 2 | 2 | DJNZ | R5, offset | ||
DE | 2 | 2 | DJNZ | R6, offset | ||
DF | 2 | 2 | DJNZ | R7, offset | ||
E0 | 1 | 2 | MOVX | A, @DPTR | 外部RAM(16 地址)传送到累加器 | |
E1 | 2 | 2 | AJMP | addr11 | 重复12 | |
E2 | 1 | 2 | MOVX | A, @R0 | 外部RAM(8 地址)传送到累加器 | |
E3 | 1 | 2 | MOVX | A, @R1 | ||
E4 | 1 | 2 | CLR | A | 累加器清零 | |
E5 | 2 | 1 | MOV | A, direct | ||
E6 | 1 | 1 | MOV | A, @R0 | ||
E7 | 1 | 1 | MOV | A, @R1 | ||
E8 | 1 | 1 | MOV | A, R0 | ||
E9 | 1 | 1 | MOV | A, R1 | ||
EA | 1 | 1 | MOV | A, R2 | ||
EB | 1 | 1 | MOV | A, R3 | ||
EC | 1 | 1 | MOV | A, R4 | ||
ED | 1 | 1 | MOV | A, R5 | ||
EE | 1 | 1 | MOV | A, R6 | ||
EF | 1 | 1 | MOV | A, R7 | ||
F0 | 1 | 2 | MOVX | @DPTR, A | 累加器传送到外部RAM(16 地址) | |
F1 | 2 | 2 | ACALL | addr11 | 重复13 | |
F2 | 1 | 2 | MOVX | @R0, A | 累加器传送到外部RAM(8 地址) | |
F3 | 1 | 2 | MOVX | @R1, A | ||
F4 | 1 | 1 | CPL | A | 累加器求反 | |
F5 | 2 | 1 | MOV | direct, A | 累加器传送到直接地址 | |
F6 | 1 | 2 | MOV | @R0, A | 直接地址传送到间接RAM | |
F7 | 1 | 2 | MOV | @R1, A | ||
F8 | 1 | 1 | MOV | R0, A | ||
F9 | 1 | 1 | MOV | R1, A | ||
FA | 1 | 1 | MOV | R2, A | ||
FB | 1 | 1 | MOV | R3, A | ||
FC | 1 | 1 | MOV | R4, A | ||
FD | 1 | 1 | MOV | R5, A | ||
FE | 1 | 1 | MOV | R6, A | ||
FF | 1 | 1 | MOV | R7, A | ||
伪指令 | ORG | 汇编起始伪指令 | ||||
伪指令 | END | 结束伪指令 | ||||
伪指令 | DB | 字节数据定义伪指令 | ||||
伪指令 | DW | 字数据定义伪指令 | ||||
伪指令 | DS | 空间定义伪指令 | ||||
伪指令 | EQU | 赋值伪指令 | ||||
伪指令 | BIT | 位地址符号定义伪指令 | ||||
伪指令 | DATA | 片内RAM直接字节地址定义伪指令 | ||||
伪指令 | XDATA | 片外RAM直接字节地址定义伪指令 |
还有一些编译器自定义的符号,如Keil的伪指令:
$NOMOD51
$NOPRINT
NAME ; 给当前模块命令,同时也是一段代码的入口
SEGMENT ;类似于typedef
PUBLIC
?C_START ; main函数入口
IF
ELSE
ENDIF
标号:
CODE
IDATA
EXTRN
RSEG ; 段选择指令
CSEG
AT
$INCLUDE(USER.ASM)
C51 各个存储区说明
keil C51中各个地址的区别
51单片机片内RAM的128B(00H~FFH) 分为哪几部分各部分地址范围及功能?
51单片机特殊功能寄存器中的字节寻址和位寻址
C51 特殊功能寄存器SFR的名称和地址
C51最全111条汇编指令合集,以及使用时的注意事项,超详细
51单片机指令表
正确区分LJMP、AJMP、SJMP、JMP单片机跳转指令
51单片机的汇编指令中AJMP 和SJMP都是两个字节,都是两个机器周期,它们有什么区别呢?
谁能帮我解释一下 INC A ; INC direct INC Rn INC @Ri INC DPTR
MCS51单片机的伪指令有哪些?
keil_C51伪指令
; $NOMOD51 ; 使A51不使用8051所有预定义的符号,使用自定义符号
; 不同的芯片厂商可以将SFR寄存器进行全新的定义
;==== SFR寄存器定义====
P0 DATA 80H ; P0 IO口
SP DATA 81H ; 堆栈指针
DPL DATA 82H ; 数据指针低字节
DPH DATA 83H ; 数据指针高字节
PCON DATA 87H ; 电源控制
TCON DATA 88H ; 定时器控制
TF1 BIT TCON.7
TR1 BIT TCON.6
TF0 BIT TCON.5
TR0 BIT TCON.4
IE1 BIT TCON.3
IT1 BIT TCON.2
IE0 BIT TCON.1
IT0 BIT TCON.0
TMOD DATA 89H ; 定时器方式
TL0 DATA 8AH ; 定时器0低字节
TH0 DATA 8CH ; 定时器0高字节
TL1 DATA 8BH ; 定时器1低字节
TH1 DATA 8DH ; 定时器1高字节
P1 DATA 90H ; P1 IO口
SCON0 DATA 98H ; UART0
TI0 BIT SCON0.1
RI0 BIT SCON0.0
SBUF0 DATA 99H ; 串口0数据
SCON1 DATA 9BH ; UART1 ; 芯片厂商自行添加的
SBUF1 DATA 9CH ; 串口1数据
P2 DATA 0A0H ; P2 IO口 ; 对于最高位大于等于10(ABCDEF)的数前面必须带0
IEN0 DATA 0A8H ; 中断使能
EA BIT IEN0.7
WDT BIT IEN0.6 ; 芯片厂商自行添加
EX1 BIT IEN0.2
EX0 BIT IEN0.0
P3 DATA 0B0H ; P3 IO口
T2CON DATA 0C8H ; 定时器2控制
TL2 DATA 0CCH ; 定时器2低字节
TH2 DATA 0CDH ; 定时器2高字节
PSW DATA 0D0H ; 程序状态寄存器
CY BIT PSW.7
AC BIT PSW.6
F0 BIT PSW.5
RS1 BIT PSW.4
RS0 BIT PSW.3
OV BIT PSW.2
F1 BIT PSW.1
P BIT PSW.0
ACC DATA 0E0H ; 累加器
B DATA 0F0H ; 寄存器B
EXADR DATA 0FEH ; SFR扩展接口 ; 支持更多的寄存器
EXDATA DATA 0FFH
; 赋值
APP_MODE EQU 0F8H ; 类似于宏定义
; 中断入口,程序入口(程序从0地址开始执行)
ORG 0000H
LJMP RESET
ORG 000BH ; 中断入口的地址都是固定的
LJMP T0INT
ORG 001BH
LJMP T1INT
ORG 002BH
LJMP T2INT
ORG 0100H ; 程序起始地址
$INCLUDE(USER.ASM)
RESET:
; 你的汇编代码,初始化各个模块,执行函数,响应中断,执行程序
END
;;;;
; 其它未写出的准备操作:
; 用DATA申明所有的SFR寄存器名字,P0(80H) ~ B(0F0H)
; 自定义的宏定义,如DEBUG_LEVEL EQU 01H,用于配置软件的不同功能
CSEG AT 0000H ; 板子复位后执行的第一条指令
LJMP STARTUP ; 执行初始化函数
CSEG AT 0003H ; 外部中断0
LJMP interupt_0 ; 依次注册好所有中断处理函数
;;;; 省略其它中断处理函数
; SEGMENT申明本模块在CODE代码段,CODE代码段起始地址是0x100,这也是程序默认运行的起始地址,前面的地址是一些固定的中断处理的函数地址
STARTUP_FUNC SEGMENT CODE AT 0100H ; 等同于ORG 0100H
RSEG STARTUP_FUNC ; 定义函数再定义段
PUBLIC STARTUP ; 申明函数,并向别的.asm暴露出函数接口
STARTUP: ; 标号,同时也是函数名,和C语言中标号类似,C语言的标号可以goto跳转
NOP ; 延时一个时钟周期
CLR EAL ; SBIT(EAL, IE, 7) ; 关闭中断7
CLR RS0 ; RS0 BIT PSW.3 ;
CLR RS1 ; RS0 BIT PSW.3 ; 和上条命令一起选择第一组R0~R7寄存器
MOV IE, #0H ; 关闭所有中断
NOP
MOV SP, #ORIGIN_SP ; ORIGIN_SP EQU 40H ; 初始化堆栈起始地址
NOP
LCALL _hardware_init ; 调用你写的函数写驱动模块寄存器初始化你需要的硬件,如引脚、PLL时钟倍频分频、JTAG设置、看门狗复位、IO输出、引脚复用、软件配置判断、内存初始化、串口、SPI、I2C等初始化
NOP
LCALL _crt0Startup ; 调用crt0.c里面的C语言函数,其实这时候已经可以直接调用main函数了,但是有些main函数之前的准备工作是用C写的,所以要提前调用一下
;;;;
; extern int main(int, char * const []);
; extern int sysExit(int exit_code);
; #define sysMain main
; int crt0Startup(int argc, char * const argv[])
; {
; // 关闭所有中断、DMA缓存刷新、CPU工作模式选择、硬件频率进一步设置、串口的完整初始化(设置波特率)、中断初始化、时钟初始化(更新当前实时时间)、有操作系统的话初始化task、内核、使能中断、调用main函数、main结束后进行资源销毁,便于软复位后系统能再次正常运行
; // sysMain(argc, argv); // 跳转到main函数执行
; // sysExit();
; }
NOP
LJMP _cpuStop ; 关闭PLL时钟分频倍频,将时钟设置为晶振的原始频率
NOP
RET
NOP
END
CSEG ; 绝对地址指示的代码段,可以当成一个函数的入口
RSEG ; 再定位段选择指令,它用来选择一个在前面已经定义过的再定位段作为当前段,例如先申明一个函数段,后面写这个函数段。PS: 程序代码放到代码段,数据对象放到数据段,段分两种,一是种绝对段,一种是再定位段。
SEGMENT ; 申明是哪种段,类似C语言的{}花括号,和END配和使用
AT ; 该段的起始地址
PUBLIC ; 给别的.asm文件暴露出函数接口,类似于C语言 int api_func(void);放在头文件中
$SAVE ; 存储最近的LIST和GEN的设置
$NOLIST ; 不使用最近的LIST配置
$RESTORE ; 恢复最近的LIST和GEN的设置
EXTRN CODE (YOUR_FUNCTION_NAME) ; EXTRN 是与PUBLIC 配套使用的,要调用其它模块的函数,就必须先在模块前声明
汇编语言段和RSEG用法
A51零散笔记
STC8头文件
寄存器B
标志寄存器(PSW)
单片机DPH DPL是什么
求教解释R0~R7.还有,RS0,RS