第2章(3)C51程序设计语言_第1页
第2章(3)C51程序设计语言_第2页
第2章(3)C51程序设计语言_第3页
第2章(3)C51程序设计语言_第4页
第2章(3)C51程序设计语言_第5页
已阅读5页,还剩47页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

KEILC编译器所支持的数据类型数据类型长度值域unsignedchar单字节0~255signedchar单字节-128~+127unsignedint双字节0~65535signedint双字节-32768~+32767unsignedlong四字节0~4294967295signedlong四字节-2147483648~+2147483647float四字节±1.175494E-38~±3.402823E+38*1~3字节对象的地址bit位0或1sfr单字节0~255sfr16双字节0~65535sbit位0或12.3.1.2数据类型一.字符型char有signedchar和unsignedchar之分,默认为signedchar。它们的长度均为一个字节,用于存放一个单字节的数据。对于signedchar,它用于定义带符号字节数据,其字节的最高位为符号位,“0”表示正数,“1”表示负数,补码表示,所能表示的数值范围是-128~+127;对于unsignedchar,它用于定义无符号字节数据或字符,可以存放一个字节的无符号数,其取值范围为0~255。unsignedchar可以用来存放无符号数,也可以存放西文字符,一个西文字符占一个字节,在计算机内部用ASCII码存放。二.int整型分singedint和unsignedint。默认为signedint。它们的长度均为两个字节,用于存放一个双字节数据。对于signedint,用于存放两字节带符号数,补码表示,数的范畴为-32768~+32767。对于unsignedint,用于存放两字节无符号数,数的范围为0~65535。三.long长整型分singedlong和unsignedlong。默认为signedlong。它们的长度均为四个字节,用于存放一个四字节数据。对于signedlong,用于存放四字节带符号数,补码表示,数的范畴为-2147483648~+2147483647。对于unsignedlong,用于存放四字节无符号数,数的范围为0~4294967295。四.float浮点型float型数据的长度为四个字节,包含指数和尾数两部分,最高位为符号位,“1”表示负数,“0”表示正数,其次的8位为阶码,最后的23位为尾数的有效数位。五.*指针型指针型变量中存放的是指向另一个数据的地址。这个指针变量要占用一定的内存单元,一般为1~3个字节。六.位类型是C51中扩充的数据类型,用于访问51单片机中的可寻址的位单元。在C51中,支持两种位类型:bit型和sbit型。它们在内存中都只占一个二进制位,其值可以是“1”或“0”。其中用bit定义的位变量在C51编译器编译时,在不同的时候位地址是可以变化的,而用sbit定义的位变量必须与51单片机的一个可以位寻址的字节单元中的某一位联系在一起,在C51编译器编译时,其对应的位地址是不可变化的。bit位类型符用于定义一般的位变量。它的格式如下:bit位变量名;在格式中可以加上各种修饰,但注意存储器类型只能是bdata、data、idata。只能是片内RAM的可位寻址区,严格来说只能是bdata。七.特殊功能寄存器型这是C51扩充的数据类型,用于访问51单片机中的特殊功能寄存器数据,它分sfr和sfr16两种类型,其中sfr为字节型特殊功能寄存器类型,占一个内存单元,利用它可以访问51内部的所有特殊功能寄存器;sfr16为双字节型特殊功能寄存器类型,占用两个字节单元,利用它可以访问51内部的所有两个字节的特殊功能寄存器。在C51中对特殊功能寄存器的访问必须先用sfr或sfr16进行声明。2.3.1.4变量及其存储模式变量是在程序运行过程中其值可以改变的量。一个变量由两部分组成:变量名和变量值。在C51中,变量在使用前必须对变量进行定义,定义的格式如下:

[存储种类]数据类型[存储器类型]变量名表;一.数据类型说明符在定义变量时,必须通过数据类型说明符指明变量的数据类型,指明变量在存储器中占用的字节数。可以是基本数据类型说明符,也可以是组合数据类型说明符,还可以是用typedef定义的类型别名。

在C51中,为了增加程序的可读性,允许用户为系统固有的数据类型说明符用typedef起别名,格式如下:

