第3章单片机C语言程序设计课件_第1页
第3章单片机C语言程序设计课件_第2页
第3章单片机C语言程序设计课件_第3页
第3章单片机C语言程序设计课件_第4页
第3章单片机C语言程序设计课件_第5页
已阅读5页,还剩75页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

3单片机的C语言程序设计教学目的熟悉C51的程序结构掌握C51的数据类型、存储类型及函数等概念了解C51与标准C的不同之处熟悉C51的开发工具KeilC51如何学习2本章内容C51的程序结构数据类型、存储类型及存储模式运算符、函数及程序流程控制C51的构造数据类型C51实例分析及混合编程KeilC51简介33.1C51的程序结构与汇编语言相比,C51在功能、结构性、可读性、可维护性及可移植性上有明显的优势。C51程序结构与一般C语言没有差别。C51的特点:

1.C51在吸取了汇编语言精华的基础上又有所改进

2.C51继承和发扬了高级语言的长处

3.C51的可移植性好

4.生成的代码质量高,在代码效率方面可以和汇编语言相媲美

C51的程序结构3.1C51的程序结构

5C51程序的结构一个C51程序大体上是一个函数定义的集合,在这个集合中仅有一个名为main的函数(主函数)。

函数定义由类型、函数名、参数表和函数体四部分组成。函数的一般格式如下:

类型函数名(参数表)

参数说明;

{

数据说明部分;

执行语句部分;

}C51的程序结构3.1C51的程序结构

6编写C51 程序时应注意以下几点:1.一个C51程序总是从main函数开始执行的,而不论main函数在整个程序中的位置如何。2.C语言程序的书写格式十分自由。一条语句可以写成一行,也可以写成几行,还可以在一行内写多条语句。但每条语句都必须以分号“;”作为结束符。3.C语言对大小字母敏感,C语言编译器编译程序时对同一个字母的大小写作为不同的变量来处理。4.可以用/*……*/对C程序中的任何部分作注释。程序加上必要的注释,可增加程序的可读性。C51的程序结构3.1C51的程序结构

73.2数据类型、存储类型及存储模式

数据类型常量和变量C51的存储类型及存储模式特殊功能寄存器、并行接口及位变量的定义数据类型

可分为基本数据类型和构造数据类型。构造数据类型由基本数据类型构造而成。C51的数据类型分类如下所示:

数据类型、存储类型及存储模式3.2

数据类型、存储类型及存储模式

910常量和变量

C语言中的数据有常量、变量之分。

常量——在程序运行的过程中,其值不能改变的量称为常量。C语言支持4种常量:整数常量、浮点数常量、枚举量常量、字符常量。

变量——在程序执行过程中,其值能不断变化的量。使用一个变量之前必须进行定义,用一个标识符作为变量名并指出它的数据类型和存储类型,以便编译系统为它分配相应的存储单元。数据类型、存储类型及存储模式3.2

数据类型、存储类型及存储模式

11C51的存储类型及存储模式51系列单片机的存储器采用哈佛结构。即其程序存储器和数据存储器分开,并有各自的寻址机构和寻址方式。以AT89C52为例,其具体结构如下图所示。

数据类型、存储类型及存储模式3.2

数据类型、存储类型及存储模式

12C51的存储类型及存储模式

AT89C52单片机在物理上有四个存储空间:1.片内程序存储器空间2.片外程序存储器空间3.片内数据存储器空间4.片外数据存储器空间片内数据存贮区是存放临时性传递变量或使用频率较高的变量的。访问片内数据存贮器速度较快,经常使用的变量置于片内数据存贮器,而将不常用的置于片外数据存贮器中。寻址方式可使用直接和间接寻址数据类型、存储类型及存储模式3.2

数据类型、存储类型及存储模式

13

C51在定义变量、常量时,将通过不同的存储类型(data、bdata、idata、pdata、xdata、code)将它们定位在不同的存储区中。存储类型与AT89C52单片机实际存储空间的对应关系如下所示。data直接寻址内部数据存储区,访问速度快(128B),00~7FHbdata

可位寻址内部数据存储区,允许位与字节混合访问(16B)idata

间接寻址内部数据存储区,可访问片内全部RAM地址空间(256B),00~FFHpdata

分页寻址外部数据存储区(256B),由MOVX@Ri访问(高位P2)xdata

外部数据存储区(64KB),由MOVX@DPTR访问code代码存储区(64KB)程序由MOVC@A+DPTR访问C51的存储类型3.2

数据类型、存储类型及存储模式

