第九章 单片机的 C51编程第一节 概述第二节 程序的格式第三节 数据类型和存储类型第四节 运算符和表达式第五节 指针与函数第六节 片内硬件资源的定义第七节 程序的基本结构第八节 C51程序举例第九节 Windows环境下 C51编译器的操作本章要点
介绍 C语言的基础知识。
掌握 C语言程序的基本结构,学会编制一些简单的单片机应用程序,并能在
Windows环境下使用 C51编译器进行编译操作。
了解 C51编译器与标准 C语言在存储模式、片内硬件资源使用等方面的差别。
第一节 概述随着开发工具及集成电路技术的发展,在开发大型的单片机应用系统时,使用高级语言更加有利 。
专门针对 8051系列单片机开发出来的 C51编译器 (简称 C51) 可编译生成能够在 8051系列单片机上运行的目标程序 。
目前针对 8051系列单片机开发出来的编译器有 多 种,包括 Franklin C51,Keil C51 for
windows等 。
返回本章首页第二节 程序的格式先从几个实例,了解 C语言的程序格式 。
例 9-1 能输出,Welcome to using C51”的 C语言程序
#include“stdio,h”
main()
{
printf(“Welcome to using C51 \n”);
}
其中 main( )为主函数,printf为输出函数,stdio.h
为头文件,执行这个程序的目的,是在屏幕上输出以下一行信息:
Welcome to using C51

