-
第四课
数据类型
先来简单说说
C
语言的标识符和关键字。
标识符是用来标识源程序
中某个对象的名字的,
这些对象可以是语
句、数据类型、函数、
变量、数组等等。
C
语言是大小字敏感的一种高级语言,如果我
们要定义一个定时器
1
,可以写做
p>
,如果程序中有
,那么这两个是完全不同定
义的标识符。标识符由字符串,
数字和下划线等组成,注意的是第一个字符必须是字母或
下划线,如
是错误的,编译时便会有错误
提示。有些编译系统专用的标识符是以下划线开头,所以一般不要以下划线开头命名标识符。标识符在命名
p>
时应当简单,含义清晰,这样有助于阅读理解程序。在
C51
编译器中,只支持标识符的前
32
位为有效标
识,
一般情况下也足够用了,除非你要写天书:
P
。
关键字则是编程语言保留的特殊标识符,它们具
有固定名称和含义,在程序编写中不允许标识符与关键资亦
同。
在
KEIL uV
ision2
中的关
键字除了有
ANSI C
标准的
32<
/p>
个关键字外还根据
51
单片机的特点扩展
了相关的关
键字。其实在
KEIL
u
Vision2
的文本编辑器中编写
C
程序,系统可以把保留字以不同颜色显示,缺省颜色为
天蓝色。
(标准和扩展关键字请看附录一中的附表
1-1
和附表
1-2
)
先看表
p>
4
-
1
,表中列出
了
KEIL
uVision2
C5
1
编译器所支持的数据类型。在标准
C
语言中基本的数据类型为
char,int,short,long,float
和
double
,而在
C51
编译器中
int
和
short
相同,
float
和
double
相同,这里就不列出说
明了。下面来看看它们的具体定义:
数据类型
unsigned
char
signed char
unsigned
int
signed int
unsigned long
signed long
float
*
bit
sfr
长
度
单字节
单字节
双字节
双字节
四字节
四字节
四字节
1
~
3
字节
位
单字节
值
域
0
~
255
-128
~
+127
0
~
65535
-32768
~
+32767
0
~
4294967295
-2147483648
~
+21474836
47
±
1.175494E-38
~
±
3.402823E+38
对象的地址
0
或
1
0
~
255
sfr16
sbit
双字节
位
0
~
65535
0
或
1
表
4
-
1
KEIL uV
ision2
C51
编译器所支持的数据类型
1
.
char
字符类型
< br>char
类型的长度是一个字节,通常用于定义处理字符数据的变量或常量。分无
符号字符类型
unsigned char
和
< br>有符号字符类型
signed
char
,默认值为
signed
char
类型。
unsigned char
< br>类型用字节中所有的位来表示数值,
所可以表达的数值范围是
0
~
255
。
signed
char
类型用字节中最高位字节表示数据
的符号,
表示正数,
< br>表示负数,负数用补码表示。所能表示的数值范围是
-128
~
+127
。
unsigned
char
常用于处理
ASCII
字符或
用
于处理小于或等于
255
的整型数。
*
正数的补码与原码相同,负二进制
数的补码等于它的绝对值按位取反后加
1
。
2
.
int
整型
int
整型长度为两个字节,
用于存放一个双字节数据。
分有符号
int
整型数
signed int
和无符号整型数
unsigned
int
,默认值为
signed
int
类型。
signed int
表
示的数值范围是
-32768
~
+32
767
,字节中最高位表示数据的符号,
表示正数,
表示负数。
unsign
ed int
表示的数值范围是
0
~<
/p>
65535
。
好了,先停一下吧,我们来写个小程序看看
unsigned
char
和
unsigned
int
用于延时的不同效果,说明它们的
长度
是不同的,呵,尽管它并没有实际的应用意义,这里我们学习它们的用法就行。依旧用我们上一课的最
小化系统做实验,不过要加多一个电阻和
LED
,
如图
4
-
1
。
实验中用
D1
的点亮表明正在用
uns
igned int
数值
延时,用
D2
点亮表明正在用
unsigned
char
数值延时。
图
4
-
1 <
/p>
第
4
课实验用电路
我们把这个项目称为
TwoLE
D,
实验程序如下:
#include
预处理命令
void
main(void) //
主函数名
{
unsigned int a; //
< br>定义变量
a
为
unsigned
int
类型
unsigned
char b; //
定义变量
b
为<
/p>
unsigned char
类型
do
{//do
while
组成循环
for
(a=0; a<65535; a++)
P1_0 =0; //65535
次设
P1.0
口为低电平,点亮
LED
P1_0 =1; //
设
P1.0
口为高电平,熄灭
LED
for (a=0; a<30000; a++);
//
空循环
for (b=0;
b<255; b++)
P1_1 =0; //255
次设
P1.1
口为低电平,点亮
LED
P1_1 =1; //
设
P1.1<
/p>
口为高电平,熄灭
LED
for (a=0; a<30000; a++);
//
空循环
}
while(1);
}
同样编译烧
写,上电运行您就可以看到结果了。很明显
D1
点亮的时间长于
D2
点亮的时间。程序中的循环延
时时
间并不是很好确定,并不太适合要求精确延时的场合,关于这方面我们以后也会做讨论。这里必须要讲
的是,当定义一个变量为特定的数据类型时,在程序使用该变量不应使它的值超过数据类型的值域。 如本例
中的变量
b
不能赋超出
0
~
255
的值,如<
/p>
for (b=0; b<255;
b++)
改为
for (b=0; b<256; b++),
编译是可以通过的,
但运行时就会有问题出现,就是说
b
的值永远都是小于
256
的,所以无法跳出循环执行下一句
P1_1
=
1
,从
而造成死循环。同理
a
的值不应超出
0
~
65535
。大家可以烧片看看实验的运行结果,同样软件仿真也是可以
p>
看到结果的。
3
.
long
长整型
long
长整型长度为四个字节,用于存放一个四字节数据。分有符号
long
长整型
signed
long
和无符号长整型
unsigned
long
,默认值为
signed
long
类型。
signed int
表示的数值范围是
-2147483648
~
< br>+2147483647
,字节中
最高位表示数据的符号
,
表示正数,
表示负数。
unsigned long
表示的数值范围是
p>
0
~
4294967295
。
4
.
float
浮点型
< br>float
浮点型在十进制中具有
7
位有效数字,是符合
IEEE
-
7
54
标准的单精度浮点型数据,占用四个字节。因
浮点数的结构
较复杂在以后的章节中再做详细的讨论。
5
.
*
指针型
指针型本身就是一个变量,在
这个变量中存放的指向另一个数据的地址。这个指针变量要占据一定的内存单
元,对不同
的处理器长度也不尽相同,在
C51
中它的长度一般为
1
~
3
个字节。指针变
量也具有类型,在以后
的课程中有专门一课做探讨,这里就不多说了。
< br>
6
.
bit
位标量
bit
位标量是
C51
编译器的一种
扩充数据类型,
利用它可定义一个位标量,
但不能定义位指针,
也不能定义位
数组。它的值是一个二进制位,不是
0
就是
1
,类似一些高级语
言中的
Boolean
类型中的
Tru
e
和
False
。
7
.
sfr
特殊功能寄存器
sfr
也是一种扩充数据类型,
点用一个内存单元,
值域为
0
~
2
55
。
利用它可以访问
51
单片机内部的所有特殊功
能寄存器。
如用
sfr P1 =0x90
这一句定
P1
为
P1
端口在片内的寄存器,
在后面的语句中我们用以用
P1 = 255
(
对
P1
端口的所有引脚置高电平)之类的语句
来操作特殊功能寄存器。
8
.
sfr16
16
位特殊功能寄存器
sfr16<
/p>
占用两个内存单元,值域为
0
~
65535
。
sfr16
和
sfr
一样用于操作特殊功能寄存器,所不同的是它用于操
作占两个字节的寄存器,好定时器
T0
和
T1
。
9
.
sbit
可录址位
< br>sbit
同位是
C51
中的一种
扩充数据类型,利用它可以访问芯片内部的
RAM
中的可寻址位
或特殊功能寄存器
中的可寻址位。如先前我们定义了
sfr P1 =0x90; //
因
P1
端口的寄存器是可位寻址的
,所以我们可以定义
sbit P1_1 =
P1
^
1; //P1_1
为
P1
中的
P1.1
引脚
//
同样我们可以用
P1.1
的地址去写
,
如
p>
sbit P1_1 = 0x91;
这样我们在以后的程序语句
中就可以用
P1_1
来对
P1.1
p>
引脚进行读写操作了。通常这些可以直接使用系统提
供的预处理文件
,里面已定义好各特殊功能寄存器的简单名字,直接引用可以省去一点时间,我自己是一直
用的。当然您也可以自己写自己的定义文件,用您认为好记的名字。
关于数据类型转换等相关操作在后面的课程或程序实例中将有所提及。
大家可以
用所讲到的数据类型改写一
下这课的实例程序,加深对各类型的认识。
< br>
第五课
常量
上一节我们学习了
KEIL
C51<
/p>
编译器所支持的数据类型。而这些数据类型又是怎么用在常量和变量的定义中
的呢?又有什么要注意的吗?下面就来看看吧。晕!你还区分不清楚什么是常量,什么是变量。常量是
在程
序运行过程中不能改变值的量,而变量是可以在程序运行过程中不断变化的量。变量
的定义可以使用所有
C51
编译器支持的数据类型,而常量的数
据类型只有整型、浮点型、字符型、字符串型和位标量。这一节我
们学习常量定义和用法
,而下一节则学习变量。
常量的数据类型说明是这样的
1
p>
.整型常量可以表示为十进制如
123,0
,-
89
等。十六进制则以
0x
开头如
0x34,-0x3B
等。长整型就在
数字后
面加字母
L
,如
104L
,
034L
,
0xF340
等。
2
.浮点型常量
可分为十进制和指数表示形式。十进制由数字和
小数点组成,如
0.888,3345.345,0.0
等,整
数或
小数部分为
0
,可以省略但必须有
小数点。指数表示形式为
[±
]
数字<
/p>
[.
数字
]e[±
]
数字,
[]
中的内容为可选项,其
中内容根据具体情况可有可无,但其余部分必须有
,
如
125e3,7e9,-3.0e-3
。
3
.字符型常量是单引号内的字符,如
p>
'a','d'
等,不可以显示的控制字符,可以在该字符前面加一
个反斜杠
组成专用转义字符。常用转义字符表请看表
5
-
1
。
4
.字符串型常量由双引号内的字符组成,如
等。当引号内的没有字符时,为空字符串。在使用特
< br>殊字符时同样要使用转义字符如双引号。
在
C
中字符串常量是做为字符类型数组来处理的,
在存储字符串时
系统会在字符串尾部加上
o
转义字符以作为该字符串
的结束符。字符串常量
和字符常量
'A
'
是不同的,前
者在存储时多占用一个字节的字间。
5
.位标量,它的值是一个二进制。
转义字符
o
n
r
t
b
f
'
含义
空字符
(NULL)
换行符
(LF)
回车符
(CR)
水平制表符
(HT)
退格符
(BS)
换页符
(FF)
单引号
双引号
反斜杠
00H/0
0AH/10
0DH/13
09H/9
08H/8
0CH/12
27H/39
22H/34
5CH/92
表
5
-
1
常用转义字符表
< br>常量可用在不必改变值的场合,如固定的数据表,字库等。常量的定义方式有几种
,
下面来加以说明。
ASCII
p>
码(
16/10
进制)
#difine False 0x0;
//
用预定义语句可以定义常量
#difine True 0x1; //
这里定义
False
为
0,True
为
1
//
在程序中用到
False
编译时自动用
0
替换,同理
True
替换为
1
unsigned int code a=100; //
这
一句用
code
把
a
< br>定义在程序存储器中并赋值
const
unsigned int c=100; //
用
const
定义
c
为无符号
int
常量并赋值
以上两句它们的
值都保存在程序存储器中,而程序存储器在运行中是不允许被修改的,所以如果在这两句后
面用了类似
a=110
,
a++
p>
这样的赋值语句,编译时将会出错。
<
/p>
说了一通还不如写个程序来实验一下吧。写什么程序呢?跑马灯!对,就写这个简单易懂的
吧,这个也好说
明典型的常量用法。先来看看电路图吧。它是在我们上一课的实验电路的
基础上增加
6
个
LED
组成的,也就
是用
P1
口的全
部引脚分别驱动一个
LED
,电路如图
5
-
1
所示。
新建一个
RunLED
的项目,主程序
如下:
<
br>口定义为 <
br>C51
#include
预处理文件里面定义了特殊寄存器的名称如
P1
P1
void main(void)
{
//
定义花样数据
const unsigned char design[32]={0xFF,0x
FE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE,0xFF,
0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x0
,
0xE7,0xDB,0xBD,0x7E,0xFF};
unsigned int a;
//
定义循环用的变量
unsigned char b; //
在
编程中因内存有限尽可能注意变量类型的使用
<
/p>
//
尽可能使用少字节的类型,在大型的程序中很受用
do{
for (b=0; b<32;
b++)
{
for(a=0; a<30000;
a++); //
延时一段时间
P1
=design[b]; //
读已定义的花样数据并写花样数据到
P1
口
}
}while(1);
}
程序中的
花样数据可以自以去定义
,
因这里我们的
LED
要
AT89C51
的
P1
引脚为低电平才会点亮,
所以我们要
向
P1
口的各引脚写数据
O
对应连接的
LED
才会被点亮,
P1
口的八个引脚刚好对应
P1
口特殊寄存器的八个二
进位,
如向
P1
口定数据
0xFE,
转成二进制就是
11111110,
最低位
D0
为
0
这里
P1.0
引脚输出低电平,
LED1
被点亮。
如此类推,大家不难算出自己想要做的效果了。大家编译烧写看看,效果就出
来,显示的速度您可以根据需
要调整延时
a
的值,不要超过变量类型的值域就很行了。哦,您还没有实验板?那如何可以知道程序运行的
结果呢?呵,不用急,这就来说说用
KEIL uV
i
sion2
的软件仿真来调试
IO
口输
出输入程序。
图
5
-
1
八路跑马灯电路
< br>编译运行上面的程序,然后按外部设备菜单
Peripherals
-
I/O
Ports
-<
/p>
Port1
就打开
Port1
的调试窗口了,如图
5
-
3
中的
2
。这时程序运行了,但我们并
不能在
Port1
调试窗口上看到有会什么效果,这时我们可以
用鼠标左
击图
5
-
3
中
1
旁边绿色的方条,点一下就
有一个小红方格在点一下又没有了,哪一句语句前有小方格程序运
行到那一句时就停止了
,就是设置调试断点,同样图
5
-
2<
/p>
中的
1
也是同样功能,分别是增加
/
移除断点、移除
所有断点、允许
/
禁止断点、禁止所有断点,菜单也有一样的功能,另外菜单中还有
Breakpoints
可打开断点
设置窗口
它的功能更强大,不过我们这里先不用它。我们
?quot;P1 = design[
b];
这一句设置一个断点这时程序
运行到这里就停住了,
p>
再留意一下
Port1
调试窗口,
再按图
5-2
中的
2<
/p>
的运行键,
程序又运行到设置断点的地方
停住了,这时
Port1
调试窗口的状态又不同了。也就是说<
/p>
Port1
调试窗口模拟了
P1
口的电平状态,打勾为高电
平,不打勾则为低电平,窗口中
P1
为
P1
寄存器的状态,
Pins
为引脚的状态,注意的是如果是读引脚值必须
把引脚对应的寄存器置
1
才能正确读取。图
p>
5
-
2
中
2
旁边的{}样的按钮分别为单步入,步越,步出和执行到
当前行。图中
3
为显示下一句将要执行的语句。图<
/p>
5
-
3
中的
p>
3
是
Watches
窗口可查看各变量的当前值,数组和
字串是显示其头一个地址,如本例中的
design
数组是保存在
code
存储区的首地址为
D:0x08,
可以在图中
4
Memory
存储器查看窗口中的
Address
地址中打入
D:0x08
p>
就可以查看到
design
各数据和存放地
址了。如果你
的
uV
ision2
p>
没有显示这些窗口,可以在
View
菜单中
打开在图
5
-
2
中
3
后面一栏的查看窗口快捷栏中打开。
图
5
-
2
调试用快捷菜单栏
第六课
变量
上课所提到变量就是一种在程序执行过程中其值能不断变化的量。
要在程序中使用变量必须先用标识符作为
变量名,并指出所用的数据类型和存储模式,
这样编译系统才能为变量分配相应的存储空间。定义一个变量
的格式如下:
[
存储种类
]
数据类型
[
存储器类型
]
变量名表
在定义格式中除了数据类型
和变量名表是必要的,其它都是可选项。存储种类有四种:自动(
auto
)
,
外部
(
extern
)
,
静态(
p>
static
)和寄存器(
registe
r
)
,缺省类型为自动
(auto)<
/p>
。这些存储种类的具体含义和用法,将
在第七课《变量的存储》中
进一步进行学习。
而这里的数据类型则是和我们在第四课中学
习到的名种数据类型的定义是一样的。
说明了一个变量的数据类
型后,还可选择说明该变量的存储器类型。存储器类型的说明就是指定该变量在
C51<
/p>
硬件系统中所使用的存
储区域,并在编译时准确的定位。表
6
-
1
中是
KEIL
uV
ision2
< br>所能认别的存储器类型。注意的是在
AT89C51
芯片
中
RAM
只有低
128
位,位于
80H
到
FFH
p>
的高
128
位则在
52
芯片中才有用,并和特殊寄存器地址重叠。特
殊寄存器(<
/p>
SFR
)的地址表请看附录二
AT89C51
特殊功能寄存器列表
存储器类型
data
bdata
idata
pdata
xdata
code
说
明
p>
直接访问内部数据存储器(
128
字节
p>
),
访问速度最快
可位寻址内部数据存储器(
16
字节)
,允许位与字节混合访问
间接访问内部数据存储器(
256
字节)
,允许访问全部内部地址
分页访问外部数据存储器(
256
字节)
,用
MOVX
@Ri
指令访问
外部数据存储器
p>
(64KB)
,用
MOVX
@DPTR
指令访问
程序存储器(<
/p>
64KB
)
,
用
MOVC @A+DPTR
指令访问
表
6
-
1
存储器类型
如果省略存储器类型,系
统则会按编译模式
SMALL,COMPACT
或
LARGE
所规定的默认存储器类型去指定
变量的存
储区域。无论什么存储模式都可以声明变量在任何的
8051
存
储区范围,然而把最常用的命令如循环
计数器和队列索引放在内部数据区可以显著的提高
系统性能。
还有要指出的就是变量的存储种类与存储器类
型是完
全无关的。
SMALL
存储模式把所
有函数变量和局部数据段放在
8051
系统的内部数据存储区这
使访问数据非常快,但
SMALL
存储模式的地址空间受限。在
写小型的应用程序时,变量和数据放在
data
内部数据存储器
中是很好
的因为访问速度快,但在较大的应用程序中
data<
/p>
区最好只存放小的变量、数据或常用的变量(如循环计数、
数据索
引)
,而大的数据则放置在别的存储区域。
< br>COMPACT
存储模式中所有的函数和程序变量和局部数据段定位在
8051
系统的外部数据存储区。
外部数据存
p>
储区可有最多
256
字节(一页)
,在本模式中外部数据存储区的短地址用
@R0/R1
< br>。
LARGE
存储模式所有函
数和过程的变量和局部数据段都定位在
8051
系统的外部数据
区外部数据区最多可有
64KB
,这要求用
DPTR
数据指针访问数据。
之
前提到简单提到
sfr,sfr16,sbit
定义变量的方法
,下面我们再来仔细看看。
sfr
和
sfr16
可以直接对
51
单片机的特殊寄存器进行定义,定义方法如下:
sfr
特殊功能寄存器名
=
特殊功能寄存器地址常数
;
sfr16
特殊功能寄存器名
=
特殊功能寄存器地址常数
;
我们可以
这样定义
AT89C51
的
P1
口
sfr P1 =0x90;
//
定义
P1
I/O
口,其地址
90H
sfr
p>
关键定后面是一个要定义的名字,可任意选取,但要符合标识符的命名规则,名字最好有一定
的含义如
P1
口可以用
P1
为名,这样程序会变的好读好多。等号后面必须是常数,不允许有带运算符的表达式,而且
该常数必须在特殊功能寄存器的地址范围之内(
80H
< br>-
FFH
)
,具体可查看附录中
的相关表。
sfr
是定义
8
位的
特殊功能寄存器而
sfr16
则是用来定义
16
位特殊功能寄存器,如
8052
的
T2
定时器,可
以定义为:
sfr16 T2 =0xCC; //
这里定义
8052
定时器
2
,地址为
T2L=CCH,T2H=CDH
用
sfr16
定义
16
p>
位特殊功能寄存器时,
等号后面是它的低位地址,
< br>高位地址一定要位于物理低位地址之上。
注
意的是不能用
于定时器
0
和
1
的定义。
sbit
可定义可位寻址
对象。如访问特殊功能寄存器中的某位。其实这样应用是经常要用的如要访问
P1
口中的
第
2
个引脚<
/p>
P1.1
。我们可以照以下的方法去定义
:
(1)sbit
位变量名=位地址
sbit
P1_1 = Ox91;
这样是把位的绝对地址赋给位变量。同
sfr
一样
sbit
的位地址必须
位于
80H-FFH
之间。
(2)Sbit
位变量名=特殊功能寄存器名
^
位位置
sft P1
=0x90;
sbit P1_1 =P1 ^ 1;
//
先定义一个特殊功能寄存器名再指定位变量名所在的位置
当可寻址位位于特殊功能寄存器中时可采用这种方法
(3)sbit
位变量名=字节地址
^
位位置
sbit P1_1
=0x90 ^ 1;
这种方法其实和
2
是一样的,只是把特殊功能寄存器的位址直接用常数表示。
在
C51
存储器类型中提供有一个
b
data
的存储器类型,这个是指可位寻址的数据存储器,位于单片机的可位
寻址区中,可以将要求可位录址的数据定义为
bdata,
如
:
unsigned char bdata
ib; //
在可位录址区定义
ucsigned
char
类型的变量
ib
int
bdata ab[2]; //
在可位寻址区定义数组
ab[
2]
,这些也称为可寻址位对象
sbit ib7=ib^7 //
用关键字
< br>sbit
定义位变量来独立访问可寻址位对象的其中一位
sbit ab12=ab[1]^12;
操作符
^
后面的位位置的最大值
取决于指定的基址类型,
char0-7,int0-15,long0-31
。
下面我们用上一课的电路来实践一下这一课
的知识。同样是做一下简单的跑马灯实验,项目名为
RunLED2
。
程序如下
:
sfr P1
=0x90; //
这里没有使用预定义文件,
sbit P1_0 =P1 ^ 0;
//
而是自己定义特殊寄存器
sbit P1_7 =0x90 ^ 7;
//
之前我们使用的预定义文件其实就是这个作用
sbit P1_1 =0x91; //
这里分别定义
P1
端口和
P10,P11,P17
引脚
void main(void)
{
unsigned int a;
unsigned char b;
do{
for (a=0;a<50000;a++)
P1_0
=0; //
点亮
P1_0
for
(a=0;a<50000;a++)
P1_7 =0;
//
点亮
P1_7
for
(b=0;b<255;b++)
{
for
(a=0;a<10000;a++)
P1 =b; //
用
b
的值来做跑马灯的花样
}
P1 =255; //
熄灭
p>
P1
上的
LED
for (b=0;b<255;b++)
{
for (a=0;a<10000;a++)
//P1_1
闪烁
P1_1 =0;
for (a=0;a<10000;a++)
P1_1
=1;
}
}while(1);
}
第七课
运算符和表达式(
1
)
上课到这一课相隔了好长一段时间,
这些日子里收到不少网友的来信支持和鼓励,
要求尽快完成余下的部分。
出门在外的人不得不先为吃饭而努力,似乎这也成为我的借口,以后每晚抽空打一些吧这样大家也就可以
不
用隔太久就能看到一些新东西。或许我的笔记并不是很正确,但我尽量的保证每课的实
验都会亲自做一次,
包括硬件的部分
,
已求不会误人子弟。
随着访问量不断的增加,
网站已启用了
的国际域名
,<
/p>
在这里我感谢各位一直支持磁动力工作室的
朋友,更要感激身在远
方一直默默支持我的女友。
明浩
2003-7-14
晚
呵,费话少说了。上两课说了常量和变量
,
先来补
充一个用以重新定义数据类型的的语句吧。这个语句就是
typedef
,
这是个很好用的语句,
但我自己却不常用它,
通常我定义变量的数据类型时都是使用标准的关键字,
这样别人可以很
方便的研读你的程序。如果你是个
DELPHI
编程爱好者或是
程序员,你对变量的定义也许习
惯了
DELPHI
的关键字,如
int
类型常会用关键字
Integer
来定义,在用
C51
时你还想用回这个的话,你可以
这样写:
typedef int integer;
integer
a,b;
这两句在编译时,
其实是
先把
integer
定义为
int
p>
,
在以后的语句中遇到
integer
p>
就用
int
置换
,
integer
就等于
int,
所以<
/p>
a,b
也就被定义为
int
。
typedef
不能直接用来定义变量,它只是对
已有的数据类型作一个名字上的置换,
并不是产生一个新的数据类型。下面两句就是一个
错误的例子:
typedef int integer;
integer = 100;
使
用
typedef
可以有方便程序的移植和简化较长的数据类型
定义。用
typedef
还可以定义结构类型,这一点在
后面详细解说结构类型时再一并说明。
typedef
的语法是
typedef
已有的数据类型
新的数据类型名
运算符就是完成某种特定运算的符号。运算符按其表达式中与
运算符的关系可分为单目运算符,双目运算符
和三目运算符。单目就是指需要有一个运算
对象,双目就要求有两个运算对象,三目则要三个运算对象。表
达式则是由运算及运算对
象所组成的具有特定含义的式子。
C
是一种表达式语言,表达式
后面加
;
号就
构
成了一个表达式语句。
赋值运算符
对于
这个符号大家不会陌生的,在
C
中
它的功能是给变量赋值,称之为赋值运算符。它的作用不用多说
大家也明白,
就是但数据赋给变量。
如,
x=10;
由此可见利用赋值运算符将一个变量与一个表达式连接起来的
式子为赋值表
达式,在表达式后面加
;
便构成了赋值语句。使用
的赋值语句格式如下:
p>
变量
=
表达式;
示例如下
a =0xFF; //<
/p>
将常数十六进制数
FF
赋于变量
a
b =c = 33;
//
同时赋值给变量
b,c
d
=e; //
将变量
e
的值赋于变量<
/p>
d
f =a+b; //
将变量
a+b
的值赋于变量
f
由上面的例子可以知道赋值语句的意义就是先计算出
右边的表达式的值,然后将得到的值赋给左边的变
量。而且右边的表达式可以是一个赋值表达式。
在一些朋友
的来信中会出现
与
这两个符号混淆的错误原码,问为何编译报错,往往就是错在
if
(a=x)
之类的语句中,错将
用为
。
符号
是用来进行相等关系运算。
算术,增减量运算符
对于
a+b,a/b
这样的表达式大家都很熟悉,用在
C
语言中,
+
,
/
,就是算术运算符。
C51
中的算
术运算符有如
下几个,其中只有取正值和取负值运算符是单目运算符,其它则都是双目运
算符:
+
加或取正值运算符
-
减或取负值运算符
*
乘运算符
/
除运算符
%
取余运算符
算术表达式的形式:
表达式
1
算术运算符
表达式
2
如:
a+b*(10-a), (x+9)/(y-a)
除法运算符和一般的算术运算规则有所不同,
如是两浮点数相除,
其结果为浮点数,
如
10.0/20.0
所得值为
0.5
,
而两个整数相除时,所得值就是整数,如
7/3
p>
,值为
2
。像别的语言一样
C
的运算符与有优先级和结合性,同
样可用用括号
p>
()
来改变优先级
。这些和我们小时候学的数学几乎是一样的,我也不必过多的说明了。
:(
还有这么多运算符呀!暂时停一停吧,我们先来做一个实
验吧。学习运算符和另外一些知识时,我们还是
给我们的实验板加个串行接口吧。借助电
脑转件直观的看单片机的输出结果,以后我还会用一些简单的实例
讲解单片机和
PC
串口通讯的简单应用和编程。如果你用的是成品实验板或仿真器,那
你就可以跳过这一段
了。
在制作电路
前我们先来看看要用的
MAX232
,这里我们不去具体讨论它
,只要知道它是
TTL
和
RS232<
/p>
电平
相互转换的芯片和基本的引脚接
线功
能就行了。通常
我会用两个小功率晶体
管加少量的电路去替换<
/p>
MAX232
,可以省一点,效果也不错(如有兴趣可以查看
p>
网站中的相关资料)
。下图就是
MAX232
的基本接线图。
图
7
-
1
MAX232
在上两课的电路的基础上按图
7
-
3
加上
< br>MAX232
就可以了。
这大热天的拿烙铁焊焊,
还真的是热气迫人来呀:
P
串口座用
DB9
的母头,这样就可以用买来的
PC
串口延长线进行和电脑相连接,也可以直接接到电脑
com
口上。
图
7
-
2
DB9
接头
图
7
-
3 <
/p>
加上了
MAX232
的实验电路
做好后我们就先用回第一课的
World
!
程序,用它来和你的电脑说声
Hello!
把程序烧
到芯片上,把串
口连接好。嘿嘿,这时要打开你的串口调试软件,没有就赶快到网上
p>
DOWN
一个了。你会用
Windows<
/p>
的超
级中端也行,不过我从不用它。我用
的
comdebug
,它是个不错的软
件,我喜欢它是因为
它功能好而且还有
线路状态
功能,这对我制作小玩意时很有用。串口号,波特率调
好,打开串口,单片机
上电,就可以在接收区看到不断出现的
<
/p>
。一定要先打开软件的串口,再把单片机上电,否则可
能因字符不
对齐而看到乱码哦。
图
7-4
调试结果
示例程序下载
具有红外遥控功能的寻迹小车控制设计
类型:系统开发
主要内容和要求:
1
.红外遥控装置能控制单片机,使之发出进、退、左转、右转控制(并给出动作指示)
< br>。
2
.使用红外对管设计寻迹
电路(即自动区别黑白道标记)
。
3
.根据寻迹信号设计单片机对电机的控制电路。
4
.单片机采用汇编及
C51
进行编制,程序的下载为
ISP
方式。
参考文献及资料:
MCS-51
单片机及接口技术
p>
单片机
C51
编程
需要人数:一人
对学生的要求:对单片机感兴趣并有一定的动手能力。
ORG
0000H
START:
MOV
P0,#0FFH;
开机初始化
MOV P2,#00H
MOV
P3,#0FFH
RECE:
MOV R5,#8
JB
P0.7,$$
MOV R7,#15
LCALL DELAY
JB
P0.7,RECE;
等待遥控信号出现
JNB P0.7,$$
GO:
MOV R7,#15
LCALL DELAY
JNB
P0.7,RE1
CLR C
RLC A
JB P0.7,$$
JNB P0.7,$$
LJMP NEXT
RE1:
SETB C
RLC A
JNB P0.7,$$
NEXT:
DJNZ R5,GO
LJMP RUN
DELAY
:
MOV R6,#10
DJNZ R6,$$
NOP
DJNZ R7,DELAY
RET
RUN:
CJNE A,#00H,PRO00
LJMP PRO0
PRO00:
CJNE A,#01H,PRO10
LJMP PRO1
PRO10:
CJNE A,#02H,PRO20
LJMP PRO2
PRO20:
CJNE A,#03H,PRO30
LJMP PRO3
PRO30:
CJNE A,#04H,PRO40
LJMP PRO4
PRO40:
CJNE A,#05H,PRO50
LJMP PRO5
PRO50:
CJNE A,#06H,PRO60
LJMP PRO6
PRO60:
CJNE A,#07H,PRO70
LJMP PRO7
PRO70:
LJMP STAR
T
PRO0:
SETB P2.0 RIGHT ENABLE
SETB P2.1 LEFT ENABLE
SETB P2.3 FRONT
SETB P2.4 FRONT
CALL DELAY1