第六章 单片机c语言程序设计概述(单片机课件)_第1页
第六章 单片机c语言程序设计概述(单片机课件)_第2页
第六章 单片机c语言程序设计概述(单片机课件)_第3页
第六章 单片机c语言程序设计概述(单片机课件)_第4页
第六章 单片机c语言程序设计概述(单片机课件)_第5页
已阅读5页,还剩52页未读 继续免费阅读

下载本文档

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

文档简介

教学基本要求:(1)、熟悉支持80C51单片机的几种编程语言及各自特点;(2)、熟悉Cx51程序结构及开发过程 ;(3)、熟悉Cx51的数据类型及存储模式;(4)、掌握80C51特殊功能寄存器(SFR)的Cx51定义;(5)、掌握80C51并行接口及Cx51定义;(6)、掌握80C51位变量及Cx51定义;(7)、掌握Cx51运算符、表达式及其规则;(8)、熟悉Cx51流程控制语句;(9)、掌握Cx51构造数据类型;(10)、掌握Cx51函数。,第一部分 单片机C语言程序设计概述,教学重点:(1)、 Cx51的数据类型及存储模式;(2)、 80C51特殊功能寄存器(SFR)的Cx51定义;(3)、 80C51并行接口及Cx51定义;教学难点:(1)、 Cx51构造数据类型;(2)、 Cx51函数;,一、80C51单片机的编程语言,四种语言支持80C51,即:汇编,PL/M,C和BASIC。1、 BASIC: 非常容易学。根据解释的行就可以找到错误,而不是当程序执行完才能显示,由于逐行解释所以很慢,每一行必须在执行时转换成机器代码,需要花费很多时间,不能做到实时性。只适用于要求编程简单而对编程效率或运行速度要求不高的场合。 2、 PL/M: 是Intel从8080微处理器开始为系列产品开发的编程语言,是一种结构化语言,但它使用关键字去定义结构。它能产生紧凑代码。总的来说是“高级汇编语言”,可详细控制代码的,生成。但对于8051系列,它不支持复杂的算术运算,浮点变量,也没有丰富的库函数支持。3、汇编语言: 用汇编程序设计MCS51系列单片机应用程序时,必须要考虑其存储器结构,尤其必须考虑其片内数据存储器与特殊功能寄存器正确、合理的使用以及按实际地址处理端口数据。当设计一个小的嵌入式系统时,一般我们都用汇编语言。在很多工程中这是一个很好的方法,因为代码一般都不超过8K 而且都比较简单。如果硬件工程师要同时设计软件和硬件经常会采用汇编语言来做程序。使用汇编的麻烦在于它的可读性和可维护性,特别当程序没有很好的标注的时候,代码的可重用性也比较低。,4、C语言: C语言是一种源于编写UNIX操作系统的语言,是一种结构化语言,可产生紧凑代码。优点如下: 1)对单片机指令系统不要求了解,仅要求对8051存储器结构有初步了解; 2)寄存器的分配,不同存储器的寻址及数据类型等细节可由编译器管理; 3)程序有规范的结构,分为不同的函数,使程序结构化; 4)更符合人们的思考习惯;改善了程序的可读性; 5)编程及程序调试时间显著缩短,从而提高效率; 6)提供的库包含许多标准子程序,具有较强数据处理能力;,7)很好的结构性和模块化更容易阅读和维护,而且由于有更好的可移植性很多处理器支持C编译器。 用C语言编写MCS51单片机的应用程序,虽然不像用汇编语言那样具体地组织、分配存储器资源和处理端口数据,但在C语言编程中,对数据类型与变量的定义,必须要与单片机的存储结构相关联,否则编译器不能正确地映射定位。 用C语言编写单片机应用程序与编写标准的C语言程序的不同之处就在于根据单片机存储结构及内部资源定义相应的C语言中的数据类型和变量,其它的语法规定、程序结构及程序设计方法都与标准的C语言程序设计相同。,二、Cx51程序结构及开发过程 Cx51源程序是一个ASCII文件,可以用任何标准的ASCII文件编辑器来编写,如:写字板,记事本等。 Cx51程序机构与一般C语言没有什么差别,程序的书写格式自由度高,灵活性强,有较大的任意性。 要点如下: 1)一般情况下,每个语句占用一行。 2)不同结构层次的语句,从不同的起始位置开始,即在同一结构层次中的语句,缩进同样的字数。 3)表示结构层次的大括号通常写在该结构语句第一字母的下方,与机构化语句对齐,并占用一行。,Cx51源程序大体上是一个函数定义的集合,集合中仅有一个名为main的主函数。主函数是程序的入口,主函数中所有语句执行完毕,则程序执行完成。 函数定义由类型,函数名,参数表和函数体组成。 格式如下: 类型 函数名(参数表) 参数说明; 数据说明部分; 执行语句部分; ,Cx51程序结构说明: 1)C语言是由函数构成的。 一个C源程序至少包含一个函数,也可以包含一个vmain函数和若干其他函数。函数是C程序的基本单位。 2)函数分为2大类: 一类是库函数,一类是用户自定义函数。库函数是Cx51在库文件中已定义的函数,其函数说明在其头文件中。用户函数是用户自己定义,自己调用的一类函数。 3)函数由2部分组成: 函数说明部分:它包括函数名,函数类型,函数属性,函数参数名和形式参数类型。一个函数名后面必须跟一个(),函数参数可以没有。,函数体: 函数说明部分下面的大括号内的内容。函数体一般包括:变量定义和执行部分(由若干语句组成). 4) 一个Cx51程序总是从main 函数开始执行的,而不论main函数在整个程序中的位置如何。 5)每个语句和数据定义的最后必须有一个分号。 6)C语言本身没有输入/输出语句,输入和输出操作是有库函数scanf和printf等函数来完成的。 7)可以用/*/对C程序中的任何部分作注释。,三、Cx51数据与运算 1、 Cx51数据类型,在编程时,为了书写方便,经常用简化的缩写形式来定义数据类型。其方法是在源程序开头使用#define语句自定义简化的类型标识符。 例如: #define uchar unsigned char #define uint unsigned int 这样,在编程中,就可以用uchar代替unsigned char,用uint代替unsigned int来定义变量。,2、Cx51数据的存储类型与8051存储结构 KEIL Cx51完全支持8051单片机的硬件结构,可以完全访问8051硬件系统的所有部分。该编译器通过将变量、常量定义成不同的存储类型的方法,将他们定义在不同的存储区中。,带存储类型的变量的定义的一般格式为 数据类型 存储类型 变量名变量存储类型定义举例:Char data var1; /* var1定位在内部RAM*/Bit bdata flags; /* flags定位在内部RAM的位寻址区*/Float idata x,y,z; /*变量定位在内部RAM,但只能采用间 址寻址方式*/Unsigned int pdata i; /*无符号整型变量i定位在外部 RAM,并用MOVX Ri访问*/Unsigned char xdata v1044; /*无符号三维数组变 量, 定位在外部RAM,并占据104 4=160字节存储空间*/,如果定义时略去存储类型标志符,编译器会自动选择默认的类型,由SMALL,COMPACT和LARGE存储模式指令限制。,3、80C51特殊功能寄存器(SFR)的Cx51定义 80C51单片机中,地址范围为80HFFH的单元为SFR寄存器。 为了能直接访问这些SFR,KEIL Cx51提供了一种自主形式的定义方法,这种定义方法与标准C语言不兼容,只适用于对8051系列单片机进行C语言编程。 特殊功能寄存器C51定义的一般语法格式如下:sfr sfr_name =int constant; “sfr”是定义语句的关键字,其后必须跟一个80C51单片机真实存在的特殊功能寄存器名,“=”后面必须是一个整型常数,不允许带有运算符的表达式,是特殊功能寄存“sfr_name”的字节地址,这个常数值的范围必须在SFR地址范围内,位于0x800xFF。,例如:sfr SCON=0x98;/* 串口控制寄存器地址98H */sfr TMOD=0x89;/* 定时/计数器方式控制寄存器地址89H */ 80C51系列单片机的特殊功能寄存器的数量与类型不尽相同,因此建议将所有特殊的“sfr”定义放入一个头文件中,该文件应包括MCS-51单片机系列机型中的SFR定义。 C51编译器的“reg51.h”头文件就是这样一个文件。 对于位寻址的SFR中的位,C51的扩充功能支持特殊位的定义,像SFR一样不与标准C兼容,使用sbit来定义位寻址单元。,第一种格式: sbit bit-name = sfr-nameint constant; “sbit”是定义语句的关键字,后跟一个寻址位符号名(该位符号名必须是80C51单片机中规定的位名称),“=”后的“sfr-name”必须是已定义过的SFR的名字,“”后的整常数是寻址位在特殊功能寄存器“sfr-name”中的位号,必须是07范围中的数。 例如: sfr PSW=0xD0 ; /* 定义PSW寄存器地址为D0H */ sbit OV=PSW2 ; /* 定义OV位为PSW.2,地址为D2H */ sbit CY=PSW7 ; /* 定义CY位为PSW.7,地址为D7H */,第二种格式: sbit bit-name =int constantint constant; “=”后的int constant为寻址地址位所在的特殊功能寄存器的字节地址,“”符号后的int constant为寻址位在特殊功能寄存器中的位号。 例如: sbit OV=0XD02 ;/* 定义OV位地址是D0H字节中的第2位 */ sbit CY=0XD07 ;/* 定义CY位地址是D0H字节中的第7位 */,第三种格式: sbit bit-name = int constant; “=”后的int constant为寻址位的绝对位地址。 例如: sbit OV=0XD2 ;/* 定义OV位地址为D2H */ sbit CY=0XD7 ;/* 定义CY位地址为D7H */ 特殊功能位代表了一个独立的定义类,不能与其它位定义和位域互换。,4、80C51并行接口及Cx51定义 80C51系列单片机并行I/O接口除了芯片上的4个I/O口(P0 P3)外,还可以在片外扩展I/O口。 80C51单片机I/O口与数据存储器统一编址,即把一个I/O口当作数据存储器中的一个单元来看待。 使用C51进行编程时,80C51片内的I/O口与片外扩展的I/O可以统一在一个头文件中定义,也可以在程序中(一般在开始的位置)进行定义,其定义方法如下: 对于80C51片内I/O口按特殊功能寄存器方法定义。 例如:sfr P0=0x80 ; /* 定义P0口,地址为80H */sfr P1=0x90 ; /* 定义P1口,地址为90H */,对于片外扩展I/O口,则根据硬件译码地址,将其视作为片外数据存储器的一个单元,使用#define语句进行定义。 例如: #include #define PORTA XBYTE 0xFFC0 absacc.h是C51中绝对地址访问函数的头文件,将PORTA定义为外部I/O口,地址为 FFC0H,长度为8位。 一旦在头文件或程序中对这些片外I/O口进行定义后,在程序中就可以自由使用变量名与其实际地址的联系,以便使程序员能用软件模拟MCS-51的硬件操作。,5、80C51位变量及Cx51定义 使用C51编程时,定义了位变量后,就可以用定义了的变量来表示80C51的位寻址单元。 位变量的C51定义的一般语法格式如下: 位类型标识符(bit) 位变量名; 例如:bit direction_bit ;/* 把direction_bit定义为位变量 */bit look_pointer ;/* 把look_pointer定义为位变量 */,四、 Cx51运算符、表达式及其规则,1、算术运算符及其表达式 1)基本的5种算术运算符: + 加法运算符或正值运算符 - 减法运算符或负值运算符 * 乘法运算符 / 除法运算符 % 模运算符或称求余运算符 2)算术表达式和运算符的优先级与结合性 3)如何在各类型的数据之间进行混合运算,2、关系运算符及其表达式 1)六种关系运算符 , =, = =, != 2)优先级, = 优先级相同(高)= =, != 优先级相同(低) 3)结合性:左结合3、逻辑运算符及其表达式 1)三种逻辑运算符 & | ! 2)优先级!优先级最高算术运算关系运算再次之&和 | 赋值运算优先级最低 3)结合性:从左向右,4、位运算及其表达式 1)位运算符 &, | 位运算符只能是整型或字符型数,不能为实型数据。5、自增减运算符、复合运算符极其表达式 1)自增减运算符: +i, -i 在使用i之前,先使i值加(减)1; i+,i- 在使用i之后,再使i值加(减)1。6、复合的赋值运算符 定义:在赋值运算符之前加上其它运算符。 +=、-=、*=、/=、%=、=、=、&=、 =、|= ,,3种基本结构组成:顺序结构、选择结构、循环结构。1、顺序结构 程序中的语句按先后顺序逐条执行。2、选择结构 在执行程序中的选择结构语句时,该语句的执行将根据不同的条件执行不同分支的语句。常用语句:if,else if语句,五、 Cx51流程控制语句,3、循环结构 程序中的语句按先后顺序逐条执行。 1)当(while)型循环 该循环的特点是:当条件满足时,就执行循环体,否则就退出循环结构。 2) 直到(do while)型循环 该循环的特点是:先执行循环体,再判断循环条件,条件不满足时,就退出循环结构。,选择语句: 1、if语句 if语句是根据所给定的条件决定执行的操作,是“二选一”的分支结构。If 语句的一般格式为: if (表达式) 语句序列1; else 语句序列2; ,if 语句的嵌套单条件选择 if 语句完整的嵌套格式为: if(表达式1) if(表达式2) 语句序列1 ; else 语句序列2 ; else if(表达式3) 语句序列3 ; else 语句序列4 ;,2、开关分支switch语句 C语言提供了switch多路选择语句。格式如下: switch(表达式) case 常量表达式1 : 语句组1 ; case 常量表达式2 : 语句组2 ; case 常量表达式n : 语句组n ; default : 语句组n+1 ; ,循环语句 1、while语句 while语句用来实现“当型”循环结构。 1)while语句的一般格式 while语句是一个循环控制语句,用来控制程序段的重复执行。其一般格式为: while(表达式) 循环体 ; 格式中的循环体,可以是单个语句、空语句,也可以是复合语句。说明:如果循环体包含一个以上的语句,就构成块语句,应该用花括号 括起来。,2、do while语句 C语言中,用do while语句构成直到型循环结构。 do while语句的一般格式 do while语句也是一个循环控制语句。其特点是先执行循环体,然后判断条件是否成立。其一般格式为: do 循环体 while(表达式) ; 说明:循环体至少执行一次。当循环体有多个语句时必须加花括号 。,3、for 语句 for语句可以用于循环次数已经确定的情况,还可用于循环次数不确定而只给出循环结束条件的情况。for语句的一般格式 for语句的一般格式为: for (表达式1 ; 表达式2 ; 表达式3) 循环体,一个循环体内包含另一个完整的循环结构,称为循环的嵌套。循环之中还可以套循环,称为多层循环。三种循环(while循环、do while循环和for循环)可以互相嵌套。例如: while( ) for ( ) ,break语句和continue语句 1、break语句 break语句可以用在循环语句和switch语句中。在循环语句中用来结束内部循环;在switch语句中用来跳出switch语句。 2、continue语句 continue语句的作用是结束本次循环,忽略continue后面的语句,进行下一次循环判定。,六、 Cx51构造数据类型,1、数组和数组单元的基本概念 1)数组 将一组排列有序的、个数有限的变量作为一个整体,用一个统一的名字来表示,则这些有序变量的全体称为数组;或者说,数组是用一个名字代表顺序排列的一组数,顺序号就是下标变量的值。 2)数组单元 在同一数组中,构成该数组的成员称为数组单元(或数组元素、下标变量)。C语言中,引用数组中的某一单元,要指出数组名和用括号括起来的数组单元在数组中的位置(顺序号)的下标。例如:a3 代表a数组中顺序号为3的那个单元。,3)数组的维数 下标变量中下标的个数称为数组的维数。 具有一个下标的下标变量,构成一维数组。 具有两个下标的下标变量,构成二维数组。 依次类推,三个下标的下标变量,构成三维数组。 有多少个下标的下标变量,就构成多少维的数组。通常把二维以上的数组称为多维数组。 4)一维数组的定义、引用、初始化 一维数组的定义 一维数组用一个统一的标识符,即数组名来标识一组变量(也称元素),用下标来指示数组中元素的序号。当数组中每个元素只带有一个下标时,此数组称为一维数组。,一维数组的引用 使用数组必须先定义,后引用。 引用时只能对数组元素引用,如a0,ai,ai+1等,而不能引用整个数组。 在引用时应注意以下几点: (1) 由于数组元素本身等价于同一类型的一个变量,因此,对变量的任何操作都适用于数组元素。 (2) 在引用数组元素时,下标可以是整型常数或表达式,表达式内允许变量存在。在定义数组时下标不能使用变量。 (3) 引用数组元素时下标最大值不能出界。,一维数组的初始化 利用赋值语句或输入语句给数组元素赋值。C语言还允许在定义数组时对各数组元素指定初始值称为数组初始化。 (1)数组初始化形式1 例如:将括号内整型数据0,1,2,3,4分别赋给整型数组元素a0,a1,a2,a3,a4。 可以写为下面的形式: int a5=0, 1, 2, 3, 4 ; (2)数组初始化形式2 例如:对a数组中所有元素赋初值0。可以写作下面的形式: int a 10=0 ;,(3)通过赋初值定义数组大小 例如: int a =1, 2, 3, 4, 5 ; 等价于:int a5=1, 2, 3, 4, 5 ; 5)字符数组 字符数组是用来存放字符的数组,字符数组中的一个元素存放一个字符。 字符数组的定义、引用、初始化 对字符数组赋值或数组初始化时,数据使用字符型数据或相应的ASCII码值。 字符串与字符型数组 字符串(也称字符串常量)是用双引号括起来的若干有效字符序列。在C语言中,字符串可以包含字母、数字、转义字符等。,2、指针的基本概念。 指针就是变量的地址。与此对应,在C语言中使用一类专门的变量指针变量来存放变量的地址。也就是说,指针变量是存放地址数据的变量。 地 指针变量 变量地址(指针) 址 指 存 向 入 变量 变量值 指 针 变 量,变量的指针就是变量的地址。 存放变量地址的变量是指针变量,用来指向另一个变量。 1)定义一个指针变量 如何定义一个指针变量 形式:基类型 *指针变量名 例如:float *pointer_3; char *pointer_4; 2)指针变量的引用 指针变量中只能存放地址(指针)。 3)指针变量作为函数参数 函数的参数可以是整型、实型、字符型等数据,还可以是指针类型的。它的作用是将一个变量的地址传送到另一个函数中。,3、结构体 在程序设计中,把一些关系密切而数据类型不同的数据组织在一起,并为其命名一个名字,这类数据称为结构体。 结构体,是将若干个类型相同或不同的数据组合成一个有机的集合。 1)结构体类型定义 使用结构体变量前,要先定义该结构体类型,再定义结构体变量。 结构体类型定义的一般格式为:,struct 结构体名 类型标识符 成员名列表 ; 类型标识符 成员名列表 ; 类型标识符 成员名列表 ; ;,2)结构体变量的定义、引用和初始化 1结构体变量定义 定义结构体变量有三种方法。 (1) 在定义结构体类型的同时定义结构体变量。 (2) 先定义结构体类型,再定义结构体变量。 (3) 直接定义结构体变量。 2结构体变量的引用 对结构体变量进行操作时,除了可以对相同类型的结构体变量进行整体赋值外,不可以对一个结构体变量整体赋值。 3结构体变量的初始化 与数组的初始化类似,结构体变量只能对外部和静态结构体变量初始化。初始化数据之间要用“,”隔开,不进行初始化的成员项要用“,”跳过。,七、 Cx51函数,所有的函数在定义时都是相互独立的,一个函数中不能再定义其他函数,即函数不能嵌套 定义,但可以互相调用。 函数调用的一般规则是:主函数可以调用其它普通函数。普通函数之间也可以互相调用,但普通函数不能调用主函数。 一个c程序的执行从main()函数开始,调用其它函数后返回到主函数main()中,最后 在主函数Main()中结束整个c程序的运行。,1、函数的分类 从用户的使用角度分为:库函数和用户自定义函数. 1)标准库函数:C语言提供了丰富的标准函数,即库函数。 (1)数学函数 调用数学库函数时,要求程序在调用数学库函数前应包含下面的头文件: # include math.h (2)字符函数和字符串函数 调用字符函数时,要求程序在调用字符函数前应包含下面的头文件: # include ctype.h 调用字符串函数时,要求在源文件中应包含下面的头文件: # include string.h,(3)输入输出函数 调用输入输出函数时,要求在源文件中应包含下面的头文件 # include stdio.h (4)动态分配函数和随机函数 调用动态分配函数和随机函数时,要求在源文件中应包含下面的头文件: # include stdlib.h“ 2)用户自定义函数 由用户编写的函数称为自定义函数。 从函数定义的形式上分:,(1)无参数函数: 调用时,无参

温馨提示

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

评论

0/150

提交评论