一定要熟悉噢!14当使用code存贮类型定义数据时,C51编译器会将其定义在代码空间或FLASH访问片内数据存贮器data、bdata、idata比访问片外数存相对要快一些,因此,可将经常使用的变量置于片内数存15例:codeuchartable[]={1,2,3,”help”,oxff};idata

uinttemp;datacharvar;/chardatavar;等价尽量用后一种staticunsignedlongxdataarray[100];静态变量externfloatidata

x,y,z;模块化编程uint

pdatadimension;uchar

xdatavector[10][4][4];charbdataflags;16如果省略掉数据类型存储模式,将自动决定变量的默认存储类型作为编译的选项。由编译器选用的存储模式决定。存储模式决定了变量的默认存储类型,参数传递区和无明确存储类型说明变量的存储类型。17存储模式说明SMALL:可直接寻址的内部数据存储区COMPACT:分页外部数据存储区LARGE:外部数据存储区参数和局部变量放入Cx51允许在变量类型定义前,指定存储类型

datacharx与chardatax等价,但应尽量使用后一种18特殊功能寄存器的定义

AT89C52单片机中除了程序计数器PC和4组通用寄存器组(R0--R7)之外,其他所有寄存器均称为特殊功能寄存器(SFR),它们分散在片内RAM区的高128B中,它们只能采用直接寻址方式访问。

为了能直接访问这些SFR,C51扩充了类型说明符sfr、sfr16、sbit。利用它们可在C语言源程序中直接对AT89C52单片机的特殊功能寄存器进行定义。

数据类型、存储类型及存储模式3.2

数据类型、存储类型及存储模式

1920定义方法如下:

sfr

特殊功能寄存器名=地址常数

sfr16特殊功能寄存器名=地址常数注:1、可以与变量名一样,用SFR名去存取SFR。

2、定义时标示符必须使用SFR名,且必须把原来分配好的绝对地址赋给预定义标示符例:sfrAcc=0xE0;

sfrP0=0x80;21由于51系列中不同的单片机的寄存器数量与类型不同,所以可采用头文件。头文件reg52.h中有所有89C52的SFR及可位寻址的位的定义,只要

#include<reg52.h>22程序的开头可以都加上以下三行#include<reg52.h>#defineucharunsignedchar#defineuintunsignedint头文件reg52.h中有所有89C52的SFR

及可位寻址位的定义23SFR一般按8位存取,在新的8051系列产品中有按16位存取的(如,8052有T2),它们需用sfr16类型来说明(*)sfr16T2=0xCC24定义SFR的位Sbit可以访问位寻址对象1、sbitSFR的位标示符=可按位寻址的SFR名^常量

sfrPSW=0xD0;

sbitOV=PSW^2;

sbitCy=PSW^7;252、sbitSFR的位标示符=可按位寻址的SFR的绝对地址^常量其中,绝对地址位于80H~FFH之间,且该地址能被8整除

sbitOV=0xD0^2;

sbitCy=0xD0^7;263、sbitSFR的位标示符=可按位寻址的SFR的绝对位地址该绝对位地址位于80H~FFH之间

sbitOV=0xD2;

sbitCy=0xD7;

特殊功能位代表了一个独立的定义类,不能与其他位定义和位域互换27并行接口的定义

AT89C52单片机内部有4个8位并行口,即SFR中的P0--P3。这些内部并行口既可进行字节寻址,也可进行位寻址。

除了内部4个并行口之外,AT89C52单片机还可以在片外扩展硬件I/O口,这些I/O口大多只能进行字节寻址。

AT89C52单片机没有专用的I/O指令,它的口地址是和数据存储器统一编址的。即把一个口看作是数据存储器的一个单元。程序采用访问数据存储器的指令来访问I/O口。数据类型、存储类型及存储模式3.2

数据类型、存储类型及存储模式

2851系列并行接口及其Cx51定义编程时,片内I/O口与片外扩展I/O口可统一在头文件中定义,也可在程序的开始位置定义,方法如下:1、片内I/O口(用sfr定义)

sfrP0=0x80

sfrP1=0x90292、片外扩展I/O口,根据其硬件译码地址,将其视为片外数据存储器的一个单元,用define定义。#include<absacc.h>#definePORTAXBYTE[0xffc0]{i=PORTA;PORTA=i;}30定义口地址的目的,便于Cx51编译器按51单片机实际硬件结构建立I/O口变量名与其实际地址的联系,以便使用软件模拟51单片机的硬件操作31位变量(bit)及其Cx51定义bit类似于unsignedint等,用来说明变量类型一、定义位变量1、bitcheck_bit;/*将变量check_bit定义为位变量*/

