C51基础C51基础运算符和表达式2分支程序设计3循环程序设计4C及C51语言概述1函数5数组及指针的使用6C51的编程规范与技巧7C51基础1C及C51语言概述1.1C及C51语言的特点语言简洁,使用方便灵活。可移植性好。表达能力强。表达方式灵活。可进行结构化程序设计。可以直接操作计算机硬件。生成的目标代码质量高。C51基础1.2C51的数据类型关键字:关键字则是编程语言保留的特殊标识符,它们具有固定名称和含义,在程序编写中不允许标识符与关键字相同。在C51中的关键字除了有ANSIC标准的32个关键字外还根据51单片机的特点扩展了相关的关键字,见表中的C51编译器的扩展关键字。关键字用途说明bit位标量声明声明一个位标量或位类型的函数sbit位标量声明声明一个可位寻址变量sfr特殊功能寄存器声明声明一个特殊功能寄存器sfr16特殊功能寄存器声明声明一个16位的特殊功能寄存器data存储器类型说明直接寻址的内部数据存储器bdata存储器类型说明可位寻址的内部数据存储器idata存储器类型说明间接寻址的内部数据存储器pdata存储器类型说明分页寻址的外部数据存储器xdata存储器类型说明外部数据存储器code存储器类型说明程序存储器interrupt中断函数说明定义一个中断函数reentrant再入函数说明定义一个再入函数using寄存器组选择选择单片机的工作寄存器组_at_绝对地址说明为非位变量指定存储空间绝对地址small存储模式选择参数及局部变量放入可直接寻址的内部RAMcompact存储模式选择参数及局部变量放入分页外部数据存储区large存储模式选择参数及局部变量放入分页外部数据存储区关键字:C51基础数据类型的具体定义:数据类型说明长度值域unsignedchar无符号字符型单字节0~255signedchar带符号字符型单字节-128~+127unsignedint无符号整型双字节0~65535signedint带符号整型双字节-32768~+32767unsignedlong无符号长整型四字节0~4294967295signedlong带符号长整型四字节-2147483648~+2147483647float单精度型四字节±1.175494E-38~±3.402823E+38*指针1~3字节对象的地址bit位变量位0或1sfr8位特殊功能寄存器单字节0~255sfr1616位特殊功能寄存器双字节0~65535sbit可位寻址定义位0或1C51基础下面详细介绍一下C51编译器中特殊的数据类型:1.bit位标量bit位标量是C51编译器的一种扩充数据类型。利用它可定义一个位标量,但不能定义位指针,也不能定义位数组。它的值是一个二进制数:0或1。C51基础2.sfr特殊功能寄存器sfr一种扩充数据类型。sfr是定义8位的特殊功能寄存器,占用一个内存单元地址,值域为0~255(80H-FFH),sfr并非标准C语言的关键字,而是Keil为能直接访问51单片机内部的所有特殊功能寄存器。其用法:sfr特殊功能寄存器名=特殊功能寄存器地址常数;如sfrP1=0x90;/*定义P1I/O口,其地址90H*/。如用P1=255/*把FFH送入P1中(对P1端口的所有引脚置高电平)*/。C51基础3.sfr16为16位特殊功能寄存器sfr16则是用来定义16位特殊功能寄存器,操作占两个字节的寄存器。其用法:sfr16特殊功能寄存器名=特殊功能寄存器地址常数;如8052的T2定时器,可以定义为:sfr16T2=0xCC;/*这里定义8052定时器2,地址为T2L=CCH,T2H=CDH*/用sfr16定义16位特殊功能寄存器时,等号后面是它的低位地址,高位地址一定要位于物理低位地址之上。注意的是不能用于定时器0和1的定义。C51基础4.sbit可寻址位sbit是一种扩充数据类型,sbit可定义可位寻址对象。如访问特殊功能寄存器中的某位。sbit的用法有三种:(1)sbit位变量名=位地址例如:sbitP1_1=0x91;(2)sbit位变量名=特殊功能寄存器名^位位置例如:sftP1=0x90;sbitP1_1=P1^1;/*P1_1为P1中的P1.1引脚*/(3)sbit位变量名=字节地址^位位置(位序号)例如:sbitP1_1=0x90^1;C51基础1.3C51对内部资源的定义MCS-51内部资源定义函数是MCU中寄存器的地址映射。MCS-51单片机提供128字节的SFR寻址区,地址为80H~FFH,51单片机中,除了程序计数器PC和4组通用寄存器组之外,其他所有的寄存器均为SFR,并位于片内特殊寄存器区。这个区域可位寻址、字节寻址或字寻址,用来控制定时/计数器、I/O口、串行口等部件。特殊功能寄存器在C51语言中的声明,由几个关键字来完成。C51基础MCS-51单片机所有标准的寄存器的使用都是已经由C51头文件定义完成,编程人员可以直接使用符号的定义。在使用C51已定义的寄存器符号时,要用预编译命令#include将有关“头文件”包括到源文件中。使用MCS-51内部资源定义时要用到“reg51.h”文件,因此源文件开头应有以下预编译命令:#includereg51.h或#include”reg51.h”。C51基础例1:利用MCS-51单片机的P1引脚P1.0引接一只LED,送“0”点亮,送“1”灭。则要求点亮,程序如下:P1.480518051GNDLED0R07407LED7R77407LED1P1.0P1.1P1.2P1.3P1.4P1.5P1.6P1.7VCCC51基础#include“reg51.h”sbitP1_0=P1^0;voidmain(){P1_1=0;}例1:利用MCS-51单片机的P1引脚P1.0引接一只LED,送“0”点亮,送“1”灭。则要求点亮,程序如下:C51基础#include代表的是加载头文件,头文件是C编译器中带的已经定义的函数的集合或自定义的一个函数的集合。程序中加载一个reg51.h的文件,那么打开reg51.h里边的内容是什么呢?如编码器在C盘下C51文件夹内,则REG51.h文件的路径是C:\C51\INC\reg51.h。例如:P1定义为sfrP1=0x90;累加器A定义为sfrACC=0xE0;定时模式TMOD定义为sfrTMOD=0x89;C51基础main()函数也称为主函数C语言都是从main()函数开始执行的。前面加了一个void是说明该函数是没有返回值的。如果点量8个灯,可P1=0x00对引脚送0,则点亮单色灯,0x00对应二进制数值00000000,所以该条语句是同时点亮了8只单色灯。整个程序用{}括起来,形成了一个完整的C51程序。上例中,符号P1(代表P1锁存器)已经在头文件“reg51.h”中有定义。P1_0表示P1.0引脚,它没有被事先定义好,所以需要使用sbit进行定义。C51基础1.4常量与变量1、在程序运行过程中其值不能被改变的量称为常量。常量分为:数值型常量和字符型常量。例2:符号常量的使用,在P1口接有8个LED,执行下面的程序:#defineLIGHT00xfe#include“reg51.h”voidmain(){P1=LIGHT0;}C51基础程序中用#defineLIGHT00xfe来定义符号LIGHT0等于0xfe,以后程序中所有出现LIGHT0的地方均会用0xfe来替代。因此,这个程序执行结果就是P1=0xfe,只有接在P1.0的LED灯亮引脚上的LED点亮。C51基础2、在程序执行过程中其值可以改变的量称为变量。要在程序中使用变量必须先用标识符作为变量名,并指出所用的数据类型和存储模式。如某仪表有4位LED数码管,编程时将3CH~3FH作为显示缓冲区,当要显示一个字串“1234”时,汇编程序如下:MOV3CH,#1MOV3DH,#2MOV3EH,#3MOV3FH,#4经过显示程序处理后,在数码管上显示1234。这里的3CH~3FH就是一个存储单元地址,用变量表示。C51基础定义一个变量的格式如下:[存储种类]数据类型[存储器类型]变量名表。在定义格式中除了数据类型和变量名表是必要的,其它都是可选项。变量共分四种类型:自动(auto)外部(extern)静态(static)寄存器(register)缺省类型为自动(auto)。C51基础存储类型:说明了一个变量的数据类型后,还可选择说明该变量的存储器类型。既指定该变量在C51硬件系统中所使用的存储区域,并在编译时准确的定位。表3中是C51编译器所能认别的存储器类型。存储器类型说明地址data直接访问内部数据存储器(128字节),访问速度最快00H-7FHbdata可位寻址内部数据存储器(16字节),允许位与字节混合访问20H-2FHidata间接访问内部数据存储器(256字节),允许访问全部内部地址00H-FFHpdata分页访问外部数据存储器(256字节),用MOVX@Ri指令访问00H-FFHxdata外部数据存储器(64KB),用MOVX@DPTR指令访问0000H-FFFFHcode程序存储器(64KB),用MOVC@A+DPTR指令访问0000H-FFFFH表3存储器类型数据默认的存储空间为data型,也就是在片内RAM中C51基础在C51存储器类型中提供有一个bdata的存储器类型,这个是指可位寻址的数据存储器,位于单片机的可位寻址区中20H~2FH,可以将要求可位寻址的数据定义为bdata。如:unsignedcharbdataib;/*在可位寻址区定义ucsignedchar类型的变量ib*/intbdataab[2];/*在可位寻址区定义数组ab[2],这些也称为可寻址位对象*/C51基础在C51存储器类型中提供有一个bdata的存储器类型,这个是指可位寻址的数据存储器,位于单片机的可位寻址区中20H~2FH,可以将要求可位寻址的数据定义为bdata。如:sbitib7=ib^7;/*用关键字sbit定义位变量来独立访问可寻址位对象的其中一位*/sbitab12=ab[1]^12;/*操作符“^”后面的位位置的最大值取决于指定的基址类型,char(0-7),int(0-15),long(0-31)*/C51基础例3:将变量a的第3位、第5位、第7位清零,其余位不变。charbdataa;sbitD3=a^3;sbitD5=a^5;sbitD7=a^7;voidmain(){D7=0;D5=0;D3=0;}C51基础1.5C51绝对地址访问1.绝对宏:在程序中,用“#includeabsacc.h”即可使用其中定义的宏来访问绝对地址,包括:CBYTE、XBYTE、PWORD、DBYTE、CWORD、XWORD、PBYTE、DWORD具体使用可参看附录中“absacc.h”内容便知。例如:val1=CBYTE[0x0040];/*指向程序存贮器的0040h字节地址,即变量Val1的地址用的是程存的0040h地址,也叫绝对地址。*/C51基础1.5C51绝对地址访问1.绝对宏:在程序中,用“#includeabsacc.h”即可使用其中定义的宏来访问绝对地址,包括:CBYTE、XBYTE、PWORD、DBYTE、CWORD、XWORD、PBYTE、DWORD具体使用可参看附录中“absacc.h”内容便知。例如:val2=XWORD[0x0004];/*指向片外RAM的0004h字地址。*/C51基础2._at_关键字直接在数据定义后加上_at_const即可.但是注意:绝对变量不能被初使化;bit型函数及变量不能用_at_指定。例如:xdatacharm1[10]_at_0x1000;/*指定m1数组从1000H开始。*/C51基础2._at_关键字直接在数据定义后加上_at_const即可.但是注意:绝对变量不能被初使化;bit型函数及变量不能用_at_指定。例如:idataval3_at_0x40;/*指定val