C51语言
本文主要涉及C51语言的一些基本知识,比如C51语言的数据类型以及存储类型以及一些基本运算。
文章目录
- C51语言
- 一、 C51与标准C的比较
- 二、 C51语言中的数据类型与存储类型
- 2.1、C51的扩展数据类型
- 2.2、数据存储类型
- 三、 C51的基本运算
- 3.1 算术运算符
- 3.2 逻辑运算符
- 3.3 关系运算符
- 3.4 位运算
- 3.5 指针和取地址运算符
一、 C51与标准C的比较
C51的基本语法与标准C相同,C51在标准C的基础上进行了适合于51系列单片机硬件的扩展。
深入理解Keil C51对标准C的扩展部分以及不同之处,是掌握C51语言的关键之一。
C51与标准C的主要区别
如下:
(1)库函数的不同。
(2)数据类型有一定的区别。
(3)C51的变量存储模式与标准C中的变量存储模式数据不一样。
(4)数据存储类型的不同。
(5)标准C语言没有处理单片机中断的定义。
(6)C51语言与标准C语言的输入/输出处理不一样。
(7)头文件的不同。
(8)程序结构的差异。
但是从数据运算操作、程序控制语句以及函数的使用上来说,Keil C51与标准C几乎没有什么明显的差别。
二、 C51语言中的数据类型与存储类型
Keil C51支持的基本数据类型如表3-1所示。针对AT89S51单片机的硬件特点,C51在标准C的基础上,扩展了4种数据类型(表3-1中最后4行)。
注意:扩展的4种数据类型,不能使用指针对它们存取。
2.1、C51的扩展数据类型
对扩展的4种数据类型说明:
(1)位变量bit
bit的值可以是1(true)
, 也可以是0(false)
(2)特殊功能寄存器sfr
特殊功能寄存器分布在片内数据存储区
的地址单元80H~FFH
之间,“sfr” 数据类型占用一个
内存单元。利用它可以访问单片机内部的所有特殊功能寄存器
。
例如:sfr P1=0x90
3)特殊功能寄存器sfr16
“sfr16”数据类型占两个内存单元
。它用于操作占两个字节的特殊功能寄存器。
例如: “sfr16 DPTR=0x82”语句定义了片内16位数据指针寄存器DPTR,其低8位字节地址为82H,高8位字节地址为83H。
(4)特殊功能位 sbit
sbit—片内特殊功能寄存器的可寻址位
。
例如:
sfr PSW=0xd0; /定义PSW寄存器地址为0xd0/
sbit PSW^2 = 0xd2; /定义OV位为PSW.2/
符号“”`前`是特殊功能寄存器的`名字`,“”的后
面数字是特殊功能寄存器可寻址位在寄存器中的位置
,取值必须是0~7
。
注意,不要把bit与sbit混淆。
bit
是定义普通的位变量
,值只能是二进制的0或1
。而sbit
定义的是特殊功能寄存器的可寻址位
,它的值是可进行位寻址的特殊功能寄存器的某位的绝对地址
。
2.2、数据存储类型
51单片机有片内、外数据存储区
,还有程序存储区
。51单片机片内的数据存储区是可读写的,51单片机的衍生系列最多可有256个字节的内部数据存储区,其中低128字节可直接寻址
,高128字节(80H~FFH)只能间接寻址
,从20H开始的16字节可位寻址。
程序存储区只能读不能写,可能在51单片机内部或者外部,或者外部和内部都有,由51单片机的硬件决定。
内部数据存储区可分为3个不同的数据存储类型:data、idata和bdata。
访问片外数据存储区比访问片内数据存储区慢
,C51提供两种
不同数据存储类型xdata
和pdata
来访问片外数据存储区
。
下面对表3-2中的各种存储区作以说明。
(1)DATA区。
寻址是最快的,应该把经常使用的变量
放在DATA区,但是DATA区的存储空间是有限的,DATA区除了包含程序变量
外,还包含了堆栈
和寄存器组
。可直接寻址
。
声明举例如下:
- unsigned char data system_status=0;
- unsigned int data unit_id[8];
- char data inp_string[20];
另外,当内部堆栈溢出
的时候,程序会莫名其妙地复位
。这是因为51单片机没有报错的机制,堆栈的溢出只能以这种方式表示,因此要留有较大的堆栈空间来防止堆栈溢出。
(2)BDATA区。
是DATA中的位寻址区,在这个区中声明变量就可进行位寻址
。BDATA区声明中的存储类型标识符为bdata
,指的是内部RAM
可位寻址的16字节存储区(字节地址为20H~2FH)中的128个位
。
下面是在BDATA区中声明的位变量和使用位变量的例子:
- unsigned char
bdata
status_byte; - unsigned int bdata status_word;
- sbit stat_flag=
status_byte^4
; - if(status_word^15)
{ …… }
stat_flag=1;
C51编译器不允许在BDATA区中声明float和double型变量。
(3)IDATA区。
IDATA区使用寄存器作为指针
来进行间接寻址,常用来存放使用比较频繁的变量
。与外部存储器寻址相比,它的指令执行周期和代码长度相对较短
。指的是片内RAM的256字节的存储区
,只能间接寻址
,速度比直接寻址慢。
声明举例如下:
- unsigned char
idata
system_status=0; - unsigned int idata unit_id[8];
- char idata inp_string[16];
- float idata out_value;
(4)PDATA区和XDATA区。
PDATA区和XDATA区位于片外存储区
,PDATA区和XDATA区声明中的存储类型标识符分别为pdata和xdata。
PDATA区只有256
字节,仅指定256字节的外部数据存储区。但XDATA区最多可达64KB,对应的xdata存储类型标识符可以指定外部数据区64KB内的任何地址。
对PDATA区的寻址要比对XDATA区寻址快,因为对PDATA区寻址,只需要装入8位地址,而对XDATA区寻址要装入16位地址,所以要尽量把外部数据存储在PDATA区中。
对PDATA区和XDATA区的声明举例如下:
- unsigned char
xdata
system_status=0; - unsigned int pdata unit_id[8];
- char xdata inp_string[16];
- float pdata out_value;
(5)程序存储区CODE。
程序存储区CODE声明的标识符为code,储存的数据是不可改变的。在C51编译器中可以用存储区类型标识符code来访问程序存储区。
声明举例如下:
unsigned char code
a[ ] ={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
三、 C51的基本运算
C51语言的基本运算与标准C类似,主要包括算术运算、关系运算、逻辑运算、位运算和赋值运算及其表达式等。
3.1 算术运算符
算术运算的算术运算符及其说明如表3-4所示。
表3-4中的自增和自减运算符
是使变量自动加1或减1,自增和自减运算符放在变量前和变量之后是不同的
。
例如:
++i,–i:在使用i之前
,先使i值加
(减)1。
i++,i–:在使用i之后
,再
使i值加(减)1。
例如:若i=4,则执行x=++i时,先使i加1,再引用结果,即x=5,运算结果为i=5,x=5。
再如:若i=4,则执行x=i++时,先引用i值,即x=4,再使i加1,运算结果为i=5,x=4。
3.2 逻辑运算符
逻辑运算符及其说明如表3-5所示。
3.3 关系运算符
关系运算符就是判断两个数之间的关系。关系运算符及其说明如表3-6所示。
3.4 位运算
位运算符及其说明如表3-7所示
3.5 指针和取地址运算符
取内容和取地址的一般形式分别为:
变量=*指针变量
指针变量=&目标变量
取内容运算是将指针变量所指向的目标变量的值
赋给左边的变量;取地址运算是将目标变量的地址
赋给左边的变量。
注意,指针变量
中只能存放地址
(也就是指针型数据),一般情况下不要将非指针类型的数据赋值给一个指针变量。