typedefc51固有的数据类型说明符别名;【例3-2】typedef的使用。 typedefunsignedintWORD; typedefunsignedcharBYTE; BYTEa1=0x12; WORDa2=0x1234;三、存储器类型存储器类型是用于指明变量所处的单片机的存储器区域情况存储器类型与存储种类完全不同。C51编译器能识别的存储器类型有:存储器类型说明data直接访问内部数据存储器(128字节),访问速度最快bdata可位寻址内部数据存储器(16字节),允许位与字节混合访问idata间接访问内部数据存储器(256字节),对于51子系列,只允许访问低128B,对于52子系列,允许访问全部256B地址pdata分页访问外部数据存储器(256字节),相当于用MOVX@Ri指令访问xdata外部数据存储器(64KB),相当于用MOVX@DPTR指令访问code程序存储器(64KB),相当于用MOVC@A+DPTR指令访问例:数据类型存储器类型变量char data var1;bit bdata flags;unsignedchar xdata vextor;定义变量时如果省略存储器类型,系统则会按编译模式SMALL、COMPACT或LARGE所规定的默认存储器类型去指定变量的存储区域。2.3.1.5C51定义特殊功能寄存器对SFR的操作,只能采用直接寻址方式。为了能直接访问这些特殊功能寄存器,KeilC51扩充了两个关键字“sfr”、“sfr16”,可以直接对51单片机的特殊寄存器进行定义。一、使用关键字sfr、sfr16定义特殊功能寄存器

sfr特殊功能寄存器名=特殊功能寄存器地址常数;如:对于8051片内I/O口,定义方法如下:sfrP1=0x90;//定义P1口,地址90Hsfr后面是一个要定义的名字,要符合标识符的命名规则,名字最好有一定的含义等号后面必须是常数,不允许有带运算符的表达式,而且该常数必须在特殊功能寄存器的地址范围之内(80H-FFH)。Sfr16特殊功能寄存器名=特殊功能寄存器地址常数;如:数据指针DPTR,可以定义为:sfr16DPTR=0x82;//这里定义数据指针DPTR,地址为DPL=82H,DPH=83H用sfr16定义16位特殊功能寄存器时,等号后面是它的低位地址,高位地址一定要位于物理低位地址之上。二、用sbit定义特殊功能寄存器的特殊位1)sbit位变量名=位地址sbitP1_1=0x91;这样是把位的绝对地址赋给位变量。同sfr一样,sbit的位地址必须位于80H~FFH之间。2)Sbit位变量名=特殊功能寄存器名^位地址sfrP3=0xB0;sbitP3_1=P3^1;//先定义一个特殊功能寄存器名,再指定位变量名所在的位置。当可寻址位位于特殊功能寄存器中时可采用这种方法。3)sbit位变量名=字节地址^位地址 sbitP3_1=0xB0^1;

三、通过头文件访问SFR编译器给出的头文件已经给出了常用51单片机中的SFR及其可位寻址位的定义。比如KeilC将这些头文件按单片机的不同生产公司、不同型号分别存在KeilC的INC子目录下,在程序中只需直接引用这些头文件即可实现对SFR的访问和控制。【例3-3】头文件引用实例。#include<AT89X51.h>//单片机为atmel公司的AT89C51main(){TL0=0xb0;//访问定时器0,设置时间常数TH0=0x3c;TR0=1;//启动定时器0⋯⋯}C51包含的头文件reg51.h,reg52.h,Reg51.h定义51子系列单片机的特殊功能寄存器和部分位寄存器Reg52.h定义52子系列单片机的特殊功能寄存器和部分位寄存器在程序开始部分使用语句#include<reg51.h>即可直接使用特殊功能寄存器及其部分位单元,不需要再作定义。2.3.1.5指针一.指针的概念在C语言中,数据通常是以变量的形式进行存放和访问的。变量在使用时分清两个概念:变量名和变量的值。变量名是数据的标识符,相当于内存单元的地址变量的值是数据的内容,变量的值相当于内存单元的内容。对于变量有两种访问方式:直接访问方式和间接访问方式。直接访问方式。对于变量的访问,我们大多数时候是直接给出变量名。间接访问方式。例如要存取变量a中的值时,可以先将变量a的地址放在另一个变量b中,访问时先找到变量b,从变量b中取出变量a的地址,然后根据这个地址从内存单元中取出变量a的值。这就是间接访问。在这里,从变量b中取出的不是所访问的数据,而是访问的数据(变量a的值)的地址,这就是指针,变量b称为指针变量。

变量的指针和指向变量的指针变量。变量的指针就是变量的地址。对于变量a,如果它所对应的内存单元地址为2000H,它的指针就是2000H。指针变量是指一个专门用来存放另一个变量地址的变量,它的值是指针。上面变量b中存放的是变量a的地址,变量b中的值是变量a的指针,变量b就是一个指向变量a的指针变量。二.指针变量的定义指针变量的定义与一般变量的定义类似,定义的一般形式为:数据类型说明符[存储器类型1]*【存储器类型2

