购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

4.3 C语言的数据类型与运算符

4.3.1 数据类型

数据是计算机处理的对象,计算机要处理的一切内容最终将以数据的形式出现。因此,程序设计中的数据有着很多种不同的含义,不同的数据类型往往以不同的形式表现出来,这些数据在计算机内部进行处理、存储时往往有着很大的区别。所以,必须掌握 C语言的数据类型。

C语言中常用的数据类型有整型、字符型、实型、指针型和空类型等。而根据变量在程序执行中是否发生变化,还可将数据类型分为常量与变量两种。在程序中,常量可以不经说明而直接引用,而变量则必须先定义类型后才能使用。

1.常量与变量

在程序运行过程中,其值不能被改变的量称为常量。常量区分为不同的类型,如 12、0为整型常量,3.14、2.55 为实型常量,'a'、'b'是字符型常量。

C语言中还常一种符号常量,其定义形式如下:

#define 符号常量的标志符常量

其中,#define是一条预编译处理命令,称为宏定义命令,其功能是把该标志符定义为其后的符号常量值。一经定义,在程序中所有出现该标志符的地方,就用之前定义好的常量来代替。习惯上符号常量的标志符用大写字母来表示,示例如下:

img

程序的第一行定义了一个符号常量 PI,它的值为 3.1415926。在后面的程序中,凡是出现PI的地方,都代表这个值。

使用符号常量的好处是显然的:当程序中有很多地方要用到某个常量,而其值又需要经常改动,使用符号常量就可以“一改全改”。

在程序运行中,其值可以改变的量称为变量,变量标志符常用小写字母来表示。变量必须先定义后使用,一般放在程序的开头部分。

2.整型数据

整型数据包括整型常量和整型变量。

1)整型常量

整型常量就是整型的常数。在 C语言中,整型常量可以分为八进制、十进制和十六进制3种。

十进制数没有前缀,用0~9来表示,如210、-174等。

八进制数必须以“0”开头,即以“0”作为八进制的前缀,用 0~7来表示,如 016(相当于十进制数14)。

十六进制数必须以“0x”开头,即以“0x”作为十六进制的前缀,用0~9和A~F来表示,如0x1A(相当于十进制数26)、0xB0(相当于十进制数176)。

2)整型变量

整型变量可分为基本型和无符号型两类,前者类型说明符为 int,在内存中占两个字节;后者类型说明符为unsigned,在内存中占两个字节。Keil C51编译器所支持的数据类型如表4-1所示。

表4-1 数据类型表

img

整型变量的定义形式如下:

类型说明符 变量标志符1,变量标志符2,……;

例如:

int a, b, max; // 各变量名之间用一个逗号间隔。

3.实型数据

实型数据在 C语言中有两种表示形式:十进制小数形式和指数形式。本书没有用到实型数据,所以不对其进行详细介绍。

4.字符型数据

字符型数据包括字符常量和字符变量。

1)字符常量

用单引号括起来的一个字符,称为字符常量,如'x'、'u'、' ='和'+'等。字符常量常用作显示说明。

2)字符变量

字符变量用来存储单个字符,其说明符是“char”,定义形式如下:

char a, b;

char型数据的长度是1个字节。unsigned char 与signed char型数据的区别是有无符号位,前者可以表达的数值范围是0~255;而后者的范围是-128~127。

3)字符串常量

由一对双引号括起来的字符序列,称为字符串常量,如“BeiJing Time :”、“Volt=”等。

5.指针型数据

指针是一个特殊的变量,它存储的是某变量的地址,使用指针是 C语言的精华所在,其使用方法在后面介绍。

6.位类型数据

位类型数据是 C51编译器的一种扩充数据类型,利用它可以定义一个位变量,但不能定义位指针,也不能定义位数组。该类型数据只能有两个取值:“1”或“0”。

7.空类型数据

C语言经常使用函数,当函数被调用完后,通常会返回一个函数值。函数值也有一定类型,示例如下:

img

函数add( )返回一个整型数据,就说该函数是整型函数。

但常有些函数不需要返回函数值。例如,LED流水点亮控制程序中的延时函数:

img

这种函数称为“空类型”,其类型说明符为“void”。