例 9-2 求三个数 a,b,c的和 。
#include“stdio,h”
main() / *主函数 */
{int a,b,c,sum; / *定义变量 */
a=12; b=34; c=56; / *给变量赋值 */
sum=a十 b十 c; / *求和 */
printf(“sum is % d\ n”,sum);/ *显示结果 */
}
执行以上程序,可在屏幕上输出 a,b,c的和,并显示:
sum is 102
例 9-3 从输入的两个数 a,b中,求出较大的数的程序 。
#include“stdio,h”
int max(int x,int y) / *定义 max函数,函数返回值为整型; x,y为形式参数,整型 */
{ int z;
if(x>y) z=x;
else z=y;
return(z); / *将 z的值返回到调用处 */
}
main() / *主函数 */
{inta,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。
从三个例子可看出 C语言或 C51源程序的基本格式有如下特点:
1,C语言程序的书写格式比较自由,一行可以写若干条语句,一个语句也可以写成几行,
不管一行写几个语句,每个语句须以,;” 结尾 。
2.程序由一个主函数和若干个其他函数组成,
主函数的名字必须为 main。 程序的执行总是从
main函数开始的,其位置无特殊规定 。
3.C语言程序通过函数调用去执行指定的工作 。 源程序文件需要包含其他源程序文件的内容时,则要在本程序文件头部用包含命令
#include进行,文件包含,处理 。
返回本章首页第三节 数据类型和存储类型一、数据类型
C语言中的数据分为常量和变量,不论常量还是和变量都有几种不同类型,不同类型的数据占用的存储长度不同。
1.常量和符号常量的类型常量指程序运行时其值不能被改变的量,常量可以用一个标识符表示,并称为符号常量。 C
语言中的常量分为如下几种类型:
整型、实型、字符、字符串
2.变量类型变量名称 符号 类型 数据长度 值域范围位型量 bit 1位 0,1
字符型有符号 signed char 8位 -128~ +127
无符号 unsigned char 8位 -32768~ +32767
整数型 有符号 signed int 16位 0~ 255
无符号 unsigned int 16位 0~ 65535
长整型 有符号 signed long 32位 -231~ 232-1
无符号 unsigned long 32位 232-1
浮点型 float 32位 3.4E-38~ 3.4E+38
指针型 指针 8~24 对象地址特殊位型 sbit 1 0或 1
8位特殊功能寄存器型 sfr 8 0~ 255
16位特殊功能寄存器型 sfr16 16 0~ 65535
表 C51变量类型二,存储类型存储类型是指该数据在单片机系统中存放的位置,也就是数据的定位方式 。
存储类型 与存储空间的对应关系
data 直接寻址片内数据存储区,访问速度快 (128字节 )
bdata 可位寻址片内数据存储区,允许位与字节混合访问 (16字节 )
idata 间接寻址片内数据存储区,可访问片内全部 RAM地址空间
( 256字节)
pdata 分页寻址片外数据存储区 (256字节 )由 MOVX @R0,A指令访问
xdata 片外数据存储区 (64K),由 MOVX @DPTR,A指令访问
code 代码存储区 (64K),由 MOVC A,@A+DPTR指令访问表 C51存储类型表 C51不同存储类型的数据大小存储类型长度
(位)
长度
(字节 )
值域,范围
data 8 1 O~ 255(8bit即 OOH~ 0FFH)
bdata 1
idata 8 1 O~ 255(8bit即 OOH~ 0FFH)
pdata 8 1 O~ 255(8bit 即 OOH~ 0FFH)
xdata 16 2 O~ 65535 (16bit 即 0000H~ 0FFFFH)
code 16 2 0~ 65535 (16bit即 0000H~ 0FFFFH)
C51中定义变量除了定义数据类型外,还应定义存储类型例,int data x,y ; 表示变量 x,y 为 16位整数并指定存储在片内数据存储区。
1.若未定义存储类型,则 C51编译器自动选择默认存储类型如下表:
存储模式 默认的存储类型
SMALL 默认的存储类型为 data,最大为 128字节
COMPACT 默认的存储类型为 pdata,每页 256字节
LARGE 默认的存储类型为 xdata,最大为 64K
2.选择变量类型时应尽量选用无符号型,可以减少测试符号的额外操作,可以提高代码效率。
3.为使编程时书写简化,数据类型允许用缩写。
例,#define uchar unsigned char
#define ulong unsigned long
返回本章首页第四节 运算符和表达式一、算术运算符及其表达式
1.C语言的基本算术运算符算术运算符有 +,-,*,/,%(%为模运算符,
或称求余运算符 )。
用算术运算符或圆括号将运算对象包括常量、
变量、函数、数组等连接起来,形成符合 C 语法规则的式子称为算术表达式。
如,a*(b-c)+2.3+?a?
2.算术运算符的优先级先乘除模,后加减,括号最优先 。
3.算术运算符的结合性
,自左至右,,即运算对象两侧的算术运算符优先级相同时,先与左边运算符结合 。
4.数据类型不同时的转换如果运算符两侧的数据类型不同,则必须转换成同一类型,再进行运算 。 转换方式有自动转换 (默认 )和强制转换 。 强制转换的形式为:
类型名 ) 表达式 );
例,(double) x; (将 x强制转换成 double型 )
注,强制转换只转换表达式的值,变量类型不变 。
二,关系运算符及其表达式
1.六种关系运算符
> (大于 ) < (小于 )
>= (大于或等于 ) <= (小于或等于 )
!= (不等于 ) == (等于 )
2.关系运算符的优先级
1,>,<,>=,<=优先级相同,!=与 ==相同,
前四种高于后两种 。
2.关系运算符的优先级低于算术运算符 。
3.关系运算符的优先级高于赋值 (=)运算符 。
3.关系表达式用关系运算符将两个表达式 (算术表达式,
关系表达式,逻辑表达式等 )连接起来的式子称为关系表达式,其结果是逻辑值,即
,真,或,假,。 C语言没有逻辑型数据,
以 1代表真,以 0代表假 。
例如 a=1,b=2,c=3,则
x=a>b,因 a>b的值为,假,,所以 x的值为
0。
b >=( a+c) 的值为,假,,表达式的值为 0;
c>b的值为,真,,表达式的值为 1;
三,逻辑运算符及其表达式
1.三种 逻辑运算符
&& 逻辑与
(两个操作数都为真时,结果才为真,否则为假 。 )
|| 逻辑或
(只要两个操作数中有一个为真,结果便为真,否则为假 。 )
! 逻辑非
(对操作数的值取反 。 )
&&和 || 要求有两个操作对象,而 !是单目运算符,只要求有一个运算对象 。
2.逻辑运算符的优先级优先顺序为 !(非 ) 算术运算符 关系运算符 &&和 || 。 最低为赋值运算符 。
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
四,位操作运算符及其表达式
& 按位与 | 按位或
∧ 按位异或 ~ 按位取反
<< 位左移 >> 位右移除运算符~外,其余位操作运算符都是两目运算符 。
位运算符操作的对象只能是整型或字符型数据 。
1,按位与 &
参与运算的两操作数,只有双方相应的位都为 1,结果值中该位为 1,否则为 0。
即 O&O=O,O&l=0,l&O=0,l&l=l
例,a=0x31,b=0x56,求 a|b的值。
a|b=01110111B
2.按位或 ¦
参与运算的两操作数只要双方相应的位中有 1,其结果该位便为 1,否则为 0。
即 O | O =O,O| l=1,l | O=1,l | l=l
例,a=0x37,b=Ox7A求 a&b的值 。
a&b=00110010
3,按位取反 ~
对操作数按位取反,即 0变 l,1变 0 。
例,a=0x31,b=0x56,求 a∧ b的值。
a∧ b=01100111B
4,按位异或 ∧
参与运算的两操作数,如果对应位的值不同,运算结果该位为 1,否则为 0。即
O∧O=O,O∧l=1,l∧O=1,l∧l=0
例,a=0x3FH=00111111B,求~ a 的值。
~ a=11000000B
5,位左移和位右移移位运算时,将左操作数的各二进制位全部左 (右 )移若干位,所移位数由右操作数决定 。 移位后留出的空白位 补 0,
溢出的位 舍弃 。
例,a=Ox3E,求 a<<2的值。
求得 11111000 即 0XF8
例,a=0x3E,求 a>>2的值。
求得 00001111 即 0X0F
五,自增减运算符及其表达式作用:使变量的值增 1或减 l。
如,++i (使用 i之前,先使 i值增 1。 )
--i (使用 i之前,先使 i值减 1。 )
i++ (在使用 i之后,使 i值增 l。 )
i-- (在使用 i之后,使 i值减 1。 )
例:若 i=5 则 j=i++; (执行后 i=6,j=?)
j=++i; (I=6,j=6)
六,复合运算符及其表达式
C语言中的两目运算符都可以和赋值运算符,=” 一起组成复合赋值运算符 。
使用的复合赋值运算符有以下 10种:
+=,-=,*=,/=,%=,
<<=,>>=,&=,|=,~ =
例如 a += 2 等价于 a=a+2。
m *= n+1 等价于 m=m*(n+1)。
七,对指针操作的运算符
& 取地址运算符
* 取内容运算符
& 可作为取地址运算符,又可作为按位与,若为按位与,&” 的两边必须有操作对象 。
* 可作为取内容运算符,还可作为指针变量的标志,但作为指针变量标志时,
一定出现在对指针定义中 。
返回本章首页第五节 指针与函数一,指针与指针变量变量名对应于内存单元的地址,变量值则是放在内存单元中的数据 。 同时把存放变量 x的地址称为指针,使用指针前也必须定义 。
指针的定义为:
char xdata *data xp
也可以写成:
data char xdata *xp
定义指针与指针变量的注意点
1.指针变量名前面冠以,*” 号,如上例 *xp,表示 xp为指针。
2.定义时,应包括被指变量的数据类型、存储类型以及指针变量本身的存储类型。指针变量本身的存储类型,写在语句的开头,或者在 *号与变量名之间。
3.如果只标明被指变量的数据类型和存储类型,而没有指明指针变量本身的存储类型,则指针变量本身被默认为通用型。
指针与指针变量的定义举例例:定义一字符变量 x,并赋值为 6。
char data x
x=6
例:定义一指针 xp,指向 x所在的内存单元
char data *data xp
xp=&x
定义后要访问 x可以用两种办法:
1)直接访问,如 printf(“% d”,x)。
2)间接访问,如 printf(“% d”,*xp)。
二、函数
C51程序是由一个主函数和若干个其他函数所构成,程序中由主函数调用其他函数,其他函数也可以互相调用。
主函数其他函数标准库函数自定义函数无参数函数有参数函数程序
1,无参数函数的定义形式类型标识符 函数名 ()
{函数体语句 }
类型标识符用来指定函数返回值的类型 。 无参数函数一般不带返回值,可以不写类型标识符 。
例,dis()
{
printf(“ok\n”);
}
函数名函数体语句
2,有参数函数的定义形式类型标识符 函数名 (参数列表及说明 )
{函数体语句 }
例,int max(int x,int y)
{int z; / *函数体语句 */
if(x>y) z=x;
else z=y;
return (z); }
返回本章首页类型标识符 函数名 参数列表及说明第六节 片内硬件资源的定义一,特殊功能寄存器的定义
8051系列单片机的片内有 21个特殊功能寄存器 ( 简称 SFR),地址分散在片内 RAM的高端 128字节地址 80H-0FFH范围内,其中有 11个寄存器具有位寻址能力 。
在 C51中使用这些寄存器必须事先予以定义,定义后便可直接访问 。
1.用 sfr定义字节型特殊功能寄存器的标志符例如,
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”包含命令就无需一一定义 。
2.用 sfr16定义双字节型的特殊功能寄存器的标志符例如,sfr16 DP=0X82
使用注意
1) sfr16用 DPTR的低 8位地址定义 16位的特殊功能寄存器,仅 限于允许组合成 16位的特殊功能寄存器 (像 DPH,DPL)使用 。
2) 也可以 不用 sfr16,而 用 sfr对 DPH、
DPL分别定义,需要赋值时可分别赋值 。
3.用 sbit定义特殊功能寄存器位地址空间的位名称例如 sbit P1_0=P^0
sbit OV=PSW^2
sbit CY=PSW^7
CY也可以用下面两种方法定义:
sbit CY=0XD0^7
sbit CY=0XD7
OV也可以用下面两种方法定义:
sbit OV=0XD0^2
sbit OV=0XD2
二,存储器绝对地址定义在包含头文件 absacc.h的前提下,可以使用 #define指令定义不同存储空间各个变量的绝对地址 。
XBYTE表示 PORT所处的存储空间和数据长度,方括弧内表示 PORT的绝对地址。
语句 PORT=0X01 表示将数据 0X01赋予片外存储器 0X2000。
例,#define PORT XBYTE[0X2000]
1) CBYTE程序存储器空间,字节型 。
2) DBYTE片内 RAM空间,字节型 。
3) PBYTE分页操作的片外 RAM空间,字节型 。
4) XBYTE片外 RAM空间,字节型 。
5) CWORD程序存储器空间,字型 。
6) DWORD片内 RAM空间,字型 。
7) PWORD分页操作的片外 RAM空间,字型 。
8) XWORD片外 RAM空间,字型 。
表示以上将 0X01赋予片外存储器的规定关键字有八种返回本章首页第七节 程序的基本结构一、顺序结构顺序结构是指程序按语句的先后顺序逐句执行,
是最基本、最简单的 —种程序结构。例如以下输入半径值,求圆面积和周长的程序。
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,perimeter is % f\n”,s,y);
}
二,分支结构分支结构可分为单分支,双分支和多路分支三种 。
1.单分支语句形式
if(表达式 )
语句;
例,从键盘输入两实数,然后按值的大小顺序输出 ( 先小后大 ) 。
#include,stdio,h”
main()
{
float a,b,t;
scanf(“% f,% f”,&a,&b);
if(a>b)
{t=a; a=b;b=t}
printf(“% 5.2f,% 5.2f”,a,b);
}
2,双分支双分支语句的形式
if(表达式 )
语句 1;
else
语句 2;
例如,if(x=1)
y=x+5;
else
y=x*5;
分支语句嵌套分支语句可以嵌套使用,双分支语句嵌套后可实现多路分支,其语句形式为:
if(表达式 1) 语句 1;
else if(表达式 2) 语句 2;

