1、第3章 C51语言编程基础 学习目标(1)了解C51编程的一般设计流程。(2)掌握C51程序设计的基本方法。学习重点和难点(1)C51的数据类型、存储器类型和存储模式。(2)C51的函数定义及使用方法。(3)C51指针的使用。3.1 单片机的C51基础知识(1)对单片机的指令系统不要求了解,仅要求对8051的存储器结构有初步了解;(2)寄存器分配、不同存储器的寻址及数据类型等细节可由编译器管理;(3)程序有规范的结构,可分成不同的函数,这种方式可使程序结构化;(4)提供的库包含许多标准子程序,具有较强的数据处理能力;(5)由于具有方便的模块化编程技术,使已编好程序容易移植;3.1.2 C51的
2、基本数据类型 1 char 字符类型 无符号字 符类型 unsigned char 有符号字符类型 signed char,默认值为 signed char 类型。2 int 整型 有符号 int 整型数 signed int 无符号整型数 unsigned int,默认值为 signed int 类型 3 long 长整型 有符号 long 长整型 signed long 无符号长整型 unsigned long,默认值为 signed long 类型 4 float 浮点型 5.bit 位变量 6 sfr 特殊功能寄存器,例如:sfr P1=0 x90 7sfr16 16 位特殊功能寄存器
3、 8 sbit 可寻址位 sfr P1=0 x90;/因 P1 端口的寄存器是可位寻址的,所以能定义 sbit P1_1=P11;/P1_1 为 P1 中的 P1.1 引脚3.1.3存储器类型存储器类型存储器类型描描 述述data直接寻址内部数据存储器,访问变量速度最快(直接寻址内部数据存储器,访问变量速度最快(128bytes)bdata可位寻址内部数据存储器,允许位与字节混合访问(可位寻址内部数据存储器,允许位与字节混合访问(16 bytes)idata间接寻址内部数据存储器,可访问全部地址空间(间接寻址内部数据存储器,可访问全部地址空间(256bytes)pdata分页(分页(256by
4、tes)外部数据存储器,由操作码)外部数据存储器,由操作码MOVX Ri访问访问xdata外部数据存储器(外部数据存储器(64KB),由),由MOVX DPTR访问访问code代码数据存储器(代码数据存储器(64KB),由),由MOVC A+DPTR访问访问3.1.4 存储器模式存储器模式 描 述SMALL参数及局部变量放入可直接寻址的内部寄存器(最大128bytes128bytes,默认存储器类型是DATA)COMAPCT 参数及局部变量放入分页外内部存储区(最大256bytes256bytes,默认存储器类型是PDATA)LARGE参数及局部变量直接放入外部数据存储器(最大64K64K,默
5、认存储器类型是XDATA)3.1.5 C51常量 1 整型常量能表示为十进制如 123、0、89 等。十六进制则以 0 x 开头如 0 x34、-0 x3B 等。长整型就在数字后面加字母 L,如 104L、034L 等。2 浮点型常量可分为十进制和指数表示形式。如0.888,3345.345,0.0 等 如125e3,7e9,-3.0e-3 3 字符型常量是单引号内的字符,如a,d等,4 字符串型常量由双引号内的字符组成,如“test”,“OK”等。5 位常量,它的值是一个二进制数。3.2 C51的基本运算 1.算术运算符+加A=x+y-减B=x-y*乘C=x*y/除D=x/y%取余数E=x%
6、y2.关系运算符符号功能范例说明=相等x=y比较x与y变量的值,相等则结果为1,不相等则为0!=不相等x!=y比较x与y变量的值,不相等则结果为1,相等则为0大于xy若x变量的值大于y变量的值,其结果为1,否则为0小于x=大等于x=y若x变量的值大于或等于y变量的值,其结果为1,否则为0=小等于xy)&(yz)若x变量的值大于y变量的值,且y变量的值也大于z变量的值,其结果为1,否则为0|或运算(xy)|(yz)若x变量的值大于y变量的值,或y变量的值大于z变量的值,其结果为1,否则为0!反相运算!(xy)若x变量的值大于y变量的值,其结果为0,否则为14.位运算符 符号功能范例&及运算A=x
7、&y|或运算B=x|y 异或 C=xy 取反 D=x 左移 E=x右移 F=xn5.递增/减运算符符号功能 范例说明+加1x+将x变量的值加1-减1x-将x变量的值减13.3 C51的程序设计基础 1.while循环语句的格式如下:While(表达式)语句;2.for循环语句 for语句是一个很实用的计数循环,其格式如下:格式:for(表达示1;表达示2;表达示3)语句;3.if选择语句if-else语句提供条件判断的语句,称为条件选择语句,其格式如下:if(表达式)语句1;else语句2;4多分支条件语句和开关语句 (1 1)多分支语句格式如下:)多分支语句格式如下:if(if(条件表达式条
8、件表达式1)1)语句语句1 1 else if(else if(条件表达式条件表达式2)2)语句语句2 2 else if(else if(条件表达式条件表达式m)m)语句语句m m else if(else if(条件表达式条件表达式n)n)语句语句n n else else 语句语句p p 4多分支条件语句和开关语句(2)开关语句 switch(表达式)case 常量1:语句1 break;case 常量2:语句2 break;case 常量m:语句m break;case 常量n:语句n break;default:语句p 5.其它语句 (1)绝对跳转语句:goto goto 标号;(2
9、)返回语句:return return(表达式或变量);(3)退出语句:break和continue 3.3.2数组unsigned int xcount 10;/定义无符号整形数组,有 10 个数据单元char inputstring 5;/定义字符形数组,有5个数据单元float outnum 10,10;/定义浮点型数组,有100个数据单元表3-10 数组定义数据类型数组名常量表达式;数据类型数组名常量表达式 1.常量表达式 N;3.3.2指针 用一个变量来存放另一个变量的地址,那么用来存放变量地址的变量称为“指针变量”变量的指针就是变量的地址,用取地址运算符&取得赋给指针变量。&STR
10、 就是把变量STR的地址取得。要访问变量STR除了能用STR这个变量名来访问之外,还能用变量地址来访问。方法是先用&STR取变量地址并赋于STRIP指针变量,然后就能用*STRIP 来对STR进行访问了。*是指针运算符,用它能取得指针变量所指向的地址的值。3.4 C51的函数 1.函数的定义 函数定义格式如下:返回值的数据类型 函数名(形参变量1说明,。,形参变量n说明)局部变量定义 函数体语句 返回语句 void 函数名(void)函数体语句 2主函数 void main(void)语句 3.中断函数 void T0_interrupt(void)interrupt 1 中断源名称 中断号
11、外部中断INT0 0 定时器/计数器T0中断 1 外部中断INT1 2 定时器/计数器T1中断 3 串行口中断UART 4 定时器/计数器T2中断T 5 在main函数里调用TwoDataAdd函数:void main(void)char a,b;int c;a=38;b=99;c=TwoDataAdd(a,b);4.库函数 函数库 对应的头文件 功能 字符函数 CTYPE.H CTYPE.H 与ASKII码表相关 一般I/O函数 STDIO.H STDIO.H 与UART相关 字符串函数 STRING.H STRING.H 字符串的截取、查找、比较等 标准函数 STDLIB.H STDLIB
12、.H 字符串与数字之间的转换 数学函数 MATH.H MATH.H 求绝对值、平方开方、三角函数 绝对地址访问 ABSACC.H ABSACC.H 绝对地址访问 内部函数 INTRINS.H INTRINS.H 只有_NOP_()函数有用,相当于汇编里的NOP 变量参数表 STDARG.H STDARG.H 不用 全程跳转 SETJMP.H SETJMP.H 不用 SFR访问 REG51/52.H REG51/52.H 特殊功能寄存器声明 5函数的调用 void main(void)char a,b;int c;a=38;b=99;c=TwoDataAdd(a,b);变量a、b叫实参,调用Tw
13、oDataAdd()函数时,实参a、b的值分别传递给形参FirstData和SecondData,用变量c接收函数的返回值。值传递的点是,在函数调用结束后,实参仍旧保持原来的值,即a=38、b=99,而形参被释放。【例【例3-13-1】写出一个完整的调用子函数的例子,用单片机控制一个】写出一个完整的调用子函数的例子,用单片机控制一个LEDLED灯闪烁发光。用灯闪烁发光。用P1P1口的第一个引脚控制一个口的第一个引脚控制一个LEDLED灯,灯,1 1秒钟闪烁一次。秒钟闪烁一次。#include /#include /头文件头文件#define uint unsigned int /#define
14、 uint unsigned int /宏定义宏定义 sbit D1=P10;/sbit D1=P10;/声明单片机声明单片机P1P1口的第一位口的第一位 uint x,y;uint x,y;void main()void main()while(1)/while(1)/大循环大循环 D1=0;/D1=0;/点亮第一个发光二极管点亮第一个发光二极管for(x=500;x0;x-)for(x=500;x0;x-)for(y=110;y0;y-);for(y=110;y0;y-);D1=1;/D1=1;/关闭第一个发光二极管关闭第一个发光二极管for(x=500;x0;x-)for(x=500;x
15、0;x-)for(y=110;y0;y-);for(y=110;y0;y-);#include /头文件#define uint unsigned int /宏定义 sbit D1=P10;/声明单片机P1口的第一位 void delay();/声明子函数 void main()while(1)/大循环D1=0;/点亮第一个发光二极管delay();/延时500毫秒D1=1;/关闭第一个发光二极管delay();/延时500毫秒 void delay()/延时子程序延时约500毫秒 uint x,y;for(x=500;x0;x-)for(y=110;y0;y-);【例3-3】调用子函数的例子
16、,用单片机控制一个LED灯闪烁发光。用P1口的第一个引脚控制一个LED灯,让它亮500ms,灭800ms。#include /#include /头文件头文件#define uint unsigned int /#define uint unsigned int /宏定义宏定义 sbit D1=P10;/sbit D1=P10;/声明单片机声明单片机P1P1口的第一位口的第一位 void delay(uint z);/void delay(uint z);/声明子函数声明子函数 void main()void main()while(1)/while(1)/大循环大循环 D1=0;/D1=0;
17、/点亮第一个发光二极管点亮第一个发光二极管delay(500);/delay(500);/延时延时500500毫秒毫秒D1=1;/D1=1;/关闭第一个发光二极管关闭第一个发光二极管delay(800);/delay(800);/延时延时800800毫秒毫秒 void delay(unsigned int z)/延时子程序延时约500毫秒 uint x,y;for(x=z;x0;x-)for(y=110;y0;y-);本章小结 C51是面向51系列单片机所使用的程序设计语言,使MCS-51单片机的软件具有良好的可读性和可移植性。具有操作直接、简洁和程序紧凑的优点,为大多数51单片机实际应用最为广泛的语言。C51编译器常用的数据类型有字符型、整型、长整型、浮点型、位型和指针型。任何数据都要以一定的存储器类型定位到单片机的存储区中,如用户未做定义,则依据系统默认存储器类型进行存储。