8.变量赋值

在程序中常常需要对变量赋值,C语言中的赋值方法如下:

类型说明符变量=值;

例如:

img

C语言中各种类型的数据运算必须借助于运算符和表达式才能进行,下面介绍几种重要的运算符与表达式。

4.3.2 运算符

1.算术运算符

C语言有5种算术运算符,如表4-2所示。

表4-2 算术运算符

img

C语言中表示加 1和减 1时可以采用简洁的运算符:自增运算符和自减运算符,如表4-3所示。

表4-3 自增运算符和自减运算符

img
2.关系运算符

在程序中经常需要比较两个变量的大小关系,以便对程序的功能进行选择。用以比较两个数据量的运算符称为关系运算符。C语言有6种关系运算符,如表4-4所示。关系运算的结果只有“0”和“1”两种,即条件满足时结果为“1”;否则为“0”。例如,a+b>c的值,当a=3,b=4,c=9时,结果为“0”;而当a =3,b=4,c=2时,结果为“1”。

表4-4 关系运算符

img
3.逻辑运算符

逻辑运算的结果只有“真”和“假”两种,用“1”表示真,用“0”表示假。即当逻辑条件满足时为真,不满足时为假。C语言的逻辑运算符有3种,如表4-5所示。

表4-5 逻辑运算符

img

例如,条件“25>100”为假,“4<8”为真,则逻辑“与”运算:(25>100)&&(4<8)= 0&&1=0。因为“与”运算的规则是“有0出0”,所以该计算结果为0。

4.位运算符

在单片机开发中经常要对一些数据进行位操作,C语言提供了位运算功能。利用位操作运算符可对一个数按二进制格式进行位操作。下面以 x=25(二进制数 00011001B),y=77(二进制数01001101B)为例来说明位运算符的使用。

1)按位“与”运算符“&”

“&”运算符的功能是对两个二进制数按位进行“与”运算。根据“与”运算规则“有0为0,全1出1”,则

img

0000 1001B化为十进制,结果为9。所以,25&77=9。

2)按位“或”运算符“|”

“|”运算符的功能是对两个二进制数按位进行“或”运算。根据“或”运算规则“有1 为1,全0出0”,则

img

0101 1101B化为十进制,结果为93。所以,25|77=93。

3)按位“异或”运算符“^”

“^”运算符的功能是对两个二进制数按位进行“异或”运算。根据“异或”运算规则“相异为1,相同出0”,则

img

0101 0100B=0x54=5×16+4=84。所以,25^77=84。

4)按位“取反”运算符“~”

“~”运算符的功能是对二进制数按位取反。例如,要对变量 z=0x0f按位取反,将 z化为二进制为0000 1111B,根据取反规则“有0出1,有1出0”,则

img

1111 0000B化为十六进制,结果为0xf0。所以,~x=0xf0。

5)左移运算符“<<”

“<<”运算符的功能是将一个二进制数的各位全部左移若干位,移动过程中,高位丢弃,低位补0。例如w=0x3a,化为二进制即0011 1010B,若将各二进制位全部左移两位,可通过左移运算符“<<”进行,其方法是 w<<2,则变量 w=1110 1000B,化为十六进制,结果为0xe8。

6)右移运算符“>>”

“>>”运算符的功能是将一个二进制数的各位全部右移若干位,正数在移动过程中,低位丢弃,高位补0;负数则高位补1。例如w=0x0f,化为二进制即0000 1111B,若将各二进制位全部右移两位,可通过左移运算符“>>”进行,其方法是 w>>2,则变量 w=0000 0011B,化为十六进制,结果为0x03。

5.赋值运算符

赋值运算符用于赋值运算,它将一个数据赋给一个变量,也可以将一个表达式的值赋给一个变量。C 语言中有以下两类赋值运算符。

1)简单赋值运算符(=)

赋值运算符“=”的作用是将一个数据赋给一个变量,如c=a+b。

2)复合赋值运算符(+=、-=、*=、/=、%=、&=、|=、^=、>>=、<<=)

使用复合赋值运算符可以简化程序,提高 C程序的编译效率并产生质量较高的目标代码。下面举例说明其效果。

➢ a+=5等价于a=a+5