】指针变量名;其中:“数据类型说明符”说明了该指针变量所指向的变量的类型。“存储器类型”是可选项,如果带有此选项,指针被定义为基于存储器的指针。无此选项时,被定义为一般指针。下面是几个指针变量定义的例子:int*p1;/*定义一个指向整型变量的指针变量p1*/chardata*p3;/*定义一个指向字符变量的指针变量p3,该指针访问的数据在片内数据存储器中,该指针在内存中占一个字节*/floatxdata*p4;/*定义一个指向浮点型变量的指针变量p4,该指针访问的数据在片外数据存储器中,该指针在内存中占两个字节*/Float*xdatap4;/*定义一个指向浮点型变量的指针变量p4,该指针存放在片外数据存储器中,该指针在内存中占三个字节*/三.指针变量的引用指针变量是存放另一变量地址的特殊变量,指针变量只能存放地址。指针变量使用时注意两个运算符:&和*。&”是取地址运算符,“*”是指针运算符。通过“&”取地址运算符可以把一个变量的地址送给指针变量,使指针变量指向该变量;通过“*”指针运算符可以实现通过指针变量访问它所指向的变量的值。例如:intx,*px,*py;/*变量及指针变量定义*/px=&x;/*将变量x的地址赋给指针变量px,使px指向变量x*/*px=5;/*等价于x=5*/py=px;/*将指针变量px中的地址赋给指针变量py,使指针变量py也指向x*/2.3.2C51的运算符及表达式1赋值运算符赋值运算符“=”,在C51中,它的功能是将一个数据的值赋给一个变量,如x=10。一个赋值语句的格式如下:

变量=表达式;执行时先计算出右边表达式的值,然后赋给左边的变量。例如:x=8+9;/*将8+9的值赋绐变量x*/x=y=5;/*将常数5同时赋给变量x和y*注意:在赋值运算中,当“=”两侧的类型不一致时,要将数据转换成同一数据类型,转换的方式有两种。1.系统自动转换编译时,将右边表达式的值转换成左侧变量的类型,再赋给该变量。2.强制转换使用强制类型转换运算符转换:(类型名)(表达式),将表达式的数据类型转换为前面要求的类型名。【例3-8】类型转换应用。unsignedcharx,y;unsignedintz,a;x=(float)a;

y=(int)(x+y);z=x+(unsignedint)y;2算术运算符

+加或取正值运算符 -减或取负值运算符*乘运算符 /除运算符 %取余运算符加、减、乘运算相对比较简单,而对于除运算,如相除的两个数为浮点数,则运算的结果也为浮点数,如相除的两个数为整数,则运算的结果也为整数,即为整除。如25.0/20.0结果为1.25,而25/20结果为1。对于取余运算,则要求参加运算的两个数必须为整数,运算结果为它们的余数。例如:x=5%3,结果x的值为2。3关系运算符C51中有6种关系运算符: >大于 <小于 >=大于等于 <=小于等于 ==等于 !=不等于关系表达式通常用来作为判别条件构造分支或循环程序。关系表达式的一般形式如下:表达式1关系运算符表达式2关系运算的结果为逻辑量,成立为真(1),不成立为假(0)。其结果可以作为一个逻辑量参与逻辑运算。例如:5>3,结果为真(1),而10==100,结果为假(0)。

4逻辑运算符C51有3种逻辑运算符:

||逻辑或 &&逻辑与 !逻辑非逻辑运算符用于求条件式的逻辑值,用逻辑运算符将关系表达式或逻辑量连接起来的式子就是逻辑表达式。逻辑与,格式:条件式1&&条件式2当条件式1与条件式2都为真时结果为真(非0),否则为假(0)逻辑或,格式:条件式1||条件式2当条件式1与条件式2都为假时结果为假(0),否则为真(非0)逻辑非,格式:!条件式当条件式原来为真(非0),逻辑非后结果为假(0)。当条件式原来为假(0),逻辑非后结果为真(非0)。例如:若a=8,b=3,c=0,则!a为假,a&&b为真,b&&c为假。5位运算符位运算是按位对变量进行运算,但并不改变参与运算的变量的值。C51中位运算符只能对整数进行操作,不能对浮点数进行操作。C51中的位运算符有:&按位与|按位或^按位异或~按位取反<<左移>>右移【例】设a=0x45=01000101B,b=0x3b=00111011B,则a&b、a|b、a^b、~a、a<<2、b>>2分别为多少?a&b=00000001b=0x01。a|b=01111111B=0x7f。a^b=01111110B=0x7e。~a=10111010B=0xba。a<<2=00010100B=0x14。b>>2=00001110B=0x0e。6复合赋值运算符C51中支持的复合赋值运算符:+=加法赋值-=减法赋值*=乘法赋值/=除法赋值%=取模赋值&=逻辑与赋值|=逻辑或赋值^=逻辑异或赋值~=逻辑非赋值>>=右移位赋值<<=左移位赋值复合赋值运算的一般格式如下:变量复合运算赋值符表达式它的处理过程:先把变量与后面的表达式进行某种运算,然后将运算的结果赋给前面的变量。7逗号运算符在C51语言中,逗号“,”是一个特殊的运算符,可以用它将两个或两个以上的表达式连接起来,称为逗号表达式。逗号表达式的一般格式为:

表达式1,表达式2,……,表达式n程序执行时对逗号表达式的处理:按从左至右的顺序依次计算出各个表达式的值,而整个逗号表达式的值是最右边的表达式(表达式n)的值。例如:x=(a=3,6*3)结果x的值为18。8条件运算符条件运算符“?:”是C51语言中唯一的一个三目运算符,它要求有三个运算对象,用它可以将三个表达式连接在一起构成一个条件表达式。条件表达式的一般格式为:

逻辑表达式?表达式1:表达式2功能是先计算逻辑表达式的值,当逻辑表达式的值为真(非0值)时,将计算的表达式1的值作为整个条件表达式的值;当逻辑表达式的值为假(0值)时,将计算的表达式2的值作为整个条件表达式的值。例如:条件表达式max=(a>b)?a:b的执行结果是将a和b中较大的数赋值给变量max。9指针与地址运算符

*指针运算符 &取地址运算符指针运算符“*”放在指针变量前面,通过它实现访问以指针变量的内容为地址所指向的存储单元。例如:指针变量p中的地址为2000H,则*p所访问的是地址为2000H的存储单元,x=*p,实现把地址为2000H的存储单元的内容送给变量x。取地址运算符“&”放在变量的前面,通过它取得变量的地址,变量的地址通常送给指针变量。例如:设变量x的内容为12H,地址为2000H,则&x的值为2000H,如有一指针变量p,则通常用p=&x,实现将x变量的地址送给指针变量p,指针变量p指向变量x,以后可以通过*p访问变量x。2.3.3.2选择控制语句一、if语句if语句是C51中的一个基本条件选择语句,它通常有三种格式:(1)if(表达式){语句;}(2)if(表达式){语句1;}else{语句2;}(3)if(表达式1){语句1;}elseif(表达式2){语句2;}elseif(表达式3){语句3;}……elseif(表达式n-1){语句n-1;}else{语句n}二、switch/case语句if语句通过嵌套可以实现多分支结构,但结构复杂。switch是C51中提供的专门处理多分支结构的多分支选择语句。它的格式如下:switch(表达式){case常量表达式1:{语句1;}break;case常量表达式2:{语句2;}break;……case常量表达式n:{语句n;}break;default:{语句n+1;}}【例2-12】STC89C51单片机的P1.0和P1.1引脚接有两只按键,其4种逻辑组合分别点亮由P2.0~P2.3控制的4只LED(高电平点亮),试编程实现此功能。解:#include<at89x51.h>voidmain(){ dataunsignedchara; do { a=P1; a=a&0x03;//,读低2位 P2=P2&0xf0; switch(a) { case0:P2=P2|0x01;break; case1:P2=P2|0x02;break; case2:P2=P2|0x04;break; case3:P2=P2|0x08; } }while(1);}2.3.3.3循环语句一、基于if和goto构成的循环采用if和goto可以构成“当型”循环程序,其格式如下:loop:if(表达式){语句;gotoloop;}采用if和goto也可以构成“直到型”循环程序,其格式如下:loop:{语句;if(表达式)gotoloop;}goto语句为无条件转向语句,它的一般形式是:goto语句标号;二、while语句while语句在C51中用于实现当型循环结构,它的格式如下:while(表达式){语句;}/*循环体*/当表达式为非0(真)时,就重复执行循环体内的语句;当表达式为0(假),则中止while循环,程序将执行循环结构之外的下一条语句。三、基于do-while语句构成的循环do-while语句只能用来实现“直到型”循环,其一般格式是:do{语句;//可以是复合语句}while(表达式);do-while语句的特点是先执行内嵌的语句;再计算表达式,如果表达式的值为非0,则继续执行内嵌的语句,直到表达式的值为0时结束循环。四、基于for语句构成的循环for语句的一般形式为:for(表达式1;表达式2;表达式3){语句;}它的执行过程是:首先求解初始化表达式1;其次求解表达式2,判断是否满足循环条件,若其值非0,则执行内嵌语句;否则退出循环;最后求解尺度增量表达式3,并回到第2步。在for语句中,可以没有表达式1、表达式2或表达式3,若三个表达式都没有,则相当于一个死循环。如果其后紧跟一个“;”,则为空循环,常用于延时;1.break语句使用break语句可以从循环体中跳出循环,提前结束循环而接着执行循环结构下面的语句。它不能用在除了循环语句和switch语句之外的任何其它语句中【例】下面一段程序用于计算圆的面积,当计算到面积大于100时,由break语句跳出循环。for(r=1;r<=10;r++){area=pi*r*r;if(area>100)break;}五、break和continue语句continue语句用在循环结构中,用于结束本次循环,跳过循环体中continue下面尚未执行的语句,直接进行下一次是否执行循环的判定。【例】输出100~200间不能被3整除的数。for(i=100;i<=200;i++){if(i%3==0)continue;printf(“%d”;i);}

2.continue语句return语句一般放在函数的最后位置,用于终止函数的执行,并控制程序返回调用该函数时所处的位置。返回时还可以通过return语句带回返回值。return语句格式有两种:(1)return;(2)return(表达式);

六、return语句2.3.4函数2.3.4.1函数的分类与定义一、函数的分类C语言函数分为主函数main()和普通函数两种,而对于普通函数,又可以分为标准库函数和用户自定义函数。1)标准库函数标准库函数是由C编译系统提供的,在C编译系统中将一些独立的功能模块编写成公用函数,并将它们集中存放在系统的函数库中,供程序设计时使用,称之为标准库函数。①字符串操作函数位于“string.h”中。包括拷贝、比较、移动等函数如memcpy、memcmp、memmove、memset,这些函数对缓冲区进行处理很方便。②流函数输入输出,位于“stdio.h”中。流函数缺省为8051串口。2)用户自定义函数用户自定义函数是用户根据自己的需要而编写的函数。从函数定义的形式上可以将其划分无参数函数、有参数函数和空函数。二、函数的定义函数定义的完整形式如下:返回数据类型函数名(形式参数列表)[reentrant][interruptn][usingm]