32位变量总位于8051内部RAM中(*)

bdatabitdisplay_flag;/*正确*/ databitdisplay_flag;/*正确*/

idatabitdisplay_flag;/*正确*/ bitdisplay_flag;/*存储模式为small,正确*/

pdatabitdisplay_flag;/*错*/ staticbitdisplay_flag;/*正确*/ externbitdisplay_flag;/*正确*/ bit*bptr;/*错*/bitb_array[3];/*错*/注:位变量不能定义成一个指针和数组332、函数可包含类型为bit的参数,也可将其作为返回值

bitfunc(bitb0,bitb1) { …….. return(b1) }343、可位寻址对象指可以字节或位寻址的对象。该对象应位于89C52片内可位寻址RAM中。允许数据类型为idata的对象放入89C52片内可位寻址RAM区中。定义可分为两步:1)先定义变量的数据类型和存储类型(*)

bdata

int

ibase;

bdatacharbary[4];352)然后可使用sbit定义可独立寻址访问的对象位

sbitmybit0=ibase^0;

sbitmybit15=ibase^15;

sbitAry07=bary[0]^7;

sbitAry37=bary[3]^7;

对象ibase和bary也可以字节寻址

Ary37=0;/*位寻址*/bary[3]=‘a’;/*字节寻址*/注:1、Sbit定义要求基址对象的存储类型为bdata,否则只有绝对的特殊位(SFR中的位定义)定义是合法的。

2、位置(’^’操作符)后的最大值依赖于指定的基类型36例:判浮点数的符号为是否为正unionfloatlong{高地址

floatbdataf;longbdatal;}fl;低地址sbit

float_sign=fl.f^31;if(!float_sign)/*符号位为正*/{………….}else{………….}S

EE

M

M

M70373.3运算符、函数及程序流程控制C51的运算符C51的函数C51的流程控制语句C51的运算符1.C51的赋值运算符和算术运算符(+、-、*、/、%)2.C51的关系运算符(>、<、>=、<=、==、!=)3.C51逻辑运算符(||、&&、!)4.C51位操作运算符(~、|、&、︿、<<

、>>

)5.自增减运算6.复合运算符(10种)运算符、函数及程序流程控制3.3运算符、函数及程序流程控制

39C51的函数函数是C语言中的一种基本模块,一个C语言程序就是由若干个模块化的函数所构成的。

1.函数的分类从用户使用角度划分,函数分为标准库函数和用户自定义函数。用户自定义函数是指用户根据任务自己编写的函数。从函数定义的形式上可划分为三种形式:无参数函数、有参数函数和空函数。运算符、函数及程序流程控制3.3运算符、函数及程序流程控制

40C51的函数

2.函数的定义无参数函数的定义

返回值类型函数名()

{函数体语句}有参数函数的定义

返回值类型函数名(形式参数列表)

形式参数类型说明

{函数体语句}空函数的定义

返回值类型函数名()

{}运算符、函数及程序流程控制3.3运算符、函数及程序流程控制

41C51的函数

3.函数的参数和返回值形式参数和实际参数

形参:定义函数时,位于函数名后面圆括号中的变量名称为“形式参数”。

实参:调用函数时,主调用函数名后面括号中的表达式称为“实际参数”。参数的返回值

通过函数调用使主调用函数获得一个确定的值,这就是函数的返回值。函数的返回值是通过return语句获得的。运算符、函数及程序流程控制3.3运算符、函数及程序流程控制

42C51的函数

4.函数的调用调用的形式为:函数名(实际参数表列);

函数的调用方式有三种:

1.函数调用语句:即把被调用函数名作为调用函数的一个语句,如func()

2.被调用函数作为表达式的运算对象:如x=2*func(a,b)

3.被调用函数作为另一个函数的实际参数:如x=min(a,func(a,b));

运算符、函数及程序流程控制3.3运算符、函数及程序流程控制

43C51的函数

5.对被调用函数的说明

在调用一个函数之前,应对该函数的类型进行说明,即“先说明,后调用”。被调用函数必须是已经存在的函数(库函数或用户自定义函数)。6.函数变量的存储方式函数变量按其有效作用范围可划分为局部变量和全局变量。变量按其存储方式可分为四种存储种类,分别是自动变量(auto)、外部变量(extern)、静态变量(static)和寄存器变量(register),这些存储种类与变量的关系为:内部变量可定义为自动变量、静态变量或寄存器变量,外部变量可定义为全局变量或静态变量。运算符、函数及程序流程控制3.3运算符、函数及程序流程控制