➢ x*=y+7 等价于x=x*(y+7)

➢ r%=p 等价于r=r%p

➢ a<<=3 等价于a=a<<3,即将a的二进制位全部左移3位后,再将移位后的值赋给a

C语言赋值运算符的意义及其说明如表4-6所示。

表4-6 C语言赋值运算符的意义及其说明

img
6.逗号运算符

逗号运算符用于将几个表达式串在一起,格式如下:

表达式1,表达式2,......,表达式n

运算顺序为从左到右,整个逗号表达式的值是最右边表达式的值,如 x=(y=3,z=5,y+2),结果为z=5,y=3,x=y+2=5。

7.条件运算符

C语言提供了一个条件运算符“?:”,它要求有3个运算对象,用它可以将3个表达式连接构成一个条件表达式。其一般形式如下:

逻辑表达式?表达式1:表达式2

首先计算逻辑表达式,当其值为真(非0)时,将表达式1的值作为整个表达式的值;当逻辑表达式为假(0)时,将表达式2的值作为整个表达式的值。

例如,当a=8,b=13时,求a、b中的最大值可用下式:

max=(a>b)?a:b

因为a>b为假,所以应取表达式2即b的值,结果max=13。

8.强制转换运算符

当参与运算的数据类型不同时,则先转换成同一数据类型,再进行运算。数据类型的转换方式有两种:一种是自动类型转换;另一种是强制转换。在 C语言程序中进行算术运算时,必须注意数据类型的转换。

自动类型转换是在对程序进行编译时由编译器自动处理的。自动类型转换的基本规则是转换后计算精度不降低,所以当 char、int、unsigned、long、double类型的数据同时存在时,其转换高低关系为char→int→unsigned →long→double。例如,当char型数据与int型数据共存时,则先将char型转化为int型再计算。

强制转换是通过强制类型转换运算符“()”进行的,其作用是将一个表达式转化为所需类型,格式如下:

(类型名)(表达式)

示例如下:

img

下面举例说明数据类型与运算符的使用方法。

4.3.3 实例8:用不同数据类型控制LED的闪烁

本例使用无符号整型数据和无符号字符型数据来设计延时函数,并分别用以控制图 4-2 中D1和D2的闪烁,从而研究这两种数据的不同效果。

1.实现方法

为比较无符号整数型数据和无符号字符型数据的使用效果,可将由它们设计延时函数的循环次数设置为相同,然后比较其延时效果。

img

图4-2 不同数据类型控制LED闪烁的电路原理图

2.程序设计

先建立文件夹“ex8”,然后建立“ex8”工程项目,最后建立源程序文件“ex8.c”。输入以下源程序:

img
img
3.用Proteus软件仿真

经Keil软件编译通过后,可利用Proteus软件进行仿真。在Proteus ISIS工作环境中绘制好图 4-2所示仿真原理图,或者打开配套光盘中的“仿真实例\第四章\ ex8”文件夹内的“ex8.DSN”仿真原理图文件。再将虚拟示波器的输入信号通道 A、B分别连接在 P1.0和P1.4引脚。然后载入编译好的“ex8.hex”文件。启动仿真。可看到D1的闪烁时间明显慢于D2,即整形数据实现的延时函数延时间明显较长。图 4-3(a)、(b)所示分别为某时刻的仿真效果图及 P1.0、P1.4口的输出波形。从波形图上也可以看出,P1.0口输出的低电平长度(D1的点亮时间)明显长于P1.4口输出的低电平长度。

img

图4-3 控制两个LED闪烁的仿真效果

由于整型数据占两个字节,而无符号字符型仅占一个字节,因此对无符号整型数据进行操作花费的时间就要长一些。例如,整型数据实现100次循环,消耗的时间约为800个机器周期;而用无符号字符型数据同样实现100次循环,消耗的周期则只有300个机器周期。所以,为了提高程序的运行速度,尽可能采用无符号字符型数据进行程序设计。

4.用实验板实验

程序仿真无误后,将“ex8”文件夹中的“ex8.hex”文件烧录入AT89S51芯片中。再将烧录好的单片机插入实验板上,为实验板通电,可看到和仿真类似的实验结果。

