第4章 AT89S51汇编语言程序设计

Download Report

Transcript 第4章 AT89S51汇编语言程序设计

第3章
单片机C语言
程序设计基础
1
第3章
目录
3.1 编程语言Keil C51简介
3.1.1 Keil C51简介
3.1.2 Keil C51的开发环境
3.1.3 C51与标准C的主要区别
3.2 C51语言程序设计基础
3.2.1 C51语言中的数据
3.2.2 C51的位变量定义
3.3 C51的运算符
3.4 C51的分支与循环程序结构
3.5 一个简单的C51程序
2
内容概要
本章在假定读者已掌握标准C语言前提下,初步介绍
如何使用C51来编写AT89C51单片机的应用程序。
C51是在标准C的基础上,根据单片机存储器硬件结
构及内部资源,扩展了相应的数据类型和变量,而C51在
语法规定、程序结构与设计方法上,都与标准C相同。
本章重点介绍C51对标准C所扩展的部分,并通过一
些例程来介绍C51的程序设计思想。最后还对C51的集成
开发环境Keil µVision3以及C51与汇编语言的混合编程作
以介绍。
3
3.1 编程语言Keil C51简介
目前51系列单片机编程的C语言都采用Keil C51(简称
C51),Keil C51是在标准C语言基础上发展起来的。
3.1.1 Keil C51简介
C语言是美国国家标准协会(ANSI)制定的编程语言
标准,1987年ANSI公布87 ANSI C,即标准C语言。
Keil C51语言是在ANSI C的基础上针对51单片机的硬件
特点进行的扩展,并向51单片机上移植,经过多年努力,
C51语言已经成为公认的高效、简洁而又贴近51单片机硬
件的实用高级编程语言。
4
目前大多数的51单片机用户都在使用C51语言来进行
程序设计。
用C51进行单片机软件开发,有如下优点:
(1)可读性好。C51语言程序比汇编语言程序的可读性
好,因而编程效率高,程序便于修改。
(2)模块化开发与资源共享。用C51开发出来的程序模
块可以不经修改,直接被其他项目所用,这使得开发者能
够很好地利用已有的大量的标准C程序资源与丰富的库函
数,减少重复劳动。
5
(3)可移植性好。为某种型号单片机开发的C语言程序,
只需将与硬件相关之处和编译连接的参数进行适当修改,
就可以方便地移植到其他型号的单片机上。例如,为51单
片机编写的程序通过改写头文件以及少量的程序行,就可
以方便地移植到PIC单片机上。
(4)代码效率高。当前较好的C51语言编译系统编译出
来的代码效率只比直接使用汇编语言低20%左右,如果使
用优化编译选项,效果会更好。
6
3.1.2 Keil C51的开发环境
Keil C51是德国Keil software公司开发的用于51系列
单片机的C51语言开发软件。Keil C51在兼容ANSI C的基
础上,又增加很多与51单片机硬件相关的编译特性,使得
开发51系列单片机程序更为方便和快捷,程序代码运行速
度快,所需存储器空间小,完全可以和汇编语言相媲美。
它支持众多的MCS-51架构的芯片,同时集编辑、编译、
仿真等功能于一体,具有强大的软件调试功能,是众多的
单片机应用开发软件中最优秀的软件之一。
7
Keil公司目前已推出V7.0以上版本的C51编译器,为
51单片机软件开发提供了全新的C语言环境,同时保留了
汇编代码高效、快速的特点。
现在,Keil C51已被完全集成到一个功能强大的全新
集成开发环境(IDE)µVision3中,该环境下集成了文件
编辑处理、编译链接、项目(Project)管理、窗口、工具
引用和仿真软件模拟器以及Monitor51硬件目标调试器等
多种功能,这些功能均可在Keil µVision3环境中极为简便
地进行操作。
8
本章经常用到Keil C51和Keil µVision3两个术语。
Keil C51一般简写为C51,指的是51单片机编程所用的C
语言;而Keil µVision3,可简写为µVision3,指的是用于
51单片机的C51程序编写、调试的集成开发环境。
µVision3内部集成了源程序编辑器,并允许用户在编
辑源文件时就可设置程序调试断点,便于在程序调试过程
中快速检查和修改程序。此外,µVision3还支持软件模拟
仿真(Simulator)和用户目标板调试(Monitor51)两种工
作方式。在软件模拟仿真方式下不需任何51单片机及其外
围硬件即可完成用户程序仿真调试。
9
在用户目标板调试方式下,利用硬件目标板中的监控
程序可以直接调试目标硬件系统,使用户节省购买硬件仿
真器的费用。
3.1.3 C51与标准C的主要区别
不同的嵌入式处理器的C编译系统与标准C的不同之
处,主要是它们所针对的嵌入式处理器的硬件系统不同。
Keil C51的基本语法与标准C相同,但对标准C进行了扩展。
深入理解Keil C51对标准C的扩展部分是掌握Keil C51
的关键之一。
10
C51与标准C的主要区别如下:
(1)头文件的差异。51系列单片机厂家有多个,它们的
差异在于内部资源如定时器、中断、I/O等数量以及功能
的不同,而对使用者来说,只需要将相应的功能寄存器的
头文件加载在程序内,就可实现所具有的功能。因此,
Keil C51系列的头文件集中体现了各系列芯片的不同资源
及功能。
(2)数据类型的不同。51系列单片机包含位操作空间和
丰富的位操作指令,因此Keil C51与ANSI C相比又扩展了
4种类型,以便能够灵活地进行操作。
11
(3)数据存储类型的不同。C语言最初是为通用计算机
设计的,在通用计算机中只有一个程序和数据统一寻址的
内存空间,而51系列单片机有片内、外程序存储器,还有
片内、外数据存储器。标准C并没有提供这部分存储器的
地址范围的定义。此外,对于AT89C51单片机中大量的特
殊功能寄存器也没有定义。
(4)标准C语言没有处理单片机中断的定义。
(5)Keil C51与标准C的库函数有较大的不同。
由于标准C的中的部分库函数不适于嵌入式处理器系统,
因此被排除在Keil C51之外,如字符屏幕和图形函数。
12
有一些库函数可以继续使用,但这些库函数都必须针
对51单片机的硬件特点来作出相应的开发,与标准C库函
数的构成与用法有很大的不同。例如库函数printf和scanf,
在标准C中,这两个函数通常用于屏幕打印和接收字符,
而在Keil C51中,它们主要用于串行口数据的收发。
(6)程序结构的差异。由于51单片机的硬件资源有限,
它的编译系统不允许太多的程序嵌套。其次,标准C所具
备的递归特性不被Keil C51支持,在C51中,要使用递归
特性,必须用reentrant进行声明才能使用。
13
但是从数据运算操作、程序控制语句以及函数的使用
上来说,Keil C51与标准C几乎没有什么明显的差别。如
果程序设计者具备了有关标准C的编程基础,只要注意
Keil C51与标准C的不同之处,并熟悉AT89S51单片机的
硬件结构,就能够较快地掌握Keil C51的编程。
14
3.2 C51语言程序设计基础
本节介绍C51语言程序设计的有关基础知识。
3.2.1 C51语言中的数据
1. 数据类型
Keil C51的基本数据类型如表14-1所示。针对
AT89S51单片机的硬件特点,C51在标准C的基础上,扩
展了4种数据类型(见表中最后4行)。
注意:扩展的4种数据类型,不能使用指针对它们存
取。
15
表14-1 Keil C51支持的数据类型
数据类型
signed char
位数
8
字节数
1
取值范围
-128~+127,有符号字符变量
unsigned char
8
1
0~255,无符号字符变量
signed int
16
2
-32768~+32767,有符号整型数
unsigned int
16
2
0~65535,无符号整型数
signed long
32
4
unsigned long
32
4
0~+4294967295,无符号长整型数
float
32
4
±3.402823 E+38,浮点数(精确到7位)
double
64
8
±1.175494E-308,浮点数(精确到15位)
*
bit
sfr
sfr16
sbit
24
1
8
16
1
1~3
对象指针
0或1
0~255
0~65535
可进行位寻址的特殊功能寄存器
的某位的绝对地址
1
2
-2147483648~+2147483647,有符号长
整型数
16
2. C51的扩展数据类型
下面对表14-1中扩展的4种数据类型进行说明。
(1)位变量bit
bit的值可以是1(true), 也可以是0(false)。
(2)特殊功能寄存器sfr
AT89S51特殊功能寄存器在片内RAM区的80H~FFH
之间,“sfr” 数据类型占用一个内存单元。利用它可访
问AT89S51内部的所有特殊功能寄存器。
例如:sfr P1=0x90这一语句定义P1口在片内的寄存
器,在后面语句中可用“P1=0xff”(使P1的所有引脚输出
17
为高电平)之类的语句来操作特殊功能寄存器。
(3)特殊功能寄存器sfr16
“sfr16”数据类型占用两个内存单元。sfr16和sfr一样
用于操作特殊功能寄存器。所不同的是它用于操作占两个字
节的特殊功能寄存器。
例如: sfr16 DPTR=0x82语句定义了片内16位数据指
针寄存器DPTR,其低8位字节地址为82H。在后面的语句中
可以对DPTR进行操作。
18
(4)特殊功能位 sbit
sbit 是指AT89S51片内特殊功能寄存器的可寻址位。
例如:
sfr PSW=0xd0
;/*定义PSW寄存器地址为0xd0*/
sbit PSW ^2 = 0xd2
;/*定义OV位为PSW.2*/
符号“^”前面是特殊功能寄存器的名字,“^”的后
面数字定义特殊功能寄存器可寻址位在寄存器中的位置,
取值必须是0~7。
注意,不要把bit与sbit混淆。bit用来定义普通的位变
量,值只能是二进制的0或1。而sbit定义的是特殊功能
19
寄存器的可寻址位, 其值是可进行位寻址的特殊功能寄
存器的位绝对地址,例如PSW寄存器OV位的绝对地址
0xd2。
3. 数据的存储类型
C51完全支持51单片机硬件系统的所有部分。在51单
片机中,程序存储器与数据存储器是完全分开的,且分为
片内和片外两个独立的寻址空间,特殊功能寄存器与片内
RAM统一编址,数据存储器与I/O端口统一编址。C51编
译器通过将变量、常量定义成不同存储类型的方法将它们
定义在不同的存储区中。
20
C51存储类型与AT89S51的实际存储空间的对应关系
见表14-2。下面对表14-2作以说明。
(1)片内数据存储器
片内RAM可分为3个区域:
data:片内直接寻址区,位于片内RAM的低128字节。
bdata:片内位寻址区,位于片内RAM位寻址区
20H~2FH。
idata:片内间接寻址区,片内RAM所有地址单元
(00H~FFH)。
21
22
(2)片外数据存储器
pdata:片外数据存储器页,一页为256字节。
xdata:片外数据存储器RAM的64KB空间。
(3)片外程序存储器
code:外部程序存储器的64KB空间。
对单片机编程,正确地定义数据类型以及存储类型,是所
有编程者在编程前都需要首先考虑的问题。在资源有限的
条件下,如何节省存储单元并保证运行效率,是对开发者
的一个考验。只有对C51中的各种数据类型以及存储类型
非常熟练的掌握,才能运用自如。
23
定义变量类型应考虑如下问题:程序运行时该变量可
能的取值范围,是否有负值,绝对值有多大,以及相应需
要的存储空间大小。在够用的情况下,尽量选择8位即一
个字节的char型,特别是unsiged char。对于51系列这样
的定点机而言,浮点类型变量将明显增加运算时间和程序
长度,如果可以的话,尽量使用灵活巧妙的算法来避免浮
点变量的引入。
定义数据的存储类型通常遵循如下原则:只要条件满
足,尽量选择内部直接寻址的存储类型data,然后选择
idata即内部间接寻址。对于那些经常使用的变量要使用内
24
部寻址。在内部数据存储器数量有限或不能满足要求的情
况下才使用外部数据存储器。选择外部数据存储器可先选
择pdata类型,最后选用xdata类型。
需指出,扩展片外存储器,原理上虽很简单,但在实
际开发中,很多时候,会带来不必要的麻烦,如可能降低
系统稳定性、增加成本、拉长开发和调试周期等,推荐充
分利用片内存储空间。
另外,通常的单片机应用都是面对小型的控制,代码
比较短,对于程序存储区的大小要求很低,常常是片内
RAM很紧张而片内Flash ROM很富裕,因此如果实时性
25
要求不高,可考虑使用宏,以及将一些子函数的常量数据
做成数据表,放置在程序存储区,当程序运行时,进入子
函数动态调用下载至RAM即可,退出子函数后立即释放该
内存空间。
26
3.2.2 C51的位变量定义
由于AT89C51能够进行位操作,C51扩展了“bit”数
据类型用来定义位变量,这是C51与标准C的不同之处。
C51中位变量bit的具体定义如下:
1. 位变量的C51定义方法
C51通过关键字“bit”来定义位变量,格式为:
bit bit-name
;
例如:bit ov-flag
;/* 将ov-flag定义为位变量*/
27
2. C51程序函数的“bit”参数及返回值
C51程序函数可以包含类型为“bit”的参数,也可将
其作为返回值。例如:
bit func(bit b0, bit b1);
/* 位变量b0,b1作为函数func的参数*/
{
……
return(b1);
/* 位变量b1作为函数的返回值*/
}
28
3. 位变量的限制
位变量不能用来定义指针和数组。例如:
bit *ptr
;/* 错误,不能用位变量来定义指针*/
bit a-array[ ]
;/* 错误,不能用位变量来定义数组*/
在定义位变量时,允许定义存储类型,位变量都被放
入一个位段,此段总是位于AT89S51片内RAM中,因此
其存储器类型限制为bdata,data 或idata,如果将位变量
定义成其他类型都会在编译时出错。
29
关于循环,需说明的是,在无操作系统的控制器和处
理器上运行的程序,主体通常采用轮询方式,即把所有的
操作包含在一个while(1){}中,如例14-1。这样的无限循环
在面向通用计算机的软件设计中是不被允许的,然而嵌入
式系统软件设计中,则由于其硬件构成和使用需求,常常
采用这种无限循环。
30