44C51的流程控制语句C语言有三种基本结构:顺序结构、选择结构与循环结构。其中选择结构又派生出串行多分支结构和并行多分支结构,循环结构又分为“while”型循环结构和“dowhile”型循环结构。

运算符、函数及程序流程控制3.3运算符、函数及程序流程控制

顺序结构流程图

选择结构流程图

45C51的流程控制语句C语言有三种基本结构:顺序结构、选择结构与循环结构。其中选择结构又派生出串行多分支结构和并行多分支结构,循环结构又分为“while”型循环结构和“dowhile”型循环结构。

运算符、函数及程序流程控制3.3运算符、函数及程序流程控制

循环结构流程图

46C51的流程控制语句1.选择语句if

C语言提供了3种形式的if语句:

(1)if(条件表达式){语句;}

(2)if(条件表达式){语句1;}

else{语句2;}

(3)if(条件表达式1){语句1;}

elseif(条件表达式2){语句2;}

elseif(条件表达式3){语句3;}

elseif(条件表达式m){语句m;}

else{语句n;}

运算符、函数及程序流程控制3.3运算符、函数及程序流程控制

47C51的流程控制语句2.switch/case语句

该语句形式如下:

switch(表达式)

{

case常量表达式1:{语句1;}break;case常量表达式2:{语句2;}break;

……

case常量表达式n:{语句n;}break;

default:{语句n+1;}

}运算符、函数及程序流程控制3.3运算符、函数及程序流程控制

48C51的流程控制语句3.循环语句while语句

一般形式为:

while(条件表达式)

{

语句;/*循环体*/

}dowhile语句

一般形式如下:

do{

语句;/*循环体*/

}

while(条件表达式);运算符、函数及程序流程控制3.3运算符、函数及程序流程控制

49C51的流程控制语句3.循环语句

for语句

一般形式如下:

for([初值设定表达式];[循环条件表达式];[更新表达式])

{

语句;/*循环体*/

}运算符、函数及程序流程控制3.3运算符、函数及程序流程控制

503.4C51的构造数据类型数组结构联合枚举指针数组一维数组一维数组的定义方式

类型说明符数组名[整型表达式]初始化二维数组二维数组的定义方式

类型说明符数组名[常量表达式][常量表达式]二维数组的初始化C51的构造数据类型3.4C51的构造数据类型52结构结构的定义结构是结构是一种数据类型,通常定义结构数据类型后再用它去定义相关变量。定义结构类型的方法如下:

struct

结构名

{结构成员说明};

结构成员说明的格式为:

类型标识符成员名;用结构类型去定义变量的方法有三种:先定义结构类型再定义类型为该结构的变量定义结构类型的同时,定义该结构的变量直接定义结构类型变量结构变量的引用

引用的方式为:结构变量名.成员名

C51的构造数据类型3.4C51的构造数据类型53联合又称为共用体。它也是C语言中的一种构造数据类型。在一个联合中可以包含多个不同类型的数据元素。其定义格式为:

union联合类型名

{

类型说明符变量名;

};

联合与结构的区别在于:联合所包含的各个成员只能分时共享同一存储空间。定义联合类型变量的方法类似于定义结构变量,同样有三种。

引用联合成员的一般格式为:

联合变量名.联合元素或:联合变量名->联合元素C51的构造数据类型3.4C51的构造数据类型54枚举

枚举数据类型是一个有名字的某些整数型常量的集合。这些整数型常量是该类型变量可取的所有的合法值。枚举定义应当列出该类型变量的可取值。

定义枚举类型变量的一般格式为:

enum

枚举名{枚举值表列}变量表列;C51的构造数据类型3.4C51的构造数据类型55指针指针是C语言的一个重要概念,也是特色之一。使用指针可以有效地表示复杂的数据结构,直接处理内存地址,而且可以更有效地使用数组。

指针的概念变量的指针就是变量的地址

指针变量的定义

指针变量定义的一般形式如下:

类型标示符*指针变量名指针变量的引用

应注意的是:“*”在指针变量定义时和在指针运算时所代表的含义是不同的。在进行指针变量定义时,“*”是指针变量类型说明符。而在进行指针运算时,“*”是指针运算符,表示引用指针所指向的变量。C51的构造数据类型3.4C51的构造数据类型565.2.1指针的基本概念变量的指针就是变量的地址。指向变量的指针变量:若有一个变量专门来存放另一个变量的地址,则该变量称为指向变量的指针变量。1、指针变量的定义