4.3.4 实例9:用P0口、P1 口分别显示加法和减法运算结果

本实例利用单片机实现“63+40”和“63-40”两道加、减法运算,并将加法计算结果送P1口显示,减法计算结果送P0口显示。本实例采用的电路原理图如图4-4所示。

img

图4-4 用P0口、P1口分别显示加法和减法运算结果的电路原理图

1.实现方法

设置两个无符号字符型变量n和m,并将其分别赋值为60和43,然后直接将(n+m)和(n-m)的结果分别送入寄存器P1和P0。

2.程序设计

先建立文件夹“ex9”,然后建立“ex9”工程项目,最后建立源程序文件“ex9.c”。输入以下源程序:

img
img
3.用Proteus软件仿真

经Keil软件编译通过后,可利用Proteus软件进行仿真。在Proteus ISIS工作环境中绘制好图 4-4所示仿真原理图,或者打开配套光盘中的“仿真实例\第四章\ex9”文件夹内的“ex9.DSN”仿真原理图文件。将编译好的“ex9.hex”文件载入AT89C51,启动仿真。如图4-5所示,可看到 P1.3、P1.4、P1.7 口的 LED被点亮,表明 P1=0110 0111B = 0x67 = 6 × 16 + 7 = 96 + 7 = 103和“63+40=103”的预期结果相同。P0口的输出结果请读者自行分析。

img

图4-5 用P0口、P1口分别显示加法和减法运算的仿真效果图

4.用实验板实验

程序仿真无误后,将“ex9”文件夹中的 hex文件烧录入 AT89S51芯片中。通电运行后,即可看到和仿真类似的实验结果。

4.3.5 实例10:用P0、P1口显示乘法运算结果

本实例用单片机实现乘法“64×71”的运算,并将结果送P1口和P0显示,结果用LED的亮灭状态验证。本实例仍然采用图4-4所示电路原理图。

1.实现方法

先设置两个字符型变量m和n,并将其赋值为64和71。再设置一个整形变量s存储m 和n的乘积。因为s=64×71=4544,需要16位二进制数表示,可将高8位送P1口,低8位送P0口。如果“4544”化为十六进制后为 H 3 H 2 H 1 H 0 ,必有

H 3 ×16×16×16+ H 2 ×16×16+ H 1 ×16+ H 0 ×1=4544

H 3 ×16+ H 2 )256+ H 1 ×16+ H 0 ×1=4544

所以,将 4544除以256取整就可以得到表示4544的 16位二进制数的高8位,而将4544除以256求余数,就可以得到表示4544的16位二进制数的低8位。所以

img
2.程序设计

先建立一个文件夹“ex10”,然后建立“ex10”工程项目,最后建立源程序文件“ex10.c”。输入以下源程序:

img
3.用Proteus软件仿真

经Keil软件编译通过后,可利用Proteus软件进行仿真。在Proteus ISIS工作环境中绘制好图 4-4所示仿真原理图,或者打开配套光盘中的“仿真实例\第四章\ex10”文件夹内的“ex10.DSN”仿真原理图文件。将编译好的“ex10.hex”文件载入 AT89C51,启动仿真。如图 4-6所示,可以看到 P1.0、P1.4口的 LED熄灭,其余均被点亮,表明高 8位数 P1= 0001 0001B =0x11;而P0口除P0.6和P0.7口的LED熄灭外,其余均被点亮,表明低8位数P0=1100 0010=0xc0,则 P1、P0表示的十六进制数即 11C0H,化为十进制数:1×16×16×16+ 1×16×16+12×16+0=4096+256+192=4544。这个结果和“64×71=4544”相同。

img

图4-6 P0、P1口显示乘法运算的仿真效果图

4.用实验板实验

程序仿真无误后,将“ex10”文件夹中的“ex10.hex”文件烧录入AT89S51芯片中。再将烧录好的单片机插入实验板上,通电运行即可看到和仿真类似的实验结果。

4.3.6 实例11:用P1、P0口显示除法运算结果

本实例用单片机实现除法“36÷5=7.2”的运算,所得商的整数部分送 P1口显示,小数部分送P0口显示。本实例采用的电路原理图如图4-4所示。

1.实现方法