{局部变量定义;函数体;}1)函数返回值与数据类型如果返回数据,进行说明;如果不返回,一般用void说明,也可以不说明。函数返回值通过returnx返回,返回值是通过函数名带回的,一个函数只能有一个返回值。2)reentrant修饰符这个修饰符用于把函数定义为可重入函数。所谓可重入函数就是允许被递归调用的函数。函数的递归调用是指当一个函数正被调用尚未返回时,又直接或间接调用函数本身。3)interruptm修饰符在C51程序设计中,当函数定义时用了interruptm修饰符,系统编译时把对应函数转化为中断函数,按MCS-51系统中断的处理方式自动把它安排在程序存储器中的相应位置。在该修饰符中,m的取值为0~31,对应的中断情况如下:0——外部中断01——定时/计数器T02——外部中断13——定时/计数器T14——串行口中断5——定时/计数器T2其它值预留。4)usingn修饰符修饰符usingn用于指定本函数内部使用的工作寄存器组,其中n的取值为0~3,表示寄存器组号。对于usingn修饰符的使用,注意以下几点:(1)加入usingn后,C51在编译时自动的在函数的开始处和结束处加入以下指令。{PUSHPSW;标志寄存器入栈MOVPSW,#与寄存器组号相关的常量……POPPSW;标志寄存器出栈}(2)usingn修饰符不能用于有返回值的函数,因为C51函数的返回值是放在寄存器中的。如寄存器组改变了,返回值就会出错。3.5绝对地址的访问一.使用C51运行库中预定义宏C51编译器提供了一组宏定义来对51系列单片机的code、data、pdata和xdata空间进行绝对寻址。这些函数原型放在absacc.h文件中。使用时须用预处理命令把该头文件包含到文件中,形式为:#include<absacc.h>CBYTE以字节形式对code区寻址,DBYTE以字节形式对data区寻址,PBYTE以字节形式对pdata区寻址,XBYTE以字节形式对xdata区寻址,CWORD以字形式对code区寻址,DWORD以字形式对data区寻址,PWORD以字形式对pdata区寻址,XWORD以字形式对xdata区寻址。

宏名[地址]地址为存储单元的绝对地址,一般用十六进制形式表示。【例】绝对地址对存储单元的访问#include<absacc.h>/*将绝对地址头文件包含在文件中*/#include<reg52.h>/*将寄

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论