类型标示符*指针变量名

例:int*ap

;/*定义ap为指针变量,指向整型变量*/572、指针变量的引用(*)

inta;

int*ap;

ap=&a;/*ap指向变量a,&为取地址符*/

指针运算符“*”,*ap和a等价*ap表示ap所指向的变量

x=*ap;/**ap所指向的变量赋值给x*/*ap=0xff;/*a=0xff*/58关于KEILC51的指针类型

支持“基于存贮器的”指针和“一般”指针两种类型。基于存贮器的指针在编译时一般被“行内”编码,无须库调用。即指针所指的对象所在的存储空间由定义时c源代码中的存储器类型决定。该指针只需1~2字节一般指针一般指针包括3个字节。2字节偏移(即指针的地址)和1字节存储器类型。为了表示这种指针必须用长整数来定义存贮类型。59指针定义(*)

staticdataunsignedchardata*标示符

autoidatachar

idataregisterpdataunsignedint

pdataexternxdata

int

xdata

code

unsingedlongcode

bdatalongbdatafloat

structunion60第二列指出指针变量存放在何处,缺省时决定于编译用存储模式第四列指明指针所指的对象存放在何处,缺省时为三字节的通用指针。611、基于存贮器的指针由C源代码中的存贮类型决定。用这种指针可高效访问对象且只需1至2字节1个字节idata*,data*,pdata*2个字节code*,xdata*例:charxdata*px

其中,xdata为指针指向的对象变量定位存储空间,指针长度为2个字节,所指的对象是个字符型,指针自身在默认存储器区(决定于编译模式)62charidata*px

;所指的对象变量在idata

中,指针为1个字节

datacharxdata*px;除指明指针所指对象在xdata中,还指明指针自身存放在data中

charxdata*datapx;与上式等价与早期C51版本兼容63例(*)

structtime{charhour;charmin;charsec;

structtimexdata*pxtime}

structtimeidata*px;

px->pxtime->hour=12;642、一般指针

即定义时未指明所指对象的存储空间共3字节:1个存放存储器类型,2个存放地址偏移量存储器类型偏移量高位偏移量低位低高指针的高位和低位地址偏移量65存储器类型编码(*)存储器类型idata/data/bdataxdatapdatacode值

0x000x010xFE0xFF66指针

对比一般指针和基于存储器的指针,可得出以下结论:基于存储器的指针长度短,运行速度快。而一般指针由于其所指对象变量的存储器空间位置只有在运行期间才能确定,编译器在编译期间无法优化存储方式,必须生成一般代码以保证能对任意空间的对象进行存取,所以一般指针所产生的代码运行速度较慢。一般指针可用于存取任何变量而不必考虑变量在AT89C52存储器空间的位置,函数可利用一般指针来存取位于任何存储空间的数据。因此一般指针的兼容性较好。而基于存储器的指针所指的对象有确定的存储器空间,因此缺乏兼容性。C51的构造数据类型3.4C51的构造数据类型67例:清零程序(将2000H—20FFH的内容清零)

★汇编语言程序

ORG0030HSE01:MOVR0,#00HMOVDPTR,#2000H;(0000H)送DPTRLOO1:CLRAMOVX@DPTR,A;0送(DPTR)INCDPTR;DPTR+1INCR0;字节数加1CJNER0,#00H,LOO1;不到FF个字节再清LOOP:SJMPLOOP清零程序(将2000H—20FFH的内容清零)

★C-51程序

#include<reg52.h>main(){

inti;unsignedcharxdata*p=0x2000;

/*指针指向2000H单元*/

for(i=0;i<256;i++){*p=0;p++;}/*清零2000H-20FFH单元*/

}69★汇编语言程序

ORG0030HL00:MOVR0,#10H;查找16个字节

MOVR1,#00HMOVDPTR,#2000HL11:MOVXA,@DPTRCJNEA,#00H,L16;取出内容与00H相等吗?INCR1;取出个数加1L16:INCDPTRDJNZR0,L11;未完继续

MOVDPTR,#2100HMOVA,R1MOVX@DPTR,A;相同数个数送2100HL1E:SJMPL1E例:查找零的个数(在2000H--200FH中查出有几个字节是零,把个数放在2100H单元中)★查找零的个数C-51程序#include<reg52.h>main(){unsignedcharxdata*p=0x2000;/*指针p指向2000H单元*/

intn=0,i;for(i=0;i<16;i++){if(*p==0)n++;/*若该单元内容为零,则n+1*/p++;/*指针指向下一单元*/}p=0x2100;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论