整数部分“7”可用除法运算“36/5=7”来实现,小数部分“0.2”的实现过程如下:

36除以5的余数为1,若用除法运算“1/5”则得“0”(小数部分自动舍去)。因此需将余数“1”再乘以10,然后用所得的积除以“5”,即

((36%5)*10)/5;   //结果为(1*10)/5=2

结果为小数部分的数字“2”。

注意 :上述方法在单片机控制小数的显示时非常有用,如温度为29.6℃。

2.程序设计

先建立文件夹“ex11”,然后建立“ex11”工程项目,最后建立源程序文件“ex11.c”。输入以下源程序:

img
3.用Proteus软件仿真

经 Keil软件编译通过后,可利用 Proteus软件进行仿真。在Proteus ISIS工作环境中绘制好图 4-4所示仿真原理图,或者打开配套光盘中的“仿真实例\第四章\ex11”文件夹内的“ex11.DSN”仿真原理图文件。将编译好的“ex9.hex”文件载入 AT89C51,启动仿真。如图4-7所示,可看到P1口的P1.0、P1.1、P1.2引脚的LED熄灭,其余均被点亮,表明P1=0000 0111B =0x07=7,与“36/5=7”的期望结果相同;而P0口只有P0.1引脚的LED熄灭,其余均被点亮,表明 P0=0000 0010=0x02=2,与“36÷5=7.2”所得小数部分数字是“2”的期望结果相同。

img

图4-7 用P1、P0口显示除法运算结果

4.用实验板实验

程序仿真无误后,将“ex11”文件夹中的“ex11.hex”文件烧录入AT89S51芯片中。再将烧录好的单片机插入实验板上,通电运行即可看到和仿真类似的实验结果。

4.3.7 实例12:用自增运算控制P0口8位LED的闪烁花样

本实例用自增运算控制P0口8位LED的流水花样,采用的电路原理图如图4-4所示。

1.实现方法

只要送到P0口的数值发生变化,P0口8位LED点亮的状态就会发生变化。可以先将变量的初值送到 P0口延时一段时间,再利用自增运算使变量加 1,然后将新的变量值送到P0口并延时一段时间……即可使8位LED的闪烁花样不断变化。

2.程序设计

先建立文件夹“ex12”,然后建立“ex12”工程项目,最后建立源程序文件“ex12.c”。输入以下源程序:

img
3.用Proteus软件仿真

经Keil软件编译通过后,可利用Proteus软件进行仿真。在Proteus ISIS工作环境中绘制好图 4-4所示仿真原理图,或者打开配套光盘中的“仿真实例\第四章\ex12”文件夹内的“ex12.DSN”仿真原理图文件,将编译好的“ex12.hex”文件载入 AT89C51。启动仿真,即可看到P0口8位LED的闪烁花样不断发生变化,其仿真效果图略。

4.用实验板实验

程序仿真无误后,将“ex12”文件夹中的“ex12.hex”文件烧录入AT89S51芯片中。再将烧录好的单片机插入实验板上,通电运行即可看到和仿真类似的实验结果。

4.3.8 实例13:用P0口显示逻辑“与”运算结果

本实例用P0口显示逻辑“与”运算(4>0)&&(9>0xab)的结果,所采用电路原理图如图4-4所示。

1.实现方法

逻辑表达式的计算过程是(4>0)&&(9>0xab)=1&&0=0,直接将这个值送到P0口即可(8位LED将被全部点亮)。

2.程序设计

先建立文件夹“ex13”,然后建立“ex13”工程项目,最后建立源程序文件“ex13.c”。输入以下源程序:

img
3.用Proteus软件仿真

经Keil软件编译通过后,可利用Proteus软件进行仿真。在Proteus ISIS 工作环境中绘制好图 4-4所示仿真原理图,或者打开配套光盘中的“仿真实例\第四章\ex13”文件夹内的“ex13.DSN”仿真原理图文件,将编译好的“ex13.hex”文件载入 AT89C51。启动仿真,即可看到P0口8位LED被全部点亮,仿真效果图略。

4.用实验板实验

程序仿真无误后,将“ex13”文件夹中的“ex13.hex”文件烧录入AT89S51芯片中。再将烧录好的单片机插入实验板上,通电运行即可看到和仿真类似的实验结果。

