1、1 单片机的C51编程 第一节第一节 概述概述第二节第二节 程序的格式程序的格式第三节第三节 数据类型和存储类型数据类型和存储类型第四节第四节 运算符和表达式运算符和表达式第五节第五节 指针与函数指针与函数 第六节第六节 片内硬件资源的定义片内硬件资源的定义 第七节第七节 程序的基本结构程序的基本结构 第八节第八节 C51C51程序举例程序举例第九节第九节 WindowsWindows环境下环境下C51C51编译器的操作编译器的操作l-2 本章要点 介绍C语言的基础知识。掌握C语言程序的基本结构,学会编制一些简单的单片机应用程序,并能在Windows环境下使用C51编译器进行编译操作。了解C5
2、1编译器与标准C语言在存储模式、片内硬件资源使用等方面的差别。l-3 第一节 概述随着开发工具及集成电路技术的发展,在开发大型的单片机应用系统时,使用高级语言更加有利专门针对8051系列单片机开发出来的C51编译器(简称C51)可编译生成能够在 8051系列单片机上运行的目标程序。目前针对8051系列单片机开发出来的编译器有多种,包括Franklin C51、Keil C51 for windows等l-4 第二节 程序的格式 先从几个实例,了解C语言的程序格式。例9-1 能输出“Welcome to use C51”的C语言程序#include“stdioh”main()printf(“We
3、lcome to use C51 n”);其中main()为主函数,printf为输出函数,stdio.h为头文件,执行这个程序的目的,是在屏幕上输出以下一行信息:Welcome to use C51 l-5 例9-2 求三个数a、b、c的和。#include“stdioh”main()*主函数*int a,b,c,sum;*定义变量*a=12;b=34;c=56;*给变量赋值*sum=a+b+c;*求和*printf(“sum is dn”,sum);*显示结果*执行以上程序,可在屏幕上输出a、b、c的和,并显示:sum is 102l-6 例9-3 从输入的两个数a,b中,求出较大的数的程
4、序。#include“stdioh”int max(int x,int y)*定义max函数,函数返回 值为整型;x,y为形式参 数,整型*int z;if(xy)z=x;else z=y;return(z);*将z的值返回到调用 处*l-7 main()*主函数*int a,b,m;*定义三个整型变量*scanf(“d,d,”&a,&b);*输入变量a和b的值*m=max(a,b);*调用max函数,将返回值m*printf(“max=%d”,m);*输出m的值*程序执行结果是在输入a,b值后,可求出较大的数并赋予变量m。如输入a=3,b=5,则执行结果可显示出 m=5。l-8 从三个例子可
5、看出C语言或C51源程序的基本格式有如下特点:1.C语言程序的书写格式比较自由,一行可以写若干条语句,一个语句也可以写成几行,不管一行写几个语句,每个语句须以“;”结尾。2.程序由一个主函数和若干个其他函数组成,主函数的名字必须为main。程序的执行总是从main函数开始的,其位置无特殊规定。3.C语言程序通过函数调用去执行指定的工作。源程序文件需要包含其他源程序文件的内容时,则要在本程序文件头部用包含命令#include进行“文件包含”处理。l-9 第三节 数据类型和存储类型 一、数据类型 C语言中的数据分为常量和变量,不论常量还是和变量都有几种不同类型,不同类型的数据占用的存储长度不同。1
6、.1.常量和符号常量的类型常量和符号常量的类型 常量指程序运行时其值不能被改变的量,常量可以用一个标识符表示,并称为符号常量。C语言中的常量分为如下几种类型:整型、实型、字符、字符串l-102.2.变量类型变量类型变量名称符号类型数据长度值域范围位型量bit1位0,1字符型有符号signed char 8位-128+127无符号unsigned char8位0255整数型有符号signed int16位-32768+32767无符号unsigned int16位065535长整型有符号signed long32位-231231-1无符号unsigned long32位0232-1浮点型floa
7、t32位3.4E-383.4E+38指针型指针824?对象地址特殊位型sbit10或18位特殊功能寄存器型sfr8025516位特殊功能寄存器型sfr1616065535表 C51变量类型l-11 二、存储类型二、存储类型 存储类型是指该数据在单片机系统中存放的位置,也就是数据的定位方式。存储类型 与存储空间的对应关系 data 直接寻址片内数据存储区,访问速度快(128字节)bdata 可位寻址片内数据存储区,允许位与字节混合访问(16字节)idata 间接寻址片内数据存储区,可访问片内全部RAM地址空间(256字节)pdata 分页寻址片外数据存储区(256字节)由MOVX R0,A指令访
8、问 xdata 片外数据存储区(64K),由MOVX DPTR,A指令访问 code 代码存储区(64K),由MOVC A,A+DPTR指令访问 表 C51存储类型l-12 C51中定义变量除了定义数据类型外,还应中定义变量除了定义数据类型外,还应定义存储类型定义存储类型例:int data x,y;表示变量x,y 为16位整数并指定存储在片内数据存储区。1.若未定义存储类型,则C51编译器自动选择默认存储类型如下表:存储模式 默认的存储类型 SMALL 默认的存储类型为data,最大为128字节 COMPACT 默认的存储类型为pdata,每页256字节 LARGE 默认的存储类型为xdat
9、a,最大为64K l-13 2.选择变量类型时应尽量选用无符号型,可以减少测试符号的额外操作,可以提高代码效率。3.为使编程时书写简化,数据类型允许用缩写。例:#define uchar uchar unsigned char#define ulong ulong unsigned longl-14 第四节 运算符和表达式 一、算术运算符及其表达式一、算术运算符及其表达式 1.C1.C语言的基本算术运算符语言的基本算术运算符 算术运算符有+、-、*、/、%(%为模运算符,或称求余运算符)。用算术运算符或圆括号将运算对象包括常量、变量、函数、数组等连接起来,形成符合C 语法规则的式子称为算术表达
10、式。如:a*(b-c)+2.3+al-15 2.2.算术运算符的优先级算术运算符的优先级 先乘除模,后加减,括号最优先。3.3.算术运算符的结合性算术运算符的结合性 “自左至右”,即运算对象两侧的算术运算符优先级相同时,先与左边运算符结合。4.4.数据类型不同时的转换数据类型不同时的转换 如果运算符两侧的数据类型不同,则必须转换成同一类型,再进行运算。转换方式有自动转换(默认)和强制转换。强制转换的形式为:类型名)表达式);例例:(double)x;(将x强制转换成double型)注:注:强制转换只转换表达式的值,变量类型不变。l-16 二、关系运算符及其表达式二、关系运算符及其表达式 1.1
11、.六种关系运算符六种关系运算符 (大于)=(大于或等于)=、=、b,因ab的值为“假”,所以x的值为0。b=(a+c)的值为“假”,表达式的值为0;cb的值为“真”,表达式的值为1;l-18 三、逻辑运算符及其表达式三、逻辑运算符及其表达式 1.1.三种三种逻辑运算符逻辑运算符&逻辑与 (两个操作数都为真时,结果才为真,否则 为假。)逻辑或 (只要两个操作数中有一个为真,结果便为 真,否则为假。)!逻辑非 (对操作数的值取反。)&和 要求有两个操作对象,而!是单目运算符,只要求有一个运算对象。l-19 2.2.逻辑运算符的优先级逻辑运算符的优先级 优先顺序为!(非)算术运算符 关系运算符&和。
12、最低为赋值运算符。3.3.逻辑表达式逻辑表达式 用逻辑运算符将关系表达式或逻辑量连接起来的式子称为逻辑表达式。逻辑表达式的值只能是0(假)或1(真)。例:已知a=2,b=3,求!a、a&b、!a&b!a为0(假)a=2非0故为假a&b为1(真)!a&b 为0(假)先执行!a为0故!a&b为0 l-20 四、位操作运算符及其表达式四、位操作运算符及其表达式&按位与 按位或 按位异或 按位取反 位右移 除运算符外,其余位操作运算符都是两目运算符。位运算符操作的对象只能是整型或字符型数据。l-21 1按位与&参与运算的两操作数,只有双方相应的位都为1,结果值中该位为1,否则为0。即 O&O=O,O&
13、l=0,l&O=0,l&l=l 例:a=0 x31,b=0 x56,求ab的值。ab=01110111B2 2按位或按位或 参与运算的两操作数只要双方相应的位中有1,其结果该位便为1,否则为0。即O O=O,O l=1,l O=1,l l=l例:a=0 x37,b=Ox7A求a&b的值。a&b=00110010l-22 3按位取反 对操作数按位取反,即0变l,1变0。例:a=0 x31,b=0 x56,求ab的值。ab=01100111B 4 4按位异或按位异或 参与运算的两操作数,如果对应位的值不同,运算结果该位为1,否则为0。即OO=O,Ol=1,lO=1,ll=0例:a=0 x3FH=0
14、0111111B,求a 的值。a=11000000Bl-23 5.5.位左移和位右移位左移和位右移 移位运算时,将左操作数的各二进制位全部左(右)移若干位,所移位数由右操作数决定。移位后留出的空白位补0,溢出的位舍弃。例:a=Ox3E,求a2的值。求得 00001111 即0 x0Fl-24 五、自增减运算符及其表达式五、自增减运算符及其表达式 作用:使变量的值增1或减l。如:+i+i (使用i之前,先使i值增1。)-i-i (使用i之前,先使i值减1。)i+i+(在使用i之后,使i值增l。)i-i-(在使用i之后,使i值减1。)例:若i=5 则j=i+;(执行后i=6,j=?)j=+i;(I
15、=6,j=6)l-25 六、复合运算符及其表达式六、复合运算符及其表达式 C语言中的两目运算符都可以和赋值运算符“=”一起组成复合赋值运算符。使用的复合赋值运算符有以下10种:+=,-=,+=,-=,*=,/=,%=,=,/=,%=,=,&=,=,&=,=,=,=例如 a+=2 等价于 a=a+2。m*=n+1 等价于 m=m*(n+1)。l-26 七、对指针操作的运算符七、对指针操作的运算符&取地址运算符*取内容运算符&可作为取地址运算符,又可作为按位与,若为按位与“&”的两边必须有操作对象。*可作为取内容运算符,还可作为指针变量的标志,但作为指针变量标志时,一定出现在对指针定义中。l-27
16、 第五节 指针与函数 一、指针与指针变量一、指针与指针变量 变量名对应于内存单元的地址,变量值则是放在内存单元中的数据。同时把存放变量x的地址称为指针,使用指针前也必须定义。指针的定义为:char*xpdata char*xp l-28 定义指针与指针变量的注意点 1.指针变量名前面冠以“*”号,如上例*xp,表示xp为指针。2.定义时,应包括被指变量的数据类型、存储类型以及指针变量本身的存储类型。指针变量本身的存储类型,写在语句的开头,或者在*号与变量名之间。3.如果只标明被指变量的数据类型和存储类型,而没有指明指针变量本身的存储类型,则指针变量本身被默认为通用型。l-29 指针与指针变量的
17、定义举例指针与指针变量的定义举例 例:定义一字符变量x,并赋值为6。char data xx=6 例:定义一指针xp,指向x所在的内存单元 data char data*xp或者 char data*data xpxp=&x 定义后要访问x可以用两种办法:1)直接访问,如printf(“d”,x)。2)间接访问,如printf(“d”,*xp)。l-30 二、函数二、函数C51程序是由一个主函数和若干个其他函数所构成,程序中由主函数调用其他函数,其他函数也可以互相调用。主函数其他函数标准库函数自定义函数无参数函数有参数函数程序l-31 1 1无参数函数的定义形式无参数函数的定义形式 类型标识符
18、 函数名()函数体语句 类型标识符用来指定函数返回值的类型。无参数函数一般不带返回值,可以不写类型标识符。例:dis()printf(“okn”);函数名函数体语句l-32 2 2有参数函数的定义形式有参数函数的定义形式 类型标识符 函数名(参数列表及说明)函数体语句例:intmax(int x,int y)int z;/*函数体语句*if(xy)z=x;elsez=y;return(z);类型标识符函数名参数列表及说明l-33 3 3中断处理函数的定义形式中断处理函数的定义形式 void 函数名(void)interrupt n(using m)函数体语句例:void Timer0(void
19、)interrupt 1 using 3 /*函数体*注意:(1)中断函数没有返回值 (2)中断函数不能传递参数 (3)中断函数中调用其他函数,要保证使用 同一个寄存器组 (4)中断处理程序要尽可能短l-34 第六节 片内硬件资源的定义 一、特殊功能寄存器的定义一、特殊功能寄存器的定义 8051系列单片机的片内有21个特殊功能寄存器(简称SFR),地址分散在片内RAM的高端128字节地址80H-0FFH范围内,其中有11个寄存器具有位寻址能力。在C51中使用这些寄存器必须事先予以定义,定义后便可直接访问。l-35 1.1.用用sfrsfr定义字节型特殊功能寄存器的标志符定义字节型特殊功能寄存器
20、的标志符 例如:sfr P0=0X80 sfr PCON=0X87 sfr TMOD=0X89 sfr PSW=0XD0 sfr P1=0X90 sfr TCON=0X88 sfr SCON=0X98 这些符号已在文件reg51.h中被定义,如果使用#include“reg51.h”包含命令就无需一一定义。l-36 2.2.用用sfr16sfr16定义双字节型的特殊功能寄存器定义双字节型的特殊功能寄存器的标志符的标志符 例如:sfr16 DP=0X82使用注意使用注意1)sfr16用DPTR的低8位地址定义16位的特殊功能寄存器,仅限于允许组合成16位的特殊功能寄存器(像DPH、DPL)使用。
21、2)也可以不用sfr16,而用sfr对DPH、DPL分别定义,需要赋值时可分别赋值。l-37 3.3.用用sbitsbit定义特殊功能寄存器位地址定义特殊功能寄存器位地址空间的位名称空间的位名称 例如sbit P1_0=P10sbit OV=PSW2sbit CY=PSW7 CY也可以用下面两种方法定义:sbit CY=0XD07 sbit CY=0XD7OV也可以用下面两种方法定义:sbit OV=0XD02sbit OV=0XD2l-38 二、存储器绝对地址定义 在包含头文件absacc.h的前提下,可以使用#define指令定义不同存储空间各个变量的绝对地址。XBYTE表示PORT所处的
22、存储空间和数据长度,方括弧内表示PORT的绝对地址。语句 PORT=0X01 表示将数据0X01赋予片外存储器0X2000。例:#define PORTXBYTE0X2000l-39 1)CBYTE程序存储器空间,字节型。2)DBYTE片内RAM空间,字节型。3)PBYTE分页操作的片外RAM空间,字节型。4)XBYTE片外RAM空间,字节型。5)CWORD程序存储器空间,字型。6)DWORD片内RAM空间,字型。7)PWORD分页操作的片外RAM空间,字型。8)XWORD片外RAM空间,字型。类似的关键字有八种类似的关键字有八种l-40 第七节 程序的基本结构 一、顺序结构一、顺序结构 顺序
23、结构是指程序按语句的先后顺序逐句执行,是最基本、最简单的种程序结构。例如以下输入半径值,求圆面积和周长的程序。include”stdio.h”#define PI 3.14 main()l-41 第七节 程序的基本结构 一、顺序结构一、顺序结构 顺序结构是指程序按语句的先后顺序逐句执行,是最基本、最简单的种程序结构。例如以下输入半径值,求圆面积和周长的程序。include”stdio.h”#define PI 3.14 main()float r,s,y;*定义三个浮点型变量*scanf(“f”,&r);*输入数据*s=PI*r*r;y=2*PI*r;printf(“area is f,per
24、imeter is fn”,s,y);l-42 二、分支结构二、分支结构 分支结构可分为单分支、双分支和多路分支三种。1.1.单分支语句形式单分支语句形式 if(if(表达式表达式)语句;语句;例:从键盘输入两实数,然后按值的大小顺序输出(先小后大)。l-43#include”stdioh”main()float a,b,t;scanf(“f,f”,&a,&b);if(ab)t=a;a=b;b=t printf(“5.2f,5.2f”,a,b);l-44 2.2.双分支双分支双分支语句的形式if(if(表达式表达式)语句语句1;1;elseelse 语句语句2;2;例如:if(x=1)y=x+
25、5;elsey=x*5;l-45 分支语句嵌套分支语句嵌套 分支语句可以嵌套使用,双分支语句嵌套后可实现多路分支,其语句形式为:if(表达式1)语句1;else if(表达式2)语句2;elseif(表达式n1)语句n-1;else 语句n;l-46 3.多分支多分支 C语言提供一种专门用于多分支的开关语句,流程图如图所示。l-47 多分支的语句形式多分支的语句形式 switch(表达式)case 常量表达式l:语句1;break;case 常量表达式2:语句2;break;case 常量表达式n:语句n;break;default:语句n+1;break;l-48 多分支语句程序举例多分支语
26、句程序举例 例:给定一个百分制成绩,要求转换为五级记分制,规定90分以上为A,8089分为B,7079分为C,6069分为D 60分以下为E。#include“stdio.h”main()int score,c;char g;printf(“请输入学生成绩:”);l-49 scanf(“d”,&score);*从键盘输入*if(score100(score0)printf(“n输入错误!”);*大于100小于0*else c=(scorescore%10)/10;switch(c)case 10:case 9:g=A;break;l-50 case 8:g=B;break;case 7:g=C
27、;break;case 6:g=D;break;case 5:case 4:case 3:case 2:case 1:case 0:g=E;printf(“成绩:%d,等级成绩为%c”,score,g);l-51 三、循环结构三、循环结构 1.while1.while语句语句 while语句的形式:while(while(表达式表达式)循环体循环体;执行步骤是:先判断(表达式)是否成立。若成立(其值为非0)则执行循环体,否则退出循环去执行while语句的下一条语句。l-52 while语句实例语句实例求1十2十3十100的和。#include“stdio.h”main()inti,sum=0;
28、i=1;l-53 while(i=100)sum=sum+i;i+;printf(“%d”,sum);l-54 2.do.while2.do.while语句语句语句形式:do do 循环体循环体while(while(表达式表达式);先执行循环体,后判断表达式是否成立,若成立(表达式值为非零),返回重新执行循环体,否则(表达式值为零)停止循环。l-55 Do.whileDo.while语句实例语句实例用do.while语句求1十2十3十100的和#include“stdio.h”main()int i,sum=0;i=1;l-56 do sum=sum+i;i+;while(i=100);pr
29、intf(“d”,sum);l-57 3.for3.for语句语句语句形式:for(exp1;exp2;exp3)for(exp1;exp2;exp3)循环体;例:用for语句改写1十2十3十100的和#include”stdio.h”main()int t,sum=O;for(i=1;i100;i+)sum=sum+i;printf(“d”,sum);l-58 第八节 C51程序举例 一、一、“走马灯走马灯”电路电路 设计一个实验电路,在AT89C51并行接口P1连接8个LED,要求这8个LED能循环点亮。电路如图。l-59 “走马灯走马灯”电路程序清单电路程序清单#includereg51
30、.h”delay(int t)/*延时函数*/int i,j;/*采用默认的存储类型*/*用双重空循环延时*/for(i=0;it;i+)for(j=0;j10;j+);main()/*主函数*/char data i,s;l-60 “走马灯走马灯”电路程序清单电路程序清单(续续)while(1)/*无穷循环*/s=0 xfe;/*设置初值,最低一位为0*/P1=s;/*P1送据,令接P1.0的LED亮*/delay(500);for(i=0;i8;i+)s=s1;/*s值左移一位,最低位补0*/s=s0 x01;/*将最低位置1*/P1=s;/*由P1送出数据,令对应的LED亮*/delay
31、(500);l-61 二、数码管动态显示二、数码管动态显示 设计一个电路,利用外接可编程并行接口8255,驱动数码管显示字符,电路如图所示。l-62 数码管动态显示程序数码管动态显示程序清单清单#include”stdio.h”#include”reg5l.h”/*载入C51头文件*/#includeabsacc.h”#define crXBYTE0 x8003#define pbXBYTE0 x8001#define pcXBYTEOX8002#define CW0 x88 char d_74=0 x3f,0 x06,0 x5b,0 x4f/*0-3的字型段码数据*/char con4=0
32、xfe,0 xfd,0 xfb,Oxf7/*扫描控制信号*/l-63 数码管动态显示程序数码管动态显示程序(续续1)1)delay(int t)/*延时函数*/inti,j;for(i=0;it;i+)for(j=0;j10;j+);scan()/*扫描显示函数*/char i;for(i=0;i4;i+)pb=d_7i;/*B口送出段码*/pc=coni;/*C口送位码*/delay(3);l-64 数码管动态显示程序数码管动态显示程序(续续2)2)main()cr=CW;*定8255工作模式*while(1)scan();*无穷循环 由于扫描速度很快,好像四个数码管同时发亮,即显示出“01
33、23”。l-65 三、救护车警声程序三、救护车警声程序 本程序利用可编程发声器件(PSG)芯片AY-3-8970产生救护车的警报声,电路如图.AY-3-8970内部寄存器所载入的数据与所实现的功能参看表9-6。l-66 救护车警报声程序救护车警报声程序#include ”reg5l.h”/*载入C51头文件*/#include absacc.h”#include ”stdlib.h”#define psg_reg XBYTE0 x9000#define psg_data XBYTEOX9001 delay(int t)/*延时函数*/inti,j;for(i=0;it;i+)for(j=0;j
34、5;j+);l-67 救护车警报声程序救护车警报声程序(续续1)1)flash()/*工作灯闪烁函数*/char i;for(i=0;i3;i+)P1=0 x80;delay(40);P1=0;delay(40);setpeg(int r,int d)/*向PSG送数函数*/psg_reg=r;/*选择寄存器*/psg_data=d;/*d写入指定存储器*/l-68 救护车警报声程序救护车警报声程序(续续2)2)alarm()/*发警报声函数*/setpsg(0,5);setpsg(1,1);/*产生440Hz的声音*/setpsg(7,62);/*R7=62启用音调发声器*/setpsg(8
35、,15);/*R6=15声道的振幅最大*/delay(300);setpsg(0,104);/*R0=104*/setpsg(1,2);*产生180Hz声音*/l-69 救护车警报声程序救护车警报声程序(续续3)3)delay(300);setpsg(8,0);/*音量设为0*main()setpsg(7,63);/*关闭音调发声器*/flash();/*调用LED闪烁函数*/delay(800);while(1)/*无穷循环*/alarm();/*调用警报声函数*/l-70 四、四、C51C51中断程序举例中断程序举例 在C51中,中断服务程序定义为函数,并规定用下列形式表示函数名函数名 i
36、nterrupt n using minterrupt n using m 将上述“走马灯”电路改用开关控制,并采用中断方式如图所示,要求开关每拨动一次,点亮的LED向前移动一个位置。l-71 “走马灯走马灯”电路中断方式程序电路中断方式程序#includereg51.h”char i;char s=0 xfe;led1()interrupt 2/*使用INT1则N=2*/if(i8)s=s【New】,弹出编辑窗口如图,可以在此窗口中编辑C51程序。l-78 2.2.建立工程文件建立工程文件 编写好程序,执行主菜单Project】-【New Project】选项,在弹出的窗口中写入工程文件的名
37、称,并加上后綴uv2,如ex1.uv2。3.3.选择目标器件选择目标器件 在Project窗口中的Target1项目上右击,选择【Select Device for Target Target1】,可弹出选择单片机型号对话框,从对话框中的厂家和单片机列表中选择目标系统所用的单片机型号,本例选择AT89C51,见下图。l-79 选择目标器件型号对话框选择目标器件型号对话框NoImagel-80 4.4.设置生成设置生成HexHex代码文件代码文件 设置方法:右击Target1,选择【Option for Target Target1】,选择output,然后在下拉有关output选项菜单中,对
38、Create HEX File可选框中打。5.5.编译编译 执行主菜单【Project】-【Rebuild All Target Files】就能自动完成编译,生成后綴为obj、hex、m51、lst等文件。hex文件就是我们所需要的目标程序,可以利用编程器写入单片机的片内程序存储器。l-81 6.6.调试调试 Vision2环境可以对程序进行仿真调试,调试器有两种工作模式:Use Simulator工作模式 Use接口驱动工作模式 在右击【Option for Target Target1】弹出的对话框中选择Use Simulator模式,将调试器配置成纯软件模拟,不需要实际的硬件支持,就可
39、以进行模拟调试。若选择Use接口驱动模式,则需要在本机与相关硬件接口相连时才能使用。l-82 调试步骤调试步骤 1)执行主菜单【Debug】-【Start/Stop Debug Session】,进入调试窗口(如图)。同时会弹出反汇编窗口(如图)或执行主菜单【View】-【Disassembly Window】弹出反汇编窗口。在这个窗口里可以应用单步跟踪、设置断点、寄存器观察等手段进行调试。l-83 2)在目标程序的执行过程中,可以利用各种窗口(Regs窗口、Watch窗口、Serial窗口等)观察程序存储器、数据存储器和串口的状态,以检查程序运行是否符合设计要求,可随时修正程序中的错误,优化程序和提高效率。3)更详细的功能和操作,可查阅Keil C51手册和有关书籍。l-84 调试窗口调试窗口NoImagel-85 反汇编窗口反汇编窗口NoImagel-