第四章单片机C语言程序设计 教学目的和要求 本章主要介绍C51的基本数据类型、运算、函数和基本编程方法。 重点要求掌握C51的数据类型、变量存储模式、输入输出处理和函数 等与ANSIC的区别,理解中断函数和重入函数的使用方法,掌握常 用标准库函数的使用。 重点:数据类型、基本编程方法、变量存储模式、输入输出处理 难点:数据类型、基本编程方法 学时:2 1.1概述 一、编程语言 1、机器语言一机器语言是二进制的(例:MCS一51中MOV 的机器语言为0111),不易被人理解,太难掌握:而且因机器而异 程序不易移植。(早期用过) 2、汇编语言一将每条机器指令配上一个助记符(例:MCS 一51中0111的汇编指令为MOV),简单汇编语言中的语句与机器指 令一一对应。汇编语言比机器语言容易一些,但仍然很难掌握:而且 因机器而异,程序不易移植。 3、高级语言一与机器语言和汇编语言相比较,高级语言与具 体计算机无关,是一种能方便描述算法过程的程序设计语言。 (BASIC、PASCAL、C、FORTRAN等) 二、汇编语言的特点: 1.面向机器的低级语言,通常是为特定的计算机专门设计的。 1
2.保持了机器语言的优点,具有直接和简捷的特点。 3.可有效地访问、控制计算机的各种硬件设备,如磁盘、存储器、CU、 I/O端口等。 4目标代码简短,占用内存少,执行速度快。 5.经常与高级语言配合使用。 三、C语言的特点: 1.可以对硬件进行直接操作,和汇编语言一样对位、字节和地 址进行操作。 2.与汇编相比,编写程序方便,可读性强,开发时间短,方便 移植 3.缺点是占用资源较多,执行效率没有汇编高(低10%一20%), 但目前一般都能满足要求。 说明: 1、目前,C与汇编联合编程是单片机开发的趋势。 2、不论是什么语言最终都要由编译器(C编译器,汇编编译器) 翻译成机器语言,才能由计算机执行。 3、针对51单片机的C语言叫C51,他和传统的C有些区别, 尤其是函数库。 2.2C51基本语法 一、C51基本数据类型 C51支持的变量通常有如下类型: l、字符型(char)一字符变量的长度为1byte,即8位。默认的 char为无符号型。 2
cunsigned char;数据范围0—255(8位数据) signed char:数据范围-l28—127(第1位符号:0正1负, 后7位是数据) 2、整型(int)一整型变量的长度为l6位,即两字节。默认的int 为无符号型 unsigned int;065535(16位数据) signed int::一32768—32767(第一位0正,1负,后15位是数 据) 3、长整型(1 ong int)一长整型变量占用4个字节,32位。默 认的long int为无符号型,数据范围与int相似 4、浮点型(oa)—浮点型变量占4个字节,它用符号位表示数 的符号,用阶码和尾数表示数的大小。(存储时:第一位符号位:0 正1负,2一9位是阶码,共8位,后23位是尾数,)实际书写中写 成10进制。 5、指针型(*)一与C中一样,在此变量中存放的是另一数据的 地址。 6、特殊功能寄存器型(sff和sff16) 8051单片机的内部高128个字节内离散的分布着专用寄存器区 (SFR),对SFR的操作,只能采用直接寻址方式。为了能直接访问 这些特殊功能寄存器,C51扩充了两个数据类型:“sfr”、“sfr16”, 这种定义方法与标准C51语言不兼容。 Sf:单字节(8): sf16:双字节(16):在使用特殊功能寄存器时,必须先用sfr或 3
sf16声明。 例:变量的定义 sf特殊功能寄存器名=特殊功能寄存器地址常数; $f16特殊功能寄存器名=特殊功能寄存器地址常数 对于8051片内I/O口,定义方法如下: sfP1=0x90:/定义P1口,地址90H sffP2=0xA0:∥定义P1口,地址A0H 说明:①sf是定义8位的特殊功能寄存器,sf16定义16位特 殊功能寄存器,如8052的T2定时器,可以定义为 sf16T2=0xCC;∥这里定义8052定时器2,地址为 T2L-CCH,T2H-CDH ②用sf16定义16位特殊功能寄存器时,等号后面是它的低位地 址,高位地址一定要位于物理低位地址之上。 ③所以sf16不能用于定时器0和1的定义。 7、位类型(bit和sbit)一占1位(0,1) bit型:用来定义变化的位地址,定义的自变量可在位寻址区变 化。 sbit型:用来定义绝对地址不变的位地址,即:与MCS一51的 可位寻址物理位联系起来,可为寻址的特殊功能寄存器用sbt定义。 sbt'定义某些持殊位,并接受任何符号名,“=”号后将绝对地 址赋给变量名 这种地址分配,有三种方法: ①sbit位变量名=位地址例:sbit P11=Ox91;
同sf一样,sbit的位地址必须位于80H~FFH之间。 ②Sbit位变量名=特殊功能寄存器名位位置 例:sfP3=0xB0: sbit P31=P3^1;∥先定义一个特殊功能寄存器名,再指定位变 量名所在的位置。 ③sbit位变量名=字节地址^位位置例:sbit P31=0xB0A1; 注意:字节地址与位号、特殊功能寄存器与位号之间用分开。 定义位变量时应注意以下问题: 1)位变量不能定义成一个指针,如不能定义:bit*aa。 2)不能定义位数组,如不能定义:bit array[2] 3)bit与sbit的不同。bit不能指定位变量的绝对地址,当需要指 定位变量的绝对地址(范围必须在0x80-0xf)时,需要使用sbit来定 义。例:sbit flag=P10; 4)变量的存储类型为bdata时,该变量的某一位可以用sbit来定 义,当然可用bit型。 bdata char jj;/*i定义为bdata整型变量*/ sbit mybit7=ij7: /*mybit'7定义为ii的第7位*/ 说明:①综上,C51的数据类型如下表: 数据类型 长 度 值域范围 bit 1 bi 0,1 sbit I bit 0,1 unsigned cha 1byte 0-255 signed char 1 byte -128-127
sfr 1 byte 0-255 unsigned int 2byte 0-65536 signed int 2byte -32768-32767 sfr16 2byte 0-65536 1~3 byte 对象的地址 unsigned 4byte 0-4294967295 long signed long 4 byte -2147483648-2147483647 float 4byte +1.175494E-38+3.402823E+38 ②程序中,若运算对象的数据类型不一致,数据类型可以自动进 行转换,转换按以下优先级别自动进行: {-- unsigned-signed ③除了基本数据类型外,还有复合类型(联合、结构等),以后 讲。 二、C51的运算 1、常量一在程序运行中其值不能改变的量称为常量。 ①整型常量。可以表示为十进制如123,0,-8等。十六进制则以 0x开头如0x34。长整型就在数字后面加字母L,如10L,0xF340L 等。 ②浮点型常量一分为十进制和指数表示形式。 十进制由数字和小数点组成,如0.888、3345.345、0.0: 指数表示形式为:[±]数字[数字]e[±]数字
[]中的内容为可选项,其中内容根据具体情况可有可无,但其 余部分必须有,如123e3、5e6、-1.0e-3。而e3,5e4.0则是非法的表示形 式。 ③字符型常量一单引号内的字符,如‘a',‘d”等。 C语言中的转义字符一“”后面的字符,常见的如下表: 0:空字符n:换行 r:回车t:水平制表 ':单引号:反斜杠f换页 b:退格 ④字符串型常量一由双引号内的字符组成,如"hello,"english' 等。当引号内的没有字符时,为空字符串。 2、变量一在程序运行中,其值可以改变的量称为变量 一个变量主要由两部分构成:一个是变量名,一个是变量值。每 个变量都有一个变量名,在内存中占据一定的存储单元,并在该内存 单元中存放该变量的值。 在C51中,变量在使用前必须定义,指出变量的数据类型及存储 模式,变量的定义格式: [存储种类]数据类型[存储器类型变量名[=初值],变量 名2[=初值],…: 1)、存储种类一指变量在程序执行中的作用范围 ①auto(自动):作用范围是定义它的函数体或复合语句中, 省略时默认为auto。 ②extern(外部):在一个函数体内要使用一个已在该函数 体外或别的程序中定义的变量时,用extern型. ③static(静态):分为内部静态和外部静态:
内部静态一在函数体内定义的变量,在函数体内有效,体 外不可见 外部静态一在函数体外定义的变量,己知可见。 ④register(寄存器):C51编译器在编译时,自动将使用最 频繁的变量存为寄存器类型,用户无需声明。(该类型的变量存放在 CPU内的寄存器中,处理速度快,但数量有限) 2)数据类型 注意:①定义变量时,必须指定数据类型,以确定变量在存储中 占用的字节数。数据类型可以是前述的基本型,也可以是复合型(后 讲) ②在编程时,为了书写和阅读方便,经常使用简化的缩写形 式或别名来定义变量的数据类型。其方法是在源程序开头使用#define 语句或typedef语句。 #define别名 C51固有名 typedef C51固有名别名 例如: #define uchar unsigned char #define uint unsigned int typedef unsigned char WORD 3)存储器类型一指变量在单片机硬件系统中所使用的存储区 域。 8051系列单片机在物理上有四个存储空间:片内(外)程序(数 据)存储器空间:
存储器类型 说 data 直接寻址的片内数据存储器低128字节,访问速度最快 bdata 片内RAM的可位寻址区(20H一2FH)(16字节),充 许位与字节混合访问 idata 间接访问片内RAM,允许访问全部256B地址 pdata 分页访问外部数据存储器(256字节),用MOVX@R: 指令访问 xdata 外部数据存储器(64KB),用MOVX@DPTR指令访问 code 程序存储器(64KB),用MOVC@A+DPTR指令访问 4)变量名 -与传统C一样 5)特殊功能寄存器变量(sf和sf16) 定义格式:sf或sf16变量名=地址 Sf:单字节(8): sf16:双字节(16)》 例:sfr PSW=0Xdo,TMOD=0X89; 6)位变量(bit或sbit) ①、bit用于一般的可位处理变量: 格式:bit变量名: 注意:bit变量的存储类型只能是片内RAM区,通常只是bdata 类, 例:bit data al;/正确 bit bdata a2;/正确 bit pdata a3;/错误 ②、sbit用于定义可位寻址字节的位或特殊功能寄存器的位,定 义时需要指明位地址。有三种定义方式(前已讲)。 说明:在C51中,C51编译器已将特殊功能寄存器和特殊位定义
好了,放在reg51.h和reg52.h两个头文件中,使用时只需在使用前加 条预处理命令#include将头文件加在程序中,然后就可以 使用特殊功能寄存器名和特殊位名。 3、编译模式—C51对程序编译时,C51确定参数及变量的存 放位置 存储模式 安 多 SMALL 函数参数及局部变量优先放在片内RAM(默认变量类型 为DATA,最大128字节),当片内RAM用满,再向片外RA 置 COMPACT 参数及局部变量放在片外RAM(默认的存储类型是 DATA,最大256字节):通过R0、R1间接寻址。 Large 参数及局部变量直接放入片外RAM(默认的存储类型是 KDATA,最大64KB):使用数据指针DPTR间接寻址。 说明:1、编译模式不同,对变量默认的存储类型不同 2、程序中,编译模式的指定通过抑ragma来完成,编译 模式的指定可以在函数定义时其后带编译模式,若每有指定,则默认 位small模式。 例:pragma small char kl; #pragma compact char k2; int funcl(int xl,int x2)large {… } 4、绝对地址的访问 8051单片机编程的时,常常需要进行绝对地址(确定低地址)进行访 10