第3章 Keil C及其程序设计(一).ppt.Convertor
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(1)系统总线:
地址总线(16位):P0(地址低8位)、P2口(地址高8位)数据总线(8位):P0口(地址/数据分时复用,借助ALE);
控制总线(6根):P3口的第二功能和9、29、30、31脚;
(2)供用户使用的端口:P1口、部分未作第二功能的P3口;
(3)P0口作地址/数据时,是真正的双向口,三态,负载能力为8个LSTTL电路;P1~P3是准双向口,负载能力为4个LSTTL电路。
(4)P0~P3在用作输入之前必须先写“1”,即:(P0)=FFH ~(P3)=FFH 。
第3章Keil C 及其程序设计
第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.2.3 一个简单的C51程序
3.2.4 C51的运算符
3.2.5 C51的分支与循环程序结构
3.3 C51的集成开发环境Keil µVision3介绍
3.3.1 集成开发环境Keil µVision3简介
3.3.2 Keil µVision3软件的安装、启动和运行
3.3.3 C51程序的开发流程
3.4 C51与汇编语言的混合编程
3.4.1 C51与MCS-51汇编语言的比较
3.4.2 C51与汇编语言混合编程的方法
内容概要:本章初步介绍如何使用C51来编写A T89C51单片机的应用程序。
C51是在标准C的基础上,根据单片机存储器硬件结构及内部资源,扩展了相应的数据类型和变量,而C51在语法规定、程序结构与设计方法上,都与标准C相同。
本章重点介绍C51对标准C所扩展的部分,并通过一些例程来介绍C51的程序设计思想。
最后还对C51的集成
开发环境Keil µVision3以
及C51与汇编语言的混合
编程作以介绍。
Keil C语言的编译器及编
译过程如下图所示。
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单片机硬件的实用高级编程语言。
目前大多数的51单片机用户都在使用C51语言来进行程序设计。
用C51进行单片机软件开发,有如下优点:
(1)可读性好。
C51语言程序比汇编语言程序的可读性好,故编程效率高,程序便于修改。
(2)模块化开发与资源共享。
用C51开发出来的程序模块可以不经修改,直接被其他项目所用,这使得开发者能够很好地利用已有的大量的标准C程序资源与丰富的库函数,减少重复劳动。
(3)可移植性好。
为某种型号单片机开发的C语言程序,只需将与硬件相关之处和编译连接的参数进行适当修改,就可以方便地移植到其他型号的单片机上。
例如,为51单片机编写的程序通过改写头文件以及少量的程序行,就可以方便地移植到PIC单片机上。
(4)代码效率高。
当前较好的C51语言编译系统编译出来的代码效率只比直接使用汇编语言低20%左右,如果使用优化编译选项,效果会更好。
【例】利用单片机的P1口接8个发光二极管,P0口接8个开关,编程实现,当开关动作时,对应的发光二极管亮或灭。
只须把P0口的内容读入后,通过P1口输出即可。
汇编程序:
ORG 0100H
MOV P0,#0FFH
LOOP:MOV A,P0
MOV P1,A
SJMP LOOP
C51语言程序:
#include <reg51.h>
void main(void)
{
unsigned char i;
P0=0xFF;
while(1)
{ i=P0;
P1=i;
}
}
3.1.2 Keil C51的开发环境
Keil C51是德国Keil software公司开发的用于51系列单片机的C51语言开发软件。
Keil C51在兼容ANSI C的基础上,又增加很多与51单片机硬件相关的编译特性,使得开发51系列单片机程序更为方便和快捷,程序代码运行速度快,所需存储器空间小,完全可以和汇编语言相媲美。
它支持众多的MCS-51架构的芯片,同时集编辑、编译、仿真等功能于一体,具有强大的软件调试功能,是众多的单片机应用开发软件中最优秀的软件之一。
Keil公司目前已推出V7.0以上版本的C51编译器,为51单片机软件开发提供了全新的C
语言环境,同时保留了汇编代码高效、快速的特点。
现在,Keil C51已被完全集成到一个功能强大的全新集成开发环境(IDE)µVision3中,该环境下集成了文件编辑处理、编译链接、项目(Project)管理、窗口、工具引用和仿真软件模拟器以及Monitor51硬件目标调试器等多种功能,这些功能均可在Keil µVision3环境中极为简便地进行操作。
本章经常用到Keil C51和Keil µVision3两个术语。
Keil C51一般简写为C51,指的是51单片机编程所用的C语言;而Keil µVision3,可简写为µVision3,指的是用于51单片机的C51程序编写、调试的集成开发环境。
µVision3内部集成了源程序编辑器,并允许用户在编辑源文件时就可设置程序调试断点,便于在程序调试过程中快速检查和修改程序。
此外,µVision3还支持软件模拟仿真(Simulator)和用户目标板调试(Monitor51)两种工作方式。
在软件模拟仿真方式下不需任何51单片机及其外围硬件即可完成用户程序仿真调试。
在用户目标板调试方式下,利用硬件目标板中的监控程序可以直接调试目标硬件系统,使用户节省购买硬件仿真器的费用。
3.1.3 C51与标准C的主要区别
不同的嵌入式处理器的C编译系统与标准C的不同之处,主要是它们所针对的嵌入式处理器的硬件系统不同。
Keil C51的基本语法与标准C相同,但对标准C进行了扩展。
深入理解Keil C51对标准C的扩展部分是掌握Keil C51的关键之一。
C51与标准C的主要区别如下:
(1)头文件的差异。
51系列单片机厂家有多个,它们的差异在于内部资源如定时器、中断、I/O等数量以及功能的不同,而对使用者来说,只需要将相应的功能寄存器的头文件加载在程序内,就可实现所具有的功能。
因此,Keil C51系列的头文件集中体现了各系列芯片的不同资源及功能。
(2)数据类型的不同。
51系列单片机包含位操作空间和丰富的位操作指令,因此Keil C51与ANSI C相比又扩展了4种类型,以便能够灵活地进行操作。
(3)数据存储类型的不同。
C语言最初是为通用计算机设计的,在通用计算机中只有一个程序和数据统一寻址的内存空间,而51系列单片机有片内、外程序存储器,还有片内、外数据存储器。
标准C并没有提供这部分存储器的地址范围的定义。
此外,对于A T89C51单片机中大量的特殊功能寄存器也没有定义。
(4)标准C语言没有处理单片机中断的定义。
(5)Keil C51与标准C的库函数有较大的不同。
由于标准C的中的部分库函数不适于嵌入式处理器系统,因此被排除在Keil C51之外,如字符屏幕和图形函数。
有一些库函数可以继续使用,但这些库函数都必须针对51单片机的硬件特点来作出相应的开发,与标准C库函数的构成与用法有很大的不同。
例如库函数printf和scanf,在标准C 中,这两个函数通常用于屏幕打印和接收字符,而在Keil C51中,它们主要用于串行口数据的收发。
(6)程序结构的差异。
由于51单片机的硬件资源有限,它的编译系统不允许太多的程序嵌套。
其次,标准C所具备的递归特性不被Keil C51支持,在C51中,要使用递归特性,必须用reentrant进行声明才能使用。
但从数据运算操作、程序控制语句以及函数的使用上来说,Keil C51与标准C几乎没有什么明显的差别。
如果程序设计者具备了有关标准C的编程基础,只要注意Keil C51与标准C的不同之处,并熟悉STC89C51单片机的硬件结构,就能够较快地掌握Keil C51的编程。
3.2 C51语言程序设计基础
本节介绍C51语言程序设计的有关基础知识。
3.2.1 C51语言中的数据
1. 数据类型
Keil C51的基本数据类型如表3-1所示。
针对AT89S51单片机的硬件特点,C51在标准C的基础上,扩展了4种数据类型(见表中最后4行)。
注意:扩展的4种数据类型,不能使用指针对它们存取。
在C51语言程序中,有可能会出现在运算中数据类型不一致的情况。
C51允许任何标准数据类型的隐式转换。
隐式转换的优先级顺序如下:
Bit→char→int→long→float→signed→unsigned
也就是说,当char型与int型进行运算时,先自动对char型扩展为int型,然后与int型进行运算,运算结果为int型。
C51除了支持隐式类型转换外,还可以通过强制类型转换符“()”对数据类型进行人为的强制转换。
2. C51的扩展数据类型
下面对表3-1中扩展的4种数据类型进行说明。
(1)位变量bit bit的值可以是1(true), 也可以是0(false)。
例如:bit flag1; bit flag2;
所有的bit变量放在80C51内部数据存储区的(20H~2FH)位段。
因为这个区域只有16个字节长,所以在某个范围内最多只能定义128个位变量。
在格式中可以加上各种修饰,但注意存储器类型只能是bdata、data、idata。
只能是片内RAM的可位寻址区,严格来说只能是bdata。
例如:
bit data a1;/*正确*/ bit bdata a2;/*正确*/
bit pdata a3;/*错误*/ bit xdata a4;/*错误*/
(2)特殊功能寄存器sfr
AT89C51特殊功能寄存器在片内RAM区的80H~FFH之间,“sfr”数据类型占用一个内存单元。
利用它可访问AT89C51内部的所有特殊功能寄存器。
例如:sfr P1=0x90这一语句定义P1口在片内的寄存器,在后面语句中可用“P1=0xff”
(使P1的所有引脚输出为高电平)之类的语句来操作特殊功能寄存器。
在等号(赋值号)的右边指定的地址必须是一个常数,不允许用带操作数的表达式。
80C51系列支持SFR的地址范围为:0x80~0xFF。
同样:sfr p1=0x90; sfr p2=0xa0;sfr p3=0xb0;
p1、p2和p3是声明的SFR名。
【这些定义在REG51.H文件中已经定义过】
(3)特殊功能寄存器sfr16
“sfr16”数据类型占用两个内存单元。
sfr16和sfr一样用于操作特殊功能寄存器。
所不同的是它用于操作占两个字节的特殊功能寄存器。
例如:sfr16 DPTR=0x82语句定义了片内16位数据指针寄存器DPTR,其低8位字节地址为82H。
在后面的语句中可以对DPTR进行操作。
(4)特殊功能位sbit
sbit 是指STC89C51片内特殊功能寄存器的可寻址位。
例如:
sfr PSW=0xd0 ;/*定义PSW寄存器地址为0xd0*/
sbit PSW ^2 = 0xd2 ;/*定义OV位为PSW.2*/
符号“^”前面是特殊功能寄存器的名字,“^”的后面数字定义特殊功能寄存器可寻址位在寄存器中的位置,取值必须是0~7。
注意,不要把bit与sbit混淆。
bit用来定义普通的位变量,值只能是二进制的0或1。
而sbit定义的是特殊功能
寄存器的可寻址位,其值是可进行位寻址的特殊功能寄存器的位绝对地址,例如PSW寄存器OV位的绝对地址0xd2。
在C51中,为了用户处理方便,C51编译器把MCS-51单片机的常用的特殊功能寄存器和特殊位进行了定义,放在一个“reg51.h”或“reg52.h”的头文件中,当用户要使用时,只需要在使用之前用一条预处理命令#include <reg51.h>或#include <reg52.h>把这个头文件包含到程序中,然后就可使用殊功能寄存器名和某些特殊位名称。
3. 数据的存储类型
C51完全支持51单片机硬件系统的所有部分。
在51单片机中,程序存储器与数据存储器是完全分开的,且分为片内和片外两个独立的寻址空间,特殊功能寄存器与片内RAM统一编址,数据存储器与I/O端口统一编址。
C51编译器通过将变量、常量定义成不同存储类型的方法将它们定义在不同的存储区中。
C51存储类型与STC89C51的实际存储空间的对应关系见表3-2。
下面对表3-2作以说明。
(1)片内数据存储器
片内RAM可分为3个区域:
data:片内直接寻址区,位于片内RAM的低128字节。
为片内直接寻址的RAM空间,寻址范围为0~127(00H~7FH)。
在此空间内,存取速度最快。
声明中,如果没有修饰符,则数据默认的存储空间为data型,也就是在片内RAM中。
idata:片内间接寻址区,片内RAM所有地址单元(00H~FFH)。
为片内间接寻址的RAM空间,寻址范围0~255。
由于只能间接寻址,访问速度比直接寻址慢。
bdata:片内位寻址区,位于片内RAM位寻址区20H~2FH。
片内位寻址区,位于片内RAM 位寻址区20H~2FH,位地址范围位0~127。
在此空间允许按字节和按位寻址。
bit定义的变量,严格来说只能是bdata。
表3-2 C51存储器类型与STC89C51存储空间的对应关系
(2)片外数据存储器
外部数据存储区是可读/写的。
可通过一个数据指针加载一个地址来间接访问外部数据区。
因此,访问外部数据区比访问内部数据存储区慢。
外部数据存储区最多可有64KB。
由于硬件设计时,要把外围设备映射到该存储区,所以这些地址不一定都能用来作为数据存储区。
编译器提供两种不同的存储类型来访问外部数据――xdata和pdata。
xdata该标识是指外部数据存储区(64KB)内的任何地址,寻址范围为0~65535。
pdata该标识符仅指一页或256字节的外部数据存储区,寻址范围为0~255。
在定义变量时,通过指明存储器类型,可以将所定义的变量存储在指定的存储区域中。
访问内部数据存储器比访问外部数据存储器快得多。
因此,应该把频繁使用的变量放置在内部数据存储器中,把很少使用的变量放在外部数据存储器中。
在变量声明中,可以包括存储器类型和singed或unsinged属性。
例如:
char data var1;
char code text[]=”Enter Parameter”;
unsigned long xdata array[100];
float idata x,y,z;
unsigned int pdata dimension;
unsigned char xdata vector[10][4][4];
char bdata flag; 【如果位变量区有未用的单元,可以进行字节访问】
如果在变量的定义中,没有包括存储器类型,那么将自动选用默认的存储器类型。
【默认的是什么?】
C51编译器在头文件“reg51.h”中定义了全部sfr/sfr16和sbit变量。
用一条预处理命令#include <reg51.h>把这个头文件包含到C51程序中,无需重定义即可直接使用它们的名称。
REG51.H文件中定义的内容
Header file for generic 80C51 and 80C31 microcontroller
#ifndef __REG51_H__ //先测试是否被宏定义过
#define __REG51_H__
/* BYTE Register */ 字节寄存器
sfr P0 = 0x80;
sfr P1 = 0x90;
sfr P2 = 0xA0;
sfr P3 = 0xB0;
sfr PSW = 0xD0;
sfr B = 0xF0;
sfr SP = 0x81;
sfr DPL = 0x82;
sfr DPH = 0x83;
sfr PCON = 0x87;
sfr TCON = 0x88;
sfr TMOD = 0x89;
sfr TL0 = 0x8A;
sfr TL1 = 0x8B;
sfr TH0 = 0x8C;
sfr TH1 = 0x8D;
sfr IE = 0xA8;
sfr IP = 0xB8;
sfr SCON = 0x98;
sfr SBUF = 0x99;
/* BIT Register */ 可位寻址的位变量/* PSW */
sbit CY = 0xD7;
sbit AC = 0xD6;
sbit F0 = 0xD5;
sbit RS1 = 0xD4;
sbit RS0 = 0xD3;
sbit OV = 0xD2;
sbit P = 0xD0;
/* TCON */
sbit TF1 = 0x8F;
sbit TR1 = 0x8E;
sbit TF0 = 0x8D;
sbit TR0 = 0x8C;
sbit IE1 = 0x8B;
sbit IT1 = 0x8A;
sbit IE0 = 0x89;
sbit IT0 = 0x88;
/* IE */
sbit EA = 0xAF;
sbit ES = 0xAC;
sbit ET1 = 0xAB;
sbit EX1 = 0xAA;
sbit ET0 = 0xA9;
sbit EX0 = 0xA8;
/* IP */
sbit PS = 0xBC;
sbit PT1 = 0xBB;
sbit PT0 = 0xB9; sbit PX0 = 0xB8; /* P3 */
sbit RD = 0xB7; sbit WR = 0xB6; sbit T1 = 0xB5; sbit T0 = 0xB4; sbit INT1 = 0xB3; sbit INT0 = 0xB2; sbit TXD = 0xB1; sbit RXD = 0xB0; /* SCON */ sbit SM0 = 0x9F; sbit SM1 = 0x9E; sbit SM2 = 0x9D; sbit REN = 0x9C; sbit TB8 = 0x9B; sbit RB8 = 0x9A; sbit TI = 0x99; sbit RI = 0x98; #endif。