第四章单片机C语言程序设计第四章单片机C语言程序设计4.1C语言与MCS-51单片机4.1.1C语言的特点及程序结构一.C语言的特点1.语言简洁、紧凑,使用方便、灵活。2.运算符丰富。3.数据结构丰富。具有现代化语言的各种数据结构。4.可进行结构化程序设计。5.可以直接对计算机硬件进行操作。6.生成的目标代码质量高,程序执行效率高。7.可移植性好。第四章单片机C语言程序设计二.C语言的程序结构C语言程序采用函数结构,必须有函数main(),程序总是从main()函数开始执行,执行到main()函数结束。函数可以是C语言编译器提供的库函数,也可以是由用户定义的自定义函数。C语言程序结构一般如下:预处理命令include函数说明longfun1();floatfun2();intx,y;floatz;第四章单片机C语言程序设计功能函数主函数功能函数功能函数1fun1(){函数体…}主函数main(){主函数体…}功能函数2fun2(){函数体…}第四章单片机C语言程序设计4.1.3C51程序结构C51的语法规定、程序结构及程序设计方法都与标准的C语言程序设计相同,以下几个方面不一样:C51中的数据类型与标准C的数据类型也有一定的区别,在C51中还增加了几种针对MCS-51单片机特有的数据类型;C51变量的存储模式与标准C中变量的存储模式不一样,C51中变量的存储模式是与MCS-51单片机的存储器紧密相关;C51与标准C的输入输出处理不一样,C51中的输入输出是通过MCS-51串行口来完成的;C51与标准C在函数使用方面也有一定的区别,C51中有专门的中断函数。第四章单片机C语言程序设计4.2C51的数据类型C51的数据类型与标准C中的数据类型基本相同,但C51中还有专门针对于MCS-51单片机的特殊功能寄存器型和位类型。一.字符型char有signedchar和unsignedchar之分,默认为signedchar。它们的长度均为一个字节。对于signedchar,表示的数值范围是-128~+127;对于unsignedchar,取值范围为0~255。二.int整型分singedint和unsignedint。默认为signedint。它们的长度均为两个字节。对于signedint,数的范畴为-32768~+32767。对于unsignedint,数的范围为0~65535。第四章单片机C语言程序设计三.long长整型分singedlong和unsignedlong。默认为signedlong。它们的长度均为四个字节。对于signedlong,数的范畴为-2147483648~+2147483647。对于unsignedlong,数的范围为0~4294967295。四.float浮点型float型数据的长度为四个字节,格式符合IEEE-754标准的单精度浮点型数据。五.*指针型指针型变量中存放的指向另一个数据的地址。指针变量要占用1~3个字节内存单元。第四章单片机C语言程序设计六.特殊功能寄存器型C51扩充的数据类型,用于访问MCS-51单片机中的特殊功能寄存器,它分sfr和sfr16两种类型。sfr:字节型特殊功能寄存器,可以访问MCS-51内部的所有特殊功能寄存器;sfr16:字型特殊功能寄存器,可以访问MCS-51内部的所有字类型特殊功能寄存器。七.位类型C51扩充的数据类型,用于访问MCS-51单片机中的可位寻址的位单元。两种位类型:bit型和sbit型。bit型:位变量的地址由C51编译器编译自动分配。Sbit型:位变量的地址固定,在C51编译器编译不变化。第四章单片机C语言程序设计基本数据类型长度取值范围unsignedchar1字节0~255signedchar1字节-128~+127unsignedint2字节0~65535signedint2字节-32768~+32767unsignedlong4字节0~4294967295signedlong4字节-2147483648~+2147483647float4字节1.175494E-38~3.402823E+38bit1位0或1Sbit1位0或1sfr1字节0~255sfr162字节0~65535C51数据类型表第四章单片机C语言程序设计在C51语言程序中,有可能会出现在运算中数据类型不一致的情况。C51隐式转换的优先级顺序如下:bitcharintlongfloatsignedunsignedC51除了支持隐式类型转换外,还可以通过强制类型转换符“()”对数据类型进行人为的强制转换。第四章单片机C语言程序设计4.3C51的运算量4.3.1常量常量是指:在程序执行过程中其值不能改变的量。在C51中支持整型常量、浮点型常量、字符型常量和字符串型常量。一.整型常量C51中可以表示成以下几种形式:十进制整数。如234、-56、0等。十六进制整数。以0x开头表示,如0x12表示十六进制数12H。长整数。以字母L结尾,如123L在存储器中占四个字节。第四章单片机C语言程序设计二.浮点型常量有十进制表示形式和指数表示形式。十进制表示形式:定点表示形式,由数字和小数点组成。如0.123。指数表示形式为:[]数字[.数字]e[]数字如:3.456e-3、-3.123e2。三.字符型常量字符型常量是用单引号引起的字符,如‘a’、‘1’、‘F’等。四.字符串型常量字符串型常量由双引号“”括起的字符组成。如“D”、“1234”、“ABCD”。字符串常量与字符常量区别:一个字符常量只用一个字节存放,而一个字符串常量在内存中存放时系统会自动的在后面加一个“\0”作为字符串结束符。如字符常量‘A’和字符串常量“A”是不一样的。第四章单片机C语言程序设计4.3.2变量变量:程序运行过程中其值可以改变的量。由变量名和变量值两部分组成。定义的格式如下:数据类型说明符[存储器类型]变量名1[=初值],变量名2[=初值2]…;一.数据类型说明符在定义变量时,用于指明变量的数据类型,即指明变量在存储器中占用的字节数。typedefc51固有的数据类型说明符别名;第四章单片机C语言程序设计【例4-1】typedef的使用。typedefunsignedintWORD;typedefunsignedcharBYTE;BYTEa1=0x12;WORDa2=0x1234;二.变量名在C51中规定变量名可以由字母、数字和下划线三种字符组成,且第一个字母必须为字母或下划线。变量名有两种:普通变量名和指针变量名。区别:指针变量名前面要带“*”号。第四章单片机C语言程序设计三.存储器类型指明变量所处的单片机存储器区域情况。C51编译器能识别的存储器类型有以下几种。存储器类型描述data片内RAM低128B,访问速度快bdata片内RAM的可位寻址区(20H~2FH),允许字节和位混合访问idata间接寻址访问的片内RAM,允许访问全部片内RAMpdata用Ri间接访问的片外RAMxdata用DPTR间接访问的片外RAM,允许访问全部64k片外RAMcode程序存储器ROM64k空间第四章单片机C语言程序设计【例4-2】变量定义存储种类和存储器类型相关情况。chardatavarl;/*在片内RAM低128B定义字符型变量var1*/intidatavar2;/*在片内RAM256B定义用间接寻址方式访问的整型变量var2*/unsignedlongdatavar3;/*在片内RAM128B定义用无符号长整型变量var3*/floatxdatavar4;/*在片外RAM64KB空间定义用间接寻址方式访问的外部实型变量var4*/intcodevar5;/*在ROM空间定义整型变量var5*/unsigncharbdatavar6/*在片内RAM位寻址区20H~2FH定义可字节处理和位处理的无符号字符型变量var6*/第四章单片机C语言程序设计四.特殊功能寄存器变量定义格式如下:sfr(sfr16)特殊功能寄存器名=地址;【例4-3】特殊功能寄存器的定义。sfrPSW=0xd0;sfrSCON=0x98;sfrTMOD=0x89;sfrP1=0x90;sfr16DPTR=0x82;sfr16T1=0X8A;第四章单片机C语言程序设计五.位变量bit位类型符用于定义一般的可位处理位变量。格式:bit位变量名;sbit位类型符用于定义在可位寻址字节或特殊功能寄存器中的位,定义时须指明其位地址。格式:sbit位变量名=位地址;【例4-4】bit型变量的定义。bita1;sbitOV=0xd2;sbitCY=oxd7;unsignedcharbdataflag;sbitflag0=flag^0;sfrP1=0x90;sbitP1_0=P1^0;sbitP1_1=P1^1;sbitP1_2=P1^2;第四章单片机C语言程序设计注:在C51中,C51编译器把MCS-51单片机常用的特殊功能寄存器和特殊位进行了定义,放在一个“reg51.h”或“reg52.h”的头文件中。使用#includereg52.h把这个头文件包含到程序中,就可使用殊功能寄存器名和特殊位名称。4.3.3存储模式存储模式指明变量默认的存储器类型。(1)SMALL模式:小编译模式,函数参数和变量被默认在片内RAM中,存储器类型为data。(2)COMPACT模式:紧凑编译模式,在COMPACT模式下,函数参数和变量被默认在片外RAM的低256字节空间,存储器类型为pdata。(3)LARGE模式:大编译模式,函数参数和变量被默认在片外RAM的64K字节空间,存储器类型为xdata。第四章单片机C语言程序设计【例4-6】变量的存储模式。#pragmasmall/*变量的存储模式为SMALL*/chark1;intxdatam1;#pragmacompact/*变量的存储模式为compact*/chark2;intxdatam2;intfunc1(intx1,inty1)large/*函数的存储模式为LARGE*/{return(x1+y1);}intfunc2(intx2,inty2)/*函数的存储模式隐含为SMALL*/{return(x2-y2);}程序编译时,k1变量存储器类型为data,k2变量存储器类型为pdata,m1和m2存储器类型为xdata,;函数func1的形参x1和y1的存储器类型为xdata型,而函数func2由于没有指明存储模式,隐含为SMALL模式,形参x2和y2的存储器类型为data。第四章单片机C语言程序设计4.3.4绝对地址的访问一.使用C51运行库中预定义宏在absacc.h文件中定义了8个宏,来对51系列单片机的code、data、pdata和xdata空间进行绝对寻址。CBYTE:字节形式对code区寻址DBYTE:字节形式对data区寻址PBYTE:字节形式对pdata区寻址XBYTE:字节形式对xdata区寻址CWORD:字形式对code区寻址DWORD:字形式对data区寻址PWORD:字形式对pdata区寻址XWORD:字形式对xdata区寻址。使用形式如下:宏名[地址]第四章单片机C语言程序设计【例4-7】绝对地址对存储单元的访问#includeabsacc.h/*将绝对地址头文件包含在文件中*/#includereg52.h/*将寄存器头文件包含在文件中*/voidmain(void){unsingedcharvar1;unsignedintvar2;var1=XBYTE[0x0005];/*访问片外RAM的0005字节单元*/var2=XWORD[0x0002];/*访问片外RAM的0002字单元*/......while(1);}第四章单片机C语言程序设计二.通过指针访问采用指针的方法,可以实现在C51程序中对任意指定的存储器单元进行访问。【例4-8】通过指针实现绝对地址的访问。#defineucharunsignedchar#defineuintunsi