else if(表达式 n—1) 语句 n-1;
else 语句 n;
3,多分支
C语言提供一种专门用于多分支的开关语句,流程图如图所示 。
多分支的语句形式
switch (表达式 )
{case 常量表达式 l,语句 1; break;
case 常量表达式 2,语句 2; break;

case 常量表达式 n,语句 n; break;
default,语句 n+1; break;
}
多分支语句程序举例例,给定一个百分制成绩,要求转换为五级记分制,规定 90分以上为 ‘ A?,80~ 89分为 ‘ B?,
70~ 79分为 ‘ C?,60~ 69分为 ‘ D? 60分以下为
‘ E?。
多分支语句程序举例
#include,stdio.h”
main()
{
int score,c;
char g;
printf(“请输入学生成绩:,);
scanf(“% d”,&score); / *从键盘输入 */
if((score>100| |(score<0))
printf(“\ n输入错误 !” ); / *大于 100小于 0*/
else
{
c=(score—score%10)/10;
多分支的语句实例 ( 续 )
switch(c)
{
case 10:
case 9,g=?A?; break;
case 8,g=?B?; break;
case 7,g=?C?; 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);
}
}
三,循环结构
1.while语句
while语句的形式,
while(表达式 )
循环体 ;
执行步骤是,先判断
(表达式 )是否成立。若成立 (其值为非 0)则执行循环体,否则退出循环去执行 while语句的下一条语句。
while语句实例求 1十 2十 3十 …100的和。
#include,stdio.h”
main()
{
int i,sum=0;
i=1;
while(i<=100)
{
sum=sum + i;
i++;
}
printf(“%d”,sum);
}
2.do...while语句语句形式,
do 循环体
while(表达式 );
先执行循环体,后判断表达式是否成立,若成立(表达式值为非零),返回重新执行循环体,否则(表达式值为零)停止循环。
Do...while语句实例用 do...while语句求 1十 2十 3十 …100的和
#include,stdio,h”
main()
{
int i,sum=0;
i=1;
do
{
sum=sum+i;
i++;
}
while(i<=100);
printf(“% d”,sum);
}
3.for语句语句形式,
for(exp1;exp2;exp3)
循环体 ;
例,用 for语句改写 1十 2十 3十 …100的和
#include”stdio.h”
main()
{
int t,sum=O;
for(i=1; i<100; i++) sum=sum+i;
printf(“% d”,sum);
}
返回本章首页第八节 C51程序举例一,,走马灯,电路设计一个实验电路,在 AT89C51并行接口 P1连接 8个 LED,
要求这 8个 LED能循环点亮。电路如图。
,走马灯,电路程序清单
#include"reg51.h”
delay(int t) /*延时函数 */
{ int i,j; /*采用默认的存储类型 */
/*用双重空循环延时 */
for(i=0; i<t; i++)
for(j=0; j<10; j++);
}
main() /*主函数 */
{
char data i,s;
,走马灯,电路程序清单 (续 )
while(1) /*无穷循环 */
{
s=0xfe; /*设置初值,最低一位为 0 */
P1=s; /*P1送据,令接 P1.0的 LED亮 */
delay(500);
for(i=0; i<8; i++)
{
s =s<<1; /*s值左移一位,最低位补 0 */
s=s¦ 0x01; /*将最低位置 1 */
P1=s; /*由 P1送出数据,令对应的 LED亮 */
delay(500);
}
}
}
二,数码管动态显示设计一个电路,利用外接可编程并行接口
8255,驱动数码管显示字符,电路如图所示。
数码管动态显示程序 清单
#include”stdio.h”
#include”reg5l.h” /*载入 C51头文件 */
#include"absacc.h”
#define cr XBYTE[0x8003]
#define pb XBYTE[0x8001]
#define pc XBYTE[OX8002]
#define CW 0x88
char d_7[4]={0x3f,0x06,0x5b,0x4f}/*0-3的字型段码数据 */
char con[4]={0xfe,0xfd,0xfb,Oxf7} /*扫描控制信号 */
数码管动态显示程序 (续 1)
delay(int t) /*延时函数 */
{int i,j;
for(i=0; i<t; i++)
for(j=0; j<10; j++);
}
scan() /*扫描显示函数 */
{char i;
for(i=0; i<4; i++)
{pb=d_7[i]; /*B口送出段码 */
pc=con[i]; /*C口送位码 */
delay(3);
}
}
数码管动态显示程序 (续 2)
main()
{cr=CW; / *定 8255工作模式 */
while(1) scan(); / *无穷循环
}
由于扫描速度很快,好像四个数码管同时发亮,即显示出,0123” 。
三,救护车警声程序本程序利用可编程发声器件 (PSG)芯片 AY-3-
8970产生救护车的警报声,电路如图,AY-3-
8970内部寄存器所载入的数据与所实现的功能参看表 9-6。
救护车警报声程序
#include,reg5l.h” /*载入 C51头文件 */
#include "absacc.h”
#include,stdlib.h”
#define psg_reg XBYTE[0x9000]
#define psg_data XBYTE[OX9001]
delay(int t) /*延时函数 */
{int i,j;
for(i=0; i<t; i++) for(j=0; j<5; j++);
}
flash() /*工作灯闪烁函数 */
{char i;
for(i=0; i<3; i++)
{P1=0x80; delay(40);
P1=0;delay(40);
}
}
救护车警报声程序 (续 1)
setpeg(int r,int d) /*向 PSG送数函数 */
{psg_reg=r; /*选择寄存器 */
psg_data=d; /*d写入指定存储器 */
}
alarm() /*发警报声函数 */
{setpsg(0,5);
setpsg(1,1); /*产生 440Hz的声音 */
setpsg(7,62); /*R7=62启用音调发声器 */
setpsg(8,15); /*R6=15声道的振幅最大 */
delay(300);
setpsg(0,104); /*R0=104*/
setpsg(1,2); / *产生 180Hz声音 */
救护车警报声程序 (续 2)
delay(300);
setpsg(8,0); /*音量设为 0*/
}
main()
{setpsg(7,63); /* 关闭音调发声器 */
flash(); /*调用 LED闪烁函数 */
delay(800);
while(1) /*无穷循环 */
alarm(); /*调用警报声函数 */
}
四,C51中断程序举例在 C51中,中断服务程序定义为函数,并规定用下列形式表示函数名 interrupt n [using m]
将上述,走马灯,
电路改用开关控制,
并采用中断方式如图所示,要求开关每拨动一次,点亮的 LED向前移动一个位置。
,走马灯,电路中断方式程序
#include"reg51.h”
char i;
char s=0xfe;
led1() interrupt 2 /*使用 INT1则 N=2*/
{
if(i<8){s=s<<1; s=s¦ 0x01; P1=s; i++; }
else {i=0 ; s=0xfe; }
}
,走马灯,电路中断方式程序 (续 )
main() /*主函数 */
{
EA=1; /*开中断 */
EX1=1; /*允许外部中断 1中断 */
IT1=1; /*下降沿触发方式 */
P1=0xfe; /*点亮第一个 LED*/
while(1); /*无穷循环等待中断 */
}
main()的任务是开中断,通过中断函数将 1
左移,并在左移 8次后,回到原始状态 。
返回本章首页第九节 Windows环境下 C51编译器的操作
C51语言的程序设计之后,需要经过 编译,优化,链接 等过程,转换成在单片机上能运行的
HEX文件,才能固化到程序存储器 。
Keil公司的 C51编译器是基于 Windows环境下的产品,包括汇编器 A51,编译器 C51,连接器
BL51和文件转换器 OH51等工具,还有集成编译环境 μVision2。 用户在此环境下可以完成源程序的编写,编译,连接,仿真调试及项目管理等操作 。
一,Keil C51的安装安装步骤执行
SETUP
插入 Keil C51
安装盘指定的安装目录 安装安装完成后此目录下有两个子目录:
UV2 在 UV2子目录中,有 μ Vision2可 执行文件
UV2.EXE。
C51 在 C51\BIN子目录中有汇编器 A51,编译器 C51、
连接器 BL51和文件转换器 OH51等执行文件以及一些存放芯片驱动程序的动态链接库 (.DLL);
在 C51\INC子目录中,装有编译需要的头文件 (*.H);
在 C51\LIB子目录中,装有 C51的标准函数库,LIB)。
二,C51程序的编写和调试执行 V2子目录中的 UV2.EXE,启动
μ Vision2,进入主窗口,用窗口中的文件编辑器编写 C51程序,程序格式应遵循
C语言的语法规则 。
编写完 C51程序后,在 μ Vision51环境下就可以进行编译,连接,如果编译连接成功,还可以调用软件仿真器进行调试 。
μ Vision2主窗口
1,编辑源文件单击主菜单项【 File】 ->【 New】,弹出编辑窗口如图,可以在此窗口中编辑 C51程序。
2.建立工程文件编写好程序,执行主菜单 Project】 ->【 New
Project】 选项,在弹出的窗口中写入工程文件的名称,并加上后綴 uv2,如 ex1.uv2。
3,选择目标器件在 Project窗口中的 Target1项目上右击,选择【 Select Device for Target?Target1?】,
可弹出选择单片机型号对话框,从对话框中的厂家和单片机列表中选择目标系统所用的单片机型号,本例选择 AT89C51,见下图。
选择目标器件型号对话框
4.设置生成 Hex代码文件设置方法:右击 Target1,选择【 Option for
Target?Target1?】,选择 output,然后在下拉有关 output选项菜单中,对 Create HEX File可选框中打 √ 。
5.编译执行主菜单【 Project】 ->【 Rebuild All Target
Files】 就能自动完成编译,生成后綴为 obj,hex、
m51,lst等文件。 hex文件就是我们所需要的目标程序,可以利用编程器写入单片机的片内程序存储器 。
6,调试
μ Vision2环境可以对程序进行仿真调试,
调试器有两种工作模式:
Use Simulator工作模式
Use接口驱动 工作模式在右击【 Option for Target?Target1?】
弹出的对话框中选择 Use Simulator模式,将调试器配置成纯软件模拟,不需要实际的硬件支持,就可以进行模拟调试。
若选择 Use接口驱动模式,则需要在本机与相关硬件接口相连时才能使用。
调试步骤
1) 执行主菜单 【 Debug】 ->【 Start/Stop Debug
Session】,进入调试窗口 ( 如图 ) 。 同时会弹出反汇编窗口 ( 如图 ) 或执行主菜单 【 View】 -
【 Disassembly Window】 弹出反汇编窗口 。 在这个窗口里可以应用单步跟踪,设置断点,寄存器观察等手段进行调试 。
2) 在目标程序的执行过程中,可以利用各种窗口 ( Regs窗口,Watch窗口,Serial窗口等 ) 观察程序存储器,数据存储器和串口的状态,以检查程序运行是否符合设计要求,可随时修正程序中的错误,优化程序和提高效率 。
3)更详细的功能和操作,可查阅 Keil C51手册和有关书籍。
调试窗口反汇编窗口返回本章首页