4.3.9 实例14:用P0口显示条件运算结果

本实例用P0口显示条件运算“(8>4)?8:4”的结果,所采用的电路原理图如图4-4所示。

1.实现方法

条件运算“(8>4)?8:4”的计算过程:先判断条件“8>4”是否满足,若满足,取8作为计算结果,否则取4作为计算结果。显然本实例条件运算的结果为8,直接将该结果送到P0口即可。

2.程序设计

先建立文件夹“ex14”,然后建立“ex14”工程项目,最后建立源程序文件“ex14.c”。输入以下源程序:

img
3.用Proteus软件仿真

经Keil软件编译通过后,可利用Proteus软件进行仿真。在Proteus ISIS工作环境中绘制好图 4-4所示仿真原理图,或者打开配套光盘中的“仿真实例\第四章\ex14”文件夹内的“ex14.DSN”仿真原理图文件,将编译好的“ex14.hex”文件载入 AT89C51。启动仿真,可看到P0口的8位LED中,只有 P1.3引脚LED熄灭,其余均被点亮。所以,P0=0000 1000B =8,与预期结果相同,其仿真效果图略。

4.用实验板实验

程序仿真无误后,将“ex14”文件夹中的“ex14.hex”文件烧录入AT89S51芯片中。再将烧录好的单片机插入实验板上,通电运行即可看到和仿真类似的实验结果。

4.3.10 实例15:用P0口显示按位“异或”运算结果

本实例用 P0口显示“异或”运算“0xa2^0x3c”的结果,所采用电路原理图如图 4-4所示。

1.实现方法

“异或”运算的规则是“相异出1,相同出0”。据此,本例计算结果如下:

img

将结果送到 P0口即可。因为 P0=1001 1110B=0x9e,可以预计 P0.0、P0.5、P0.6引脚LED将被点亮,而其他LED均处于熄灭状态。

2.程序设计

先建立文件夹“ex15”,然后建立“ex15”工程项目,最后建立源程序文件“ex15.c”。输入以下源程序:

img
img
3.用Proteus软件仿真

经Keil软件编译通过后,可利用Proteus软件进行仿真。在Proteus ISIS工作环境中绘制好图 4-4所示仿真原理图,或者打开配套光盘中的“仿真实例\第四章\ex15”文件夹内的“ex15.DSN”仿真原理图文件,将编译好的“ex15.hex”文件载入 AT89C51。启动仿真,可看到只有P0.0、P0.5、P0.6引脚LED被点亮,与预期结果相同,其仿真效果图略。

4.用实验板实验

程序仿真无误后,将“ex15”文件夹中的“ex15.hex”文件烧录入AT89S51芯片中。再将烧录好的单片机插入实验板上,通电运行即可看到和仿真类似的实验结果。

4.3.11 实例16:用P0显示左移运算结果

本实例用P0口显示左移运算“0x3b<<2”的结果,所采用电路原理图如图4-4所示。

1.实现方法

左移运算“0x3b<<2”的计算过程:先将 0x3b转化为二进制数(由单片机自动完成)0011 1011,然后再将所有二进制位左移两位。移动过程中,高位丢弃,低位补 0。按此规则,0011 1011左移两位后得到1110 1100。将此结果送到P0口,将使P0.0、P0.1、P0.4引脚LED点亮。

2.程序设计

先建立文件夹“ex16”,然后建立“ex16”工程项目,最后建立源程序文件“ex16.c”。输入以下源程序:

img
3.用Proteus软件仿真

经Keil软件编译通过后,可利用Proteus软件进行仿真。在Proteus ISIS工作环境中绘制好图 4-4所示仿真原理图,或者打开配套光盘中的“仿真实例\第四章\ex16”文件夹内的“ex16.DSN”仿真原理图文件,将编译好的“ex16.hex”文件载入 AT89C51。启动仿真,可看到P0.0、P0.1、P0.4引脚LED被点亮,与预期结果相同,其仿真效果图略。

4.用实验板实验

程序仿真无误后,将“ex16”文件夹中的“ex16.hex”文件烧录入AT89S51芯片中。再将烧录好的单片机插入实验板上,通电运行即可看到和仿真类似的实验结果。

