课程的基本要求课件

上传人:荷叶****8 文档编号:243139236 上传时间:2024-09-16 格式:PPT 页数:112 大小:1.10MB
返回 下载 相关 举报
课程的基本要求课件_第1页
第1页 / 共112页
课程的基本要求课件_第2页
第2页 / 共112页
课程的基本要求课件_第3页
第3页 / 共112页
点击查看更多>>
资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,课程的基本要求,通过本课程的学习,应该,掌握,C51,的程序设计语言;,掌握,8051,的中断、定时器,/,定位器、,串行通信等内部资源的,C,编程方法;,正确理解单片机的,C,语言模块化设计方法;,了解,8051,外部扩展资源的,C,程序设计方法。,单片机的,C,语言和程序设计,6.2 C,语言与,MCS-51,单片机,6.3 C51,运算符、表达式及其规则,6.4 C51,数据与运算,6.5 C51,函数,6.6,库函数简介,6.7 8051,内部资源的,C51,编程,6.1,概述,6.1,单片机的,C,语言和程序设计,对于,8051,及其兼容单片机,目前有四种语言支持:汇编语言、,BASIC,语言、,PL/M,语言和,C,语言。,C,语言是一种编译型程序设计语言,它兼顾了各种高级语言的特点,并具备汇编语言的功能。,与汇编语言相比,,C,语言有很多的优点:,不要求了解单片机的指令系统,仅要求对,8051,的存储器结构有初步了解;,寄存器分配,不同存储器的寻址及数据类型等细节可由编译器管理;,程序有规范的结构;,函数库提供很多的标准程序。,单片机的,C,语言和标准,C,语言的比较,C51,与标准的,C,语言定义的库函数不同,.,C51,中的数据类型和标准,C,的数据类型也有一定的区别,.,C51,变量与标准,C,中变量的存储模式不一样,.,C51,与标准,C,的输入,/,输出处理不一样,.,C51,与标准,C,语言在函数使用方面有一定的区别,.,学习重点,:,学习,C51,程序设计,重点掌握标准,C,语言和,C51,的区别,.,主要内容,:,C51,的数据类型和存储类型、,基本运算、构造数据类型、,函数以及程序设计中的其他一些问题等内容,.,6.2 C,语言与,MCS-51,单片机,6.2.1 C,语言编译器与程序开发过程,6.2.2 C51,程序结构,全局变量说明,/*,可被本程序的各函数引用*,/,函数,1,说明,函数,n,说明,主函数,main(),局部变量说明 *只能在本函数内引用*,执行语句,(,包括函数调用语句,)(,形式参数表,),函数,1(,形式参数说明,),局部变量说明 *只能在本函数内引用*,执行语句,(,包括调用其他函数语句,)(,形式参数表,),函数,n(,形式参数说明,),局部变量说明,执行语句,例,6.1,程序如下:,# include ,# include ,# define CON8279 XBYTE OX6EFF,# define uchar unsigned char,void INIT79(); /*8279,初始化*,/,void main(), uchar xdata *p;,uchar code TAB = 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,/* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 */,INIT79(),;,P=,While (1), while(IE1 = = 0);/*,等待键输入*,/,IE1=0,;,DAT8279=TAB*P,;,Void INIT79(void),CON8279=0xDC;,CON8279=0x10;,注释部份,/*,*/,这部分内容不会,被编译,也不被执行,编译预处理,程序编译、执行前系统,自动进行的特殊处理,特点:,以,#,开头,结束处无分号,#define CON8279 XBYTE,0x6EFF,#define,宏定义命令,CON8279,符号常量,0x6EFF,宏体(可以是一个表达式,如,3+4,),作用:用简单符号代表宏体部份内容,意义:直观,/,多次使用,/,便于修改,注意:,#define,可出现在程序的任一位置(作用范围:由此行到程序末尾),宏定义不是,C,语句,不必在行末加分号,否则会连分号一起置换。,#include ,标准方式,只按标准方式,(,系统存放,C,库函数头文件所在目录,),查找所要包含的文件,对,CX51,默认只在,C51include,目录下查找,#include “ ”,先在源文件所在目录找指定头文件,,若无再按标准方式找(更保险),小 结,CX51,语言程序的基本特点,CX51,语言是一种函数式语言,其程序基本组成是函数,每个,CX51,程序必须有一个、也只能有一个主函数,main,不管主函数在程序中的位置如何,程序执行总是从主函数开始,所有变量必须先定义(规定数据类型)后使用,每个语句必须用分号“,;”,结束(注意是“每个语句”而不“每行语句”),编译预处理命令不是语句(行末不能用分号结束),Cx51,语言本身没有输入,/,输出语句,其输入,/,输出功能须通过调用标准函数通过串行口实现,使用系统提供的标准库函数或其他文件提供的现成函数时,必须使用“文件包含”。,6.3 C51,运算符、表达式及其规则,6.3.1,算术运算符及表达式,1.,基本的算术运算符,C51,语言的算术运算符一共有,5,种:,+,加法运算符,减法运算符,* 乘法运算符,/,除法运算符,%,模(取余数)运算符,例:,14 % 4,= 0x02,2.,自增(,+ +,),自减()运算符,(,1,)当,+ + j,(或,j,)时,是先将变量,j,的值加,1,(或减小,1,),再取变量值;,(,2,)当,j + +,(或,j,)时,是先取变量值,,再把变量的值加,1,(或减,1,),例如:,int i, j, k;,i = 4,;,j = + + i,;,/ * j,值为,5,,,i,值也为,5*/,i = 5,;,k = i + +,;,/* k,值为,5,,,i,值为,6*/,3.,算术表达式及优先级和结合性,单目运算符优先级高于双目运算符,双目运算符优先级高于双目赋值运算符。,6.3.2,关系运算符、关系表达式,C51,语言共有,6,种关系运算符:,(小于),(大于), =,(大于等于),= =,(等于),! =,(不等于),6.3.3,逻辑运算符及表达式,C51,提供三种以逻辑量为操作数的逻辑运算符:,! 逻辑非,&,逻辑与,|,逻辑或,例如:若,a = 3,,,b = 4,则,!,a = 0 ,因为,a = 3,为非,0,数,即为逻辑,1,;,a | b = 1,因为,a,、,b,为非,0,数,是逻辑,1,;,a&b = 1,因为,a,、,b,为非,0,数,是逻辑,1,;,!,a&b = 0,因为!,a,优先于,&,。,6.3.4,位运算符及表达式,C51,语言提供,6,种位运算符,,所有的位运算符都是针对整型操作数,而不能针对实型数据。,&,按位与 (例:,char a=3,b=6;,则:,a&b = 2.,),|,按位或, 按位异或,按位取反,右移,左移,6,3,5,赋值运算符,赋值运算符,即是把运算符右侧操作数赋给左侧的操作数,。,即变量名,=,表达式,当“,=”,两侧类型不一致时,系统自动将右边表达式的值转换成左侧变量的类型,再赋给该变量,具体规则如下:,当整型变量,=,实型数据时,实数的小数部分被舍去;,当实型变量,=,整型数据时,变量中的数值为浮点形式;,当短字节整型变量,=,长字节整型数据时,,则长字节整型数据的低位数据赋给短字节整型变量,;,当长字节整型变量,=,短字节整型数据时,,则短字节整型数据赋给长字节整型变量的低位数据,而长字节整型变量的每一位高位数据被赋给短字节整型数据的符号值。,赋值语句,作用:使变量获得具体的运算值。,语句形式,变量名,=,表达式(常量、变量、函数、算式及其混合),;,lower =0;,/*,变量,lower,赋初值*,/,s=sin(x);,/*,求,sin(x)*/,注意:,函数,sin( ),在头文件,math.h,中定义。,所以程序开头处必须加上一行所谓“文件包含”:,#include ,变量赋初值亦可在数据类型定义时进行:,int lower =0, x;,把变量声明语句与赋值结合在一起的语句,术语上称为,“,初始化语句,”,。,2.,复合赋值运算符,凡是有两个运算对象的运算符都可以与赋值运算符“,=”,一起组成复合运算符。,复合赋值运算符有以下,10,种:,+=,,,- =,,*,=,,,/=,,,%=,,,=,,,&=,,,|=,,,=,。,例如:,a+=b,等价于,a = (a+b),a=4,等价于,a = (a4),6,4 C51,数据与运算,6,4,1,数据类型,数据类型,长度(,bit,),长度(,byte,),值域范围,位型,(bit),1,0,1,字符型,(char),Unsigned char (char),Signed char,8,8,1,1,0255,-128127,整型,(int),Unsigned int,Signed int (int),16,16,2,2,065535,-3276832767,长整型,(long),Unsigned long,Signed long,(long),32,32,4,4,04294967295,-214748836482147488,3647,浮点型,(float),Float,double,32,64,4,8,约,10,-38,10,38,约,10,-308,10,308,一般指针,24,3,存贮空间,065535,80C51,单片机采用哈佛结构,,RAM,与,ROM,分开,,SFR,与片内,RAM,统一编址。,KEIL CX51,编译器将变量、常量定义成不同的存储类型,(data, bdata, idata, pdata, xdata, code),的方法,将它们定位在不同的存储区中。,8051,的变量的存储类型定义为:,存储类别,变量类型,存储类型,变量名,其中存储种类与存储类型为可选项。,存储类别,主要有四种:自动(,auto,)(默认的存储种类)、外部(,extern,)、静态(,static,)和寄存器(,register,)。,存储类型,主要有:,data,,,bdata,,,idata,,,pdata,,,xdata,,,code,等。,6,4,2,变量及其数据类型,1,变量的说明,变量的格式如下:,存储类说明,类型说明符,修饰符,标识符,=,初值,其中, ,部分可有可无。,(,1,)类型说明符,(char,int,long,),(,2,)标识符,(,3,)变量初始化,(,4,)存储类说明符,a,auto,(自动存储类):堆栈,(,默认存储类),b,register,(寄存器存储类):,c,extern (,外部存储器类,),:,d,static,(静态存储类):,(,5,)修饰符,由于,8051,存储空间的多样性,,C51,提供了修饰存储空间,类型的修饰符,,用于指明定义的变量应分配在什么存储空间中。,C51,存储空间类型的修饰符有,data,,,idata,,,pdata,,,xdata,,,code,,,bdata,,,无修饰符时,取决于编译时选用的存储方式,存储类别,决定变量的,“,寿命,”,(何时,“,生,”,,何时,“,灭,”,),一个完整的变量说明格式如下:,存储类别 数据类型 存储类型 变量名,如,static int data x , y ;,C51,程序的存储类别有:, register,型(寄存器型),存取速度快,一般只允许,2,3,个,且限于,char,型和,int,型,通常用于循环变量。,auto,型(自动变量型),优点,同一内存区可被不同变量反复使用。,以上两种变量均属于“动态存储型”,即调用函数时才为这些变量分配单元,函数调用结束其值自动消失。,static,型(静态变量型),程序执行开始至结束,始终占用该存储空间,extern,型(外部变量型),同上,其值可供其他源文件使用,以上两种均属于“静态存储”性质,即从变量定义处开始,在整个程序执行期间其值都存在,。,从变量的存在时间来看,可分为静态存储变量和动态存储变量。,静态存储变量是指该变量在程序运行期间其存储空间不变,全局变量为静态存储变量;,动态存储变量是指该变量的存储空间不确定,在程序运行期间需要动态地为该变量分配存储空间,局部变量为动态变量。,变量的生存期,静态存储变量:,与程序,“,共存亡,”,动态存储变量:,与函数,“,共存亡,”,寄存器变量:,同动态变量,未说明存储类别时,,函数内定义的变量默认为,auto,型,函数外定义的变量默认为,extern,型。,2,变量的数据类型,对于,Franklin C51,编译器,只有,bit,和,Unsigned char,两种数据类型可以直接支持机器指令,,为了提高单片机的数据处理速度,在编制,C51,程序时一定要对变量和数据类型进行慎重的选择。,(,1,)位变量(,bit,),bit,是,C51,特有的数据类型,,其值为,: 1,(,ture,)或,0,(,false,)。,bit,类型可用的修饰符有,bdata,,,data,,,idata,,,但最好是,bdata,修饰符,例如:,bdata bit mark1,data bit mark2,idata bit mark3,(,2,)字符变量(,char,),字符变量的长度为一个字节,,标识符为,char,(,-128127,)或,unsigned char( 0-255,),,,(,3,)整型变量(,int,),整型变量(,int,)的长度为二个字节,,标识符为,int,,,unsigned int,,,。,0x78,0x56,。,整型变量值,0x5678,(,4,)长整型变量(,long int,),长整型变量的长度为四个字节,,标识符为,unsigned long, long,。,(,5,)浮点型变量 (,float,),浮点型变量长度为四个字节,,C51,的浮点变量数据类型格式具有,24,位精度,尾数的高位始终为,1,,,位的分布为:,1,位符号位,8,位指数位,23,位尾数位,例如:浮点型变量值,-12.5,的十六进制表示为,0xC1480000,地址,+0,0x00,+1,0x00,+2,0x48,+3,0xC1,.,。,6,4,4,数据的存储,1,存储类型与存储空间,存储类型,存储区,data,bdata,idata,pdata,Xdata,code,直接寻址片内数据存储区,,128,字节,,07FH,;访问速度快,存放常用变量或临时性递变量。,可位寻址片内数据存储区,,16,字节,,128,位,允许位与字节混合访问。,间接寻址片内数据存储区,,128,字节,,07FH,。,由,MOVX R0,,,MOVX R1,分页访问片外数据存储区,,256,字节,/,页;高,8,位地址保存在,P2,口中。,由,MOVX DPTR,访问片外数据存储区(,RAM,),,64K,,,00FFFFH,;存放不常用变量、等待发送或处理的数据。,由,MOVC A+DPTR,访问程序存储区(,ROM,或,EPROM,),,64K,,,00FFFFH,;存放指令代码和固定信息,片内数据存储区:,data,、,bdata,与,idata,当使用,data,与,bdata,存储类型定义时,,CX51,将它们定位在片内,RAM,。它存取数据快,但资源有限。,片内,RAM,存放临时性变量或使用频率较高的变量。,片外数据存储区:,pdata,与,xdata,pdata,能访问,1,页(,256,字节)的外部,RAM,,主要用于紧凑模式(,Compact Mode,)。,当使用,xdata,存储定义类型,其最大可寻址范围为,64K,。,程序存储区:,code,当使用,code,存储类型定义数据时,编译器会将其定义在代码空间(,ROM,或,EPROM,)。,如:,# define uchar unsigned char / *,定义符号常量,uchar * /,uchar data a1; /*,字符变量,a1,定位在,8051,的片内数据存,储区中*,/,bit bdata flag; /*,位变量,flag,定位在,8051,的片内数据存储,区中的可位寻址区*,/,float idata x, y; /*,浮点变量,x,,,y,定位在,8051,的片内数据,存储区并只能通过间接寻址来访问*,/,uchar xdata s = 3,4,7,2,12,8;,/*,无符号字符数组,s,定位在片外,RAM*/,uchar code table 10 = 0x3f, 0x06, 0x5b, 0x4f, 0x66,0x6d, 0x7d, 0x07, 0x7f, 0x6f ;,/*,无符号字符数组,table,定位在片外,ROM*/,2,存储模式,存储模式,说明,SMALL,COMPACT,LARGE,参数及局部变量放入可直接寻址的片内存储器,(,最大,128,字节,默认存储类型是,data),,因此访问十分方便。另外所有对象,包括栈,都必须嵌入片内,RAM,。栈长很关键,因为实际栈长依赖于不同函数的嵌套层数,参数及局部变量放入分页片外存储区,(,最大,256,字节,默认的存储类型,pdata),,通过寄存器,R0,和,R1(R0,,,R1),间接寻址,栈空间位于,8051,系统内部数据存储区中,参数及局部变量直接放入片外数据存储器,(,最大,64K,,默认存储类型为,xdata),,使用数据指针,DPTR,进行寻址。用此指针访问效率较低,这种访问机制直接影响代码长度,6,4,5 MCS-51,结构的,C51,定义,1,特殊功能寄存器,(SFR),的,C51,定义,sf r,特殊功能寄存器名“,=”,该特殊功能寄存器的地址常数 ”;”,例如:,sf r SCON = ox98; /*,串口控制寄存器地址,98H*,sf r TMOD = ox89,; *定时计数器控制寄存,器地址,89H*,2. I,0,口的,C51,定义,(1).,片内,I,O,口用关键字,sfr,定义。,例如:,sf r P1= 0x90; /*,定义,P1,口,地址,90H*,(2).,片外扩展,I,O,口的硬件译码地址,看作片外数据存储单元,用,#define,语句定义。,例如:,# include ,# define PORTA XBYTE0xffc0,;,/*,将,PORTA,定义为外部,I/O,口,地址为,0xffc0,,长度为,8,位*,3,特殊位,(sbit),的,C51,定义,(1),已定义的特殊寄存器名,基地址上特殊位的位置,(0,7),当特殊寄存器的地址为字节,(8,位,),时,可使用这种方法。,例如:,sfr PSW= 0xd0,;,/*,定义,PSW,寄存器地址为,0xD0*,sbit OV= PSW 2; /*,定义,OV,位为,PSW.2,地址为,0xD2*,sbit CY=PSW7,;,/*,定义,CY,位为,PSW.7,地址为,0xD7*,(2),寄存器基地址,基地址上特殊位的位置,(0,7),以,0x80,0xFF,之间、并能被,8,整除的整常数作为基地址。,例如;,sbit OV=0xD02,;,/*OV,位地址为,0xD2*,sbit CY=0xD07,;,/*CY,位地址为,0xD7*,(3)0x80,到,0xFF,之间的位绝对地址,例如:,sbit OV=OxD2,;,sbit CY=OxD7,;,在主程序前只要加上,#include,-,即包含对上述特殊寄存器的定义,4,对存储器和外部扩展,I/O,的绝对地址访问。,利用库函数中的绝对地址访问的头文件,absacc,h,可对不同区域的存储器和外部扩展,I,O,口进行访问。,该头文件中的函数有:,CBYTE,地址, (,访问,code,区字符型,),DBYTE,地址, (,访问,data,区字符型,),PBYTE,地址, (,访问,pdata,区或,I,O,口字符型,),XBYTE,地址, (,访问,xdata,区或,I,O,字符型,),例如:若有宏定义:,#define DAC0832 XBYTE0x7FFF,那么程序中,DAC0832,出现的地方,就是对地址为,7FFFH,的外部,RAM,单元或,I,O,口进行访问。,还有访问数据类型为,int,型的,4,个函数:,CWORD,、,DWORD,、,PWORD,和,XWORD,。,它们的访问区域同上。例如赋值语句:,XWORD0= 0x9988,;,例如,将内部,RAM 30H,单元的内容送,20H,单元的程序如下。,# include ,void main ( ),DBYTE 0X20 = DBYTE 0X30,;,例如:,CPU,片外,RAM,清零,ORG 0000H,LJMP MAIN ;,跳转到主程序,ORG 0030H,MAIN:MOV DPTR,#0000H;,送,RAM,地址,LOOP:MOVA,#00H;,MOVX DPTR,A;,往,RAM,存,00H,INCDPTR ;,地址加,1,MOVA,DPL ;,判断,RAM,地址是否已经到达尾地址,CJNEA,#00H,LOOP,MOVA,DPH,CJNEA,#20H,LOOP,WAIT:NOP;,循环等待,JMPWAIT,END,C,程序:,#include,#include,#define uchar unsigned char,#define uint unsigned int,void main(), uint i;,for ( i=0;i0x2000;i+);,XBYTEi = 0;,6.4.6 C51,的指针,6,.,4,.,6,.,1,指针的基本概念,1.,变量的地址,变量包含变量名和变量的值两个含义,前者为数据的标识(内存地址)后者为数据的内容。,即为它们所占连续的内存单元的最低字节单元的地址。,例如:,Long a = 0x12345678,;,单元地址,a,的单元,2001,78,2002,56,2003,34,2004,12,变量,a,的地址为,2001H,对于内存中变量的存取有两种方式,(1),直接存取,例如:,int a=10,根据变量名与内存单元地址的对应关系,,找到变量,a,在内存中的位置。,(2),间接存取,1000h,10,变量,a,1002h,2000h,1000,指针变量,a_pointer,例如要存取变量,a,时,要以将变量,a,的地址放入内存单元(假设放在,2000,、,2001,两个字节中,),,然后从地址,1000,、,1001,的两字节内存单元中存取变量的值,10,,在这里,存放在地址,2000,和,2001,内存中的,实际就是指向变量,a,的指针变量,a_pointer,。,2,指针变量的概念,变量的指针,简而言之即是变量的地址,对上面的变量,a,它的指针就是内存中存储地址,1000h,。,指针变量,是指专门用来存放另一个变量地址(指针)的变量,它的值是指针。,提到的地址,2000h,,,2001h,两字节中存放的变量,a_pointer,就是一个指针变量,它的值就是变量,a,的地址,1000h,。,(,1,)指针变量的定义,指针变量定义的一般形式为,存储类说明符,类型说明符,修饰符, ,指针定位修饰符,标识符, =,地址初始值, ,中的部分可有可无。,存储类说明符,类型说明符,:,与一般变量的说明相同。,修饰符是,:,为指针指向的对象定位存储空间的说明。,指针定位修饰符,:,是给指针本身定位所在存储空间,,一般不予以指定。,例如:,int,*a,类型说明符,标识符,Unsigned char,data,*,xdata,xx / *,外部,RAM,指针指向,内部,RAM,数据区,*,/,类型说明符,修饰符,指针定位修饰符,(,2,)指针变量的使用,1,),&,取地址运算符,当把某变量的地址赋给一个指针变量后,就是说该指针变量指向该变量,例如:,int a,,,*,pointer, b,;,pointer = &a,;,执行了,pointer =&a,语句后,指针,pointer,指向变量,a,,即指针变量,pointer,对应的内存单元中装入变量,a,对应的内存单元地址。,例如,pointer = 300,;是非法的。,2,),*,取指向运算符,即取指针变量所指向的变量的值。,例如:,b = *pointer,;,相当于,b = a,&,和,*,都是单目运算符,优先级相同,且结合顺序是自右至,左的,.,如,*,pointer,+,等价于,*,(pointer,+,),而不是,(*pointer),+,。,实际编程和运算中,变量地址和指针变量的地址是不可见的,变量,指针变量和内存单元地址三者间的对应关系是由编译器决定的,程序设计人员只是通过,&,和,*,运算符来使指针变量与变量建立起联系。,6. 6. 6. 4,指针与数组,1,数组指针和指向数组的指针变量,一般把数组的起始地址放到一个指针变量中去,因此,我们把数组的起始地址称为数组指针,。,而把一个存放数组起始地址的变量称作指向数组的指针变量。简称数组指针变量。,其定义格式如下:,类型说明符(,*,标识符), ,或,类型说明符(,*,标识符),例如,,int a20,;,/*,包含,20,个整型元素的数组,*,/,int *p,;,/*,指向整型数据的指针,*,/,把指针变量指向数组,表示方法为:,p = &a0,或,p = a,此时,p,为数组指针变量。,2,指针和一维数组,(1),一维数组的地址,一维数组在内存中的存放;从下标为,0,的元素开始,连续存放。下标为,0,的元素的地址即为整个数组的地址。,例如:,int a 4 = 0x5678,,,0x1234,,,0x5678,,,0x1234,;,单元地址,单元,200A,78,200B,56,200C,34,200D,12,200E,78,200F,56,2010,34,2011,12,数组,a,的地址为,a0,的地址,200A,。,(2),指针的使用,要用指针变量来处理一维数组只需将一维数组的地址赋给一个指针变量即可。,例如:,int *p,,,a4,;,p,a,;,*,数组,a,的地址赋给指针变量,p*/,即,p,指向了数组,a,,则,*,p = a 0 ,。,对指针变量,其算术运算的特殊性表现在:,1),只能加减,不能乘除。,2),当某指针变量指向一个数组时,对该指针变量加,l,则不管这个数组是什么数据类型,这个指针变量都指向数组的下一个元素,(,只要没越界,),。如:做完,p,+,运算后,,p,就指向数组,a,的下一个元素,即,a 1 ,。,数组元素的引用可以采用两种方法:下标法和指针法。,下标法:,例如:,int a 10 ,,,*,p,;,p,a,;,数组的第,n,个元素可表示为;,an,或,pn,指针法:,数组的第,n,个元素可表示为:,*,(a+n),或,*,(p+n),注意:数组名可看成是一个指针常量,其值不能改变。,例,6.2,用选择法对数组进行排序,(,从小到大,),。,方法思路,设数组长度为,5,,令,i,0,(,1,),.,寻找,a i ,及后面的元素中最小元素,,a k,;,(,2,),.,若,k,=,i,,转,(4),;,(,3,),.,若,k!,i,,交换,ai,与,ak,的值;,(,4,),. i,+,,若,i4,,转,(1),;否则结束。,main ( ),int a 5 = 15, 10, 2, -78, 5, i, k, j, temp;,for (i,0,;,i 4,;,i,+,),k,=,i,;,for (j = k+1,;,j5,;,j,+,) /* 1 ,步,*,/,if (aj ak ) k = j,;,if ( k !,i ) /* 3 ,步,*,/,temp,ai,;,ai = ak,;,ak,temp,;,for ( i = 0; i 5; i,+,),printf ( %5d, a i );,3,指针与二维数组,设有一个二维数组,a,,它有,3,行,4,列,定义为:,static int a 34 = 1,3,5,7,9,11,13,15,17,19,21,23;,对这个数组理解如下:,a,是数组名;数组包含,3,个元素:,a0,,,a1,和,a2,每个元素又是一个一维数组,包含,4,个元素,(4,列,),,如,a0,代表的一维数组又包含,4,个元素即:,a00,,,a01,,,a02,和,a03.,a,【0】,=,1,3,5,7,【1】,=,9,11,13,15,【2】,=,17,19,21,23,a0,代表第,0,行中第,0,列的地址,即,&a00,;,相应地,,a1=&a10,,,a2=&a20,。,&a23,a2+3,表示。,*(a+0)+1,&a01,*(a+1)+3,&a13,既然,a2+3,和,*,(a+2)+3,是元素,a23,的地址,,*(a2+3),或者,*,(*(a+2)+3),也就是元素,a23,的值。,例,6.3,用指针变量输出数组元素的值。,程序如下:,main( ),int a 22 = 3,,,4 , 5,,,6, * p;,for (p = a0; p a0 + 4; p,+,),printf (,“,%5d,”,*p);,4.,指针数组和指向指针的指针变量,(1),指针数组,其定义的一般形式是:,类型说明符,数组名,元素个数,例,6.4,用选择法对,10,个字符串排序。,程序如下:,#include,“,stdio,h,”,main ( ),char ch1081,*p10,*p1;/*p,指针数组,包含,10,个指针元素,*,int i,,,i,,,k,;,printf (Enter 10 strings: n);,for ( i=0,;,il0,;,i,+,) /*,输入,10,个字符串,*,/,gets (chi),;,for (n=0,;,n10,;,n,+,),*,使,p,的,10,个指针元素分别指向上面,10,个字符串,*,pn= ch n,;,for (i,0,;,i9,;,i,+,),k = i,;,for (j,i+1,;,j10,;,j,+,),if (strcmp (pj,,,pk)0) k = j,;,if (k!,i),p1,pk,;,pk,pi,;,pi=p1,;,for (i=0;i,p - num,,,p - eng,(2),指向结构体数组的指针变量,结构体指针除了可以指向结构体变量,还可以指向结构体数组。,例如:,struct student *p,,,stu220,;,p,stu2,*,p,指向结构体数组,stu2*,这样,p,指向数组,stu2,的第一个元素,stu20,,即,*,p,stu20,。此时若,p,+,,则,p,指向数组,stu2,的第二个元素,即,*,p=stu21,。,6,4,6,4 C51,的指针类型,C51,的指针类型,若未指定它所指向的对象的存储类型,则该指针变量被认为是一般指针;需占用,3,个字节,若指定了它所指对象的存储类型,则该指针变量被认为是基于存储器的指针。这种指针只需,12,个字节,(1),基于存储器的指针,基于存储器的指针是在说明一个指针变量时,指定它所指向的对象的存储类型。,例如:,char xdata * px,;,(2),一般指针,在函数调用中,函数的指针参数需要用“一般”指针。一般指针的说明形式为:,char *pz,;,这里没有指定指针变量,pz,所指向的变量的存储类型,,pz,处于编译模式默认的存储区,长度为,3,个字节,格式为:,地址,+0,+1,+2,内容,存储类型编码,高位地址偏移量,低位地址偏移量,其中,存储类型由编译模式决定,不同的存储区域的编码如下:,存储类型,idata,xdata,pdata,data,Code,编码值,1,2,3,4,5,例如:要将数值,0x41,写入地址为,0x8000,的外部数据存储器。,则这样写即可:,# include,XBYTE 0x8000 = 0x41,;,其中,XBYTE,是一个指针,它是在头文件,absacc,h,中定义的,定义如下:,# define XBYTE,(,unsigned char*,),0x20000L,),XBYTE,被定义为,(unsigned char*) 0x20000L,,为一般指针,其存储类型为,2,,即为,xdata,类型,偏移量是,0000,.,这样,,XBYTE,成为指向外部数据存储器的零地址单元的指针。而,XBYTE0x8000,则表示外部数据存储器的,0x8000,单元。,6.5 C51,函数,普通函数分为库函数和用户定义函数,6.5.1,函数的定义,1,无参数函数的定义方法,返回值类型标识符,函数名(),函数体,无参数函数一般不带返回值给调用函数,返回值类型设为,void,(即无类型),例,6.5,:设计一程序,延迟一段时间,,再顺序地将,P,1,、,0,P,1,、,7,,置,1,#include ,void delay (),int a = 10000;,while (- - a),;,void main ( ),char a = 1;,do ,P,1,= a;,a = a x ) a = y;,if ( z a ) a = z;,return(a);,形式参数也可以用下面的形式进行说明,int max ( int x , int y, int z), int a = x;,if ( yx ) a = y;,if ( za ) a = z;,return (a),6.5.2,函数的说明,1.,函数说明格式,在,C51,程序中,除主函数和库函数外,用户自定义的函数在被调用前都要进行说明。,作为规范化的,C51,程序:在主函数,main(),之前,应对自定义的函数要作原型说明,而在,main(),函数后进行被调用函数的定义性说明。,函数原型说明格式如下:,extern,类型说明符,标识符(形参表),reentrant using n,存储模式,函数定义性说明格式如下:,存储类说明符,类型说明符,标识符(形参表),reentrant interrupt m using n ,存储模式,函数体,在上面格式中, ,的内容不是必需的。,2.,函数说明,(1).,存储类说明符,extern,使用,extern,说明符的函数作用域是全程序存在的;在定义性说明时,在不加存储说明的情况下,函数的默认存储类特性为,extern,。,全局变量,有效作用范围:从定义变量位置开始直到本源文件结束,如果需要将全局变量的作用范围扩展至整个源文件,法,1,全部在源文件开头处定义,法,2,在引用函数内,用,extern,说明,法,3,在源文件开头处,用,extern,说明,【,例三,】,求程序运行结果,extern int x,y;,void main(void),unsigend int i, j;,i=x;,j=y;,int x=100,y=200;,结果:,i=100,j=200,去掉第一行试试,如果要将全局变量作用范围扩展到其他源文件,只需在使用这些变量的文件中对变量用,extern,加以说明。,file2.c,extern fun1 ( int x ) ; /*,定义外部函数,fun1() */,file3.c,extern fun2 ( int y ) ;,例,6.7,:外部函数,file1.c,extern fun1 ( ) , fun2 ( ) ; /*,说明本文件要用到,main ( ),其他文件中的函数。,*,/,fun1 ( a ) ;,fun2 ( b );,(2),类型说明符,所谓类型是指函数返回值的类型,unsigned char-,字符型,char-,字符型,unsigned int-,整型,int-,整型,unsigned long-,长整型,long-,长整型,float-,浮点型,struct-,结构体,union-,共用体,void-,无返回值,bit-,位变量,(3),函数标识符,函数标识符即函数名。,函数名() 带或不带返回值的函数。, *,函数名() 返回指针的函数。,(* 函数名)(,void,)定义带或不带返回值的无参数函数,指针。,(* 函数名)(形参表)定义带或不带返回值的有参数,函数指针, *,(* 函数名)(,void,)定义返回指针的无参函数指针, *,(* 函数名)(形参表)定义返回指针的有参函数指针,(,4,)形参表,形参表是传入函数的形式参数表,(,5,)附加修饰符部分,a. reentrant,使用这个修饰符说明该函数为再入函数。所谓再入函数就是允许被嵌套调用的函数。调用可发生在任何时候,即使是在中断过程中,在实时处理的应用问题中常常需要再入函数。,由于,MCS,一,51,缺乏合适的寻址方法,使用栈结构相对来说是必要的。因而应尽量少用再入函数。,定义一再入函数的语法如下:,返回值函数名,(,参数,),模式,reentrantinterrupt nusing n,例如:,int calc(char i, int b)reentrant ,int x,;,x=tablei,;,return(x * b),;,b. interrupt n,“interrupt”,后接一个,0,31,的常整数,不允许使用表达式。,中断不允许用于外部函数,它对函数目标代码的影响下:,*当调用函数时,,SFR,中的,ACC.B, DPH, DPL,和,PSW,(当需要时)入栈;,(,自动完成,),*,如不使用寄存器组切换,甚至中断函数所需的所有工作寄,存器(,Rn,)都入栈;,*函数退出前,所有的寄存器内容出栈;,*函数由,8051,控制命令“,RETI”,终止。,extern bit alarm;,int alarm_count;,void falarm(void) interrupt 1 using 3 ,alarm_count *= 2;,alarm = 1;,; FUNCTION falarm (BEGIN),0000 COEO PUSH ACC,0002 CODO PUSH PSW,; SOURCE LINE # 5,; SOURCE LINE # 6,0004 E500 R MOV A,alarm_count+01H,0006 25E0 ADD A,ACC,0008 F500 R MOV alarm_count+01H,A,000A E500 R MOV A,alarm_count,000C 33 RLC A,000D F500 R MOV alarm_count,A,; SOURCE LINE # 7,000F D200 E SETB alarm,; SOURCE LINE # 8,0011 D0D0 POP PSW,0013 D0E0 POP ACC,0015 32 RETI,; FUNCTION faiarm ( END),开发中断过程时有下列规则:,*不能进行参数传送;,*无返回值,如果想定义一个返回值将产生错误,,然而,如果返回整型值编译器将不产生错误信息;,*编译器会识别对中断过程的直接调用并拒绝它们;,*编译器从绝对地址,8n+3,处产生一个中断向量,,其中,n,为中断号,该向量包括一个到中断过程的跳转,;,*C-51,编译器允许,031,个中断,究竟允许哪些中断依赖于使用的,8051,系列芯片,编译器不能检查。下列中断及其相关地址为,8051,控制器所知:,0,:,EXTERNAL 0 0003H,1,:,TIMER,COUNTER,一,0 000BH,2,:,EXTERNAL 1 0013H,3,:,TIMER,COUNTER,一,1 001BH,4,:,SERIAL PORT 0023H,*,中断过程调用的函数所使用的寄存器组必须与中断过程相同,,当没有使用“,using”,指令时编译器会选择一个寄存器组作绝对寄存器访问,,当子程序使用另一寄存器组时会发生错误,用户必须保证按要求使用相应寄存器组,,C,编译器不会对此检查。,using n,8051,有,4,个寄存器组,每组有,8,个寄存器,R0 R7,。使用修饰符,using n,可以指定在本函数内部使用的寄存器组。其中,n,的取值为,0 3,,表示通用寄存器组号。,“,using”,不允许用于外部函数,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 教学培训


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!