4.3.12 实例17:“万能逻辑电路”实验

本实例以单片机实现逻辑函数“F= img Y+Z”为例,介绍单片机实现“万能逻辑电路”的方法。本实例采用图4-8所示的电路原理图。

img

图4-8 实现逻辑函数的电路原理图及仿真效果图

逻辑函数的实现有两个基本途径:一是专门设计数字电路,实现逻辑功能;二是通过单片机编程来实现逻辑功能,即“软件就是硬件”。显然,用软件代替硬件有着很大的灵活性和更广阔的使用范围。因此,单片机被称为“万能逻辑电路”。

1.实现方法

因为输入量的逻辑电平只有两种(按下按键为 0,松开按键为 1),所以可将这 3个输入量分别定义为位变量(X定义为P1.5,Y定义为P1.6,Z定义为P1.7),则可以使用位的逻辑运算符(&、|、~)来实现逻辑函数。

F=((~X)&Y)|Z ; //通过位运算实现逻辑函数

先将X取反后再和Y进行“与”运算,然后将所得结果和Z进行“或”运算,最后将结果赋给F。

2.程序设计

先建立文件夹“ex17”,然后建立“ex17”工程项目,最后建立源程序文件“ex17.c”。输入以下源程序:

//实例17:“万能逻辑电路”实验

img
3.用Proteus软件仿真

经Keil软件编译通过后,可利用Proteus软件进行仿真。在Proteus ISIS工作环境中绘制好图4-8所示仿真原理图,或者打开配套光盘中的“仿真实例\第四章\ ex17”文件夹内的“ex17.DSN”仿真原理图文件,将编译好的“ex17.hex”文件载入 AT89C51。启动仿真,可以看到,当用鼠标按下按键SZ时,P0.4引脚LED被点亮,仿真效果如图 4-8所示。因为此时X=1,Y=1,Z=0,所以F=((~1)&1)|0=(0&1)|0=0|0=0。因为F被位定义为P1.4,其逻辑值的变化将被反映为 P1.4引脚的电平信号变化,“0”表示低电平,所以 P1.4引脚LED被点亮。

4.用实验板实验

程序仿真无误后,将“ex17”文件夹中的“ex17.hex”文件烧录入AT89S51芯片中。再将烧录好的单片机插入实验板上,通电运行即可看到和仿真类似的实验结果。

4.3.13 实例18:用右移运算流水点亮P1口8位LED

本实例用右移运算“>>”流水点亮 P1口的 8位 LED,所采用电路原理图如图 4-4所示。

1.实现方法

因为右移运算的结果是低位丢弃,高位补0,所以可将P1置为0xff,即二进制数1111 1111,那么将各二进制位右移1位后,即经“P1=P1>>1”运算1次后,最高位将被补0,而最低位的 1被丢弃,结果 P1=0111 1111B;然后再将各二进制位右移 1位,则 P1=0011 1111B……经8次右移运算后,P1=0000 0000B。待8位LED全部点亮后,重新将P1置为0xff,如此循环,就可以流水点亮P1口的8位LED。

2.程序设计

先建立文件夹“ex18”,然后建立“ex18”工程项目,最后建立源程序文件“ex18.c”。输入以下源程序:

img
img
3.用Proteus软件仿真

经Keil软件编译通过后,可利用Proteus软件进行仿真。在Proteus ISIS工作环境中绘制好图 4-4所示仿真原理图,或者打开配套光盘中的“仿真实例\第四章\ex18”文件夹内的“ex18.DSN”仿真原理图文件,将编译好的“ex18.hex”文件载入 AT89C51。启动仿真,即可看到P1口8位LED被循环流水点亮。

4.用实验板实验

程序仿真无误后,将“ex18”文件夹中的“ex18.hex”文件烧录入AT89S51芯片中。再将烧录好的单片机插入实验板,通电运行即可看到和仿真类似的实验结果。 cKTcp/kIdJxJ1oR1Ug1d5adKena7C3I2mnr0X7UhywTpSzKJ6An7z7zKS35nD0RO

点击中间区域
呼出菜单
上一章
目录
下一章
×