




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、2022-4-141项目项目4 4 单片机的单片机的C51C51语言基础语言基础本章要点本章要点v 了解C51的数据类型v 掌握掌握顺序结构、选择结构、循环结构的C程序的构成及编程技巧v 了解C51的运算符、表达式及其规则v 掌握掌握数组的定义和使用、指针的定义和使用、函数的定义和使用2022-4-1422022-4-1434.1 4.1 任务任务1 1 认识单片机的认识单片机的C C语言语言v4.1.1 C51程序开发概述程序开发概述v 1.采用采用C51的优点的优点v 2.C51程序的开发过程程序的开发过程v4.1.2 C51程序结构程序结构v C51程序结构同标准C一样,是由若干个函数构
2、成的,每个函数即是完成某个特殊任务的子程序段。组成一个程序的若干个函数可以保存在一个或几个源文件中,最后再将它们连接在一起。C语言程序的扩展名为“.c”,如my_test.c。v 2022-4-144C语言的语句规则:语言的语句规则: v 每个变量必须先说明后引用,变量名英文大小写是有差别的。v C语言程序一行可以书写多条语句,但每个语句必须以“;”结尾,一个语句也可以多行书写。 v C语言的注释用/*/表示。 v “”花括号必须成对,位置随意,可在紧挨函数名后,也可另起一行,多个花括号可以同行书写,也可逐行书写,为层次分明,增加可读性,同一层的“”花括号对齐,采用逐层缩进方式书写。2022-
3、4-1454.2 任务任务2 认识认识C51的数据类型的数据类型v4.2.1 C51的标识符和关键字的标识符和关键字v4.2.2 数据与数据类型数据与数据类型v4.2.3 C51数据的存储类型数据的存储类型v4.2.4 80C51硬件结构的硬件结构的C51定义定义2022-4-1464.2.1 C51的标识符和关键字的标识符和关键字v 标识符标识符是一种单词,它用来给变量、函数、符号常量、自定义类型等命名。用标识符给C语言程序中各种对象命名时,要用字母、下划线和数字组成的字符序列,并要求首字符是字母或下划线,不能是数字。v 关键字关键字是一种已被系统使用过的具有特定含义的标识符。用户不得再用关
4、键字给变量等命名。C语言关键字较少,ANSI C标准一共规定了32个关键字,见表4-1母的大小写是有区别的。2022-4-147关 键 字用 途说 明auto存储种类说明用以说明局部变量,缺省值为此break程 序 语句退出最内层循环case程 序 语句Switch语句中的选择项char数据类型说明单字节整型数或字符型数据const存储种类说明在程序执行过程中不可更改的常量值continue程 序 语句转向下一次循环default程 序 语句Switch语句中的失败选择项do程 序 语句构成 dowhile循环结构double数据类型说明双精度浮点数else程 序 语句构成 ifelse选择结
5、构e n um数据类型说明枚举类型extern存储种类说明在其他程序模块中说明了的全局变量float数据类型说明单精度浮点数for程 序 语句构成for循环结构goto程 序 语句构成goto转移结构if程 序 语句构成 ifelse选择结构int数据类型说明基本整型数long数据类型说明长整型数register存储种类说明使用CPU内部寄存器的变量return程 序 语句函数返回short数据类型说明短整型数signed数据类型说明有符号数,二进制数据的最高位为符号位sizeof运算符计算表达式或数据类型的字节数static存储种类说明静态变量struct数据类型说明结构类型数据switch
6、程 序 语句构成Switch选择结构typedef数据类型说明重新进行数据类型定义union数据类型说明联合类型数据unsigned数据类型说明无符号数数据void数据类型说明无类型数据volatile数据类型说明该变量在程序执行中可被隐含地改变while程 序 语句构成while和dowhile循环结构2022-4-148关 键 字用 途说 明bit位标量声明声明一个位标量或位类型的函数sbit位变量声明声明一个可位寻址变量sfr特殊功能寄存器声明声明一个特殊功能寄存器(8位)sfr16特殊功能寄存器声明声明一个16位的特殊功能寄存器data存储器类型说明直接寻址的8051内部数据存储器bd
7、ata存储器类型说明可位寻址的8051内部数据存储器idata存储器类型说明间接寻址的8051内部数据存储器pdata存储器类型说明“分页”寻址的8051外部数据存储器xdata存储器类型说明8051外部数据存储器code存储器类型说明8051程序存储器interrupt中断函数声明定义一个中断函数reetrant再入函数声明定义一个再入函数using寄存器组定义定义8051的工作寄存器组Keil C51编译器扩展关键字编译器扩展关键字4.2.2 数据与数据类型数据与数据类型v 数据:具有一定格式的数字或数值。数据是计算机的操作对象。不管使用任何语言,任何算法进行程序设计,最终在计算机中运行的
8、只有数据流。v 数据类型:数据的不同格式叫数据类型。v 数据结构:数据按一定的数据类型进行排列、组合及架构称为数据结构。v 程序设计中用到的数据都存储在存储单元中,在汇编语言中我们可以用DB或DW伪指令来定义存放数据的存储单元;在C51中,编译系统要根据定义的数据类型来预留存储单元,这就是定义数据类型的意义。C51提供的数据数据结构是以数据类型的形式出现的,C51的数据类型如表4-3所示2022-4-149表4-3 C51的数据类型2022-4-14104.2.3 C51数据的存储类型数据的存储类型v C51是面向80C51系列单片机的程序设计语言,应用程序中使用的任何数据(变量和常数)必须以
9、一定的存储类型定位于单片机相应的存储区域中。C51编译器支持的存储类型如表4-4所示。v 表4-4 C51的存储类型与8051存储空间的对应关系2022-4-1411v 如果用户不对变量的存储类型进行定义,C51的编译器采用默认的存储类型。默认的存储类型由编译命令中存储模式指令限制。C51支持的存储模式如表4-5所示。例如:v Char var ; /*在 small模式中,var定位data存储区*/v /*在 compact模式中,var定位pdata存储区*/v /*在 large模式中,var定位xdata存储区*/v v 表4-5 C51存储模式2022-4-1412v v 在kei
10、l C51 uVision3平台下,设置存储模式的界面如图4-2所示,步骤:工程建立好后,使用菜单Project|Option for Target Target1即出现图4-2所示工程对话框,点击Target标签,其中的Memory Model用于设置RAM的使用情况,有3个选项: small是所有的变量都在单片机的内部RAM中;Compact变量存储在外部RAM里,使用8位间接寻址;large变量存储在外部RAM中,使用16位间接寻址,可以使用全部外部的扩展RAM。2022-4-14134.2.4 80C51硬件结构的硬件结构的C51定义定义v C51是适合于80C51单片机的C语言。它对
11、标准C语言(ANSI C)进行扩展,从而具有对80C51单片机硬件结构的良好支持与操作能力.v1.特殊功能寄存器的定义特殊功能寄存器的定义v 80C51单片机内部RAM的80HFFH区域有21个特殊功能寄存器,为了对它们能够直接访问,C51编译器利用扩充的关键字SFR和SFR16对这些特殊功能寄存器进行定义。vSFR的定义方法: sfr 特殊功能寄存器名=地址常数 v例如:vsfr P0= 0 x80; /* 定义P0口,地址为0 x80*/vsfr TMOD=0 x89; /*定时/计数器方式控制寄存器地址89H*/v2.特殊功能寄存器中特定位的定义特殊功能寄存器中特定位的定义v在C51中可
12、以利用关键字sbit定义可独立寻址访问的位变量,如定义80C51单片机SFR中的一些特定位。定义的方法有3种:2022-4-1414v1)sbit 位变量名=特殊功能寄存器名位的位置(07)v例如:vsfr PSW =0 xD0; /*定义PSW寄存器地址为0 xd0h*/vsbit OV = PSW2; /*定义OV位为PSW.2,地址为0 xd2*/vsbit CY = PSW7; /*定义Cy位为PSW.7,地址为0 xd7*/v 2)sbit位变量名=字节地址位的位置v例如:vsbit OV =0 xd02; /*定义OV位的地址为0 xd2*/v sbit CF =0 xd07; /
13、*定义CF位的地址为0 xd7*/v注意:字节地址作为基地址,必须位于0 x800 xff之间。v3)sbit 位变量名=位地址v例如:vsbit OV =0 xd2; /*定义OV位的地址为0 xd2*/v sbit CF =0 xd7; /*定义CF位的地址为0 xd7*/v注意:位地址必须位于0 x800 xFF之间。2022-4-1415v3.8051并行接口及其并行接口及其C51定义定义v1)对于8051片内I/O口用关键字sfr来定义。例:vsfr P0=0 x80; /*定义P0口,地址为80h*/vsfr P1=0 x90; /*定义P1口,地址为90h */v2)对于片外扩展
14、I/O口,则根据其硬件译码地址,将其视为片外数据存储器的一个单元,使用define语句进行定义。v例:v #include /绝对地址定义头文件v#define PORTA XBYTE0 x78f0 ; /*将PORTA定义为外部口,地址为78f0,长度为8位*/v一旦在头文件或程序中对这些片内外的I/O口进行定义以后,在程序中就可以就可以自由使用这些口了。定义口地址的目的是为了便于C51编译器按8051实际硬件结构建立I/O口变量名与其实际地址的联系,以便使程序员能用软件模拟8051硬件操作。2022-4-1416v4.位变量(位变量(bit)及其定义)及其定义vC51编译器支持bit数据类
15、型:v1)位变量的C51定义语法及语义如下:v bit dir_bit; /*将dir_bit定义为位变量*/v bit lock_bit; /*将lock_bit 定义为位变量*/v2)函数可包含类型为bit的参数,也可以将其作为返回值。vbit func(bit b0,bit b1) /*.*/ return (b1);v3)对位定义的限制:位变量不能定义成一个指针。v如 bit *bit_ptr是非法的。不存在位数组,如不能定义bit arr。v在位定义中允许定义存储类型,位变量都放在一个段位中,此段总位于8051片内RAM中,因此存储类型限制为data或idata。如果将位变量的存储类
16、型定义成其他类型,编译时将出错。v4)可位寻址对象:可位寻址的对象是指可以字节寻址或位寻址的对象,该对象位于8051片内RAM可位寻址RAM区中,C51编译器允许数据类型为idata的对象放入8051片内可位寻址的区中。先定义变量的数据类型和存储类型:vbdata int ibase; /*定义ibase为bdata整型变量*/vbdata char bary4; /*定义bary4为bdata字符型数组*/2022-4-14174.3 C51的运算符、表达式及其规则的运算符、表达式及其规则v4.3.1 算术运算符和算术表达式算术运算符和算术表达式v4.3.2 关系运算符、关系表达式及优先级关
17、系运算符、关系表达式及优先级v4.3.3 逻辑运算符和逻辑表达式及优先级逻辑运算符和逻辑表达式及优先级v4.3.4 C51位操作及其表达式位操作及其表达式v4.3.5 运算符的优先级运算符的优先级2022-4-14184.3.1 算术运算符和算术表达式算术运算符和算术表达式v1.基本算术运算符基本算术运算符v 加法运算符,或正值符号;v 减法运算符,或负值符号;v 乘法运算符;v 除法运算符;v% 模(求余)运算符;例11%3=2,结果是11除以3所得余数为2。v2.自增减运算符自增减运算符v自增减运算符的作用是使变量值自动加1或减1。v + 自增运算符;v- 自减运算符;2022-4-141
18、9v3.类型转换类型转换v运算符两侧的数据类型不同时,要转换成同种类型。转换的方法有两种:自动转换和强制类型转换。v自动转换是编译系统在编译时自动进行的类型转换,顺序是: vbitcharintlongfloat,signedunsigned。v强制类型转换是通过类型转换运算来实现的。v其一般形式:(类型说明符)(表达式) v功能:把表达式的运算结果强制转换成类型说明符所表示的类型。v如:v(double)a 将a强制转换成double类型v(int)(x+y) 将x+y值强制转换成int类型v(float)(5%3) 将模运算5%3的值强制转换成float类型。2022-4-14204.3.
19、2 关系运算符、关系表达式及优先级关系运算符、关系表达式及优先级v1.C51提供六种关系运算符提供六种关系运算符v 小于; v= 小于等于;v 大于;v= 大于等于v = 测试等于;v != 测试不等于;v 2.关系运算符的优先级关系运算符的优先级v1)、=的优先级相同,两种=、!=相同;前4种优先级高于后两种。v2)关系运算符的优先级低于算术运算符。v3)关系运算符的优先级高于赋值运算符。v如: ca+b 等效于 c(a+b); ab!=c 等效于(ab)!=cv a=bc 等效于a=(bc)2022-4-1421v3.关系运算符的结合性为左结合关系运算符的结合性为左结合v如:a=4,b=3
20、,c=1 ,则 f=abc,则ab的值为1,1c的值为0,故f=0。v4.关系表达式关系表达式v用关系运算符和将两个表达式(可以是算术表达式、关系表达式、逻辑表达式、字符表达式)连接起来的式子。v5.关系表达式的结果关系表达式的结果v真和假。C51中用0表示假,1表示真。2022-4-14224.3.3 逻辑运算符和逻辑表达式及优先级逻辑运算符和逻辑表达式及优先级v1.C51提供提供3种逻辑运算符种逻辑运算符v! 逻辑“非”(NOT)v& 逻辑 “与”(AND)v | 逻辑“或”(OR)v“&”和“|”是双目运算符,要求有两个运算对象;而“!”是单目运算符,只要求有一个运算对象
21、。v2.逻辑运算符的优先级逻辑运算符的优先级v在逻辑运算中,逻辑非的优先级最高,且高于算术运算符;逻辑“与”、“或”的优先级最低,低于关系运算符,但高于赋值运算符。v3.逻辑表达式逻辑表达式v用逻辑运算符将关系表达式或逻辑量连接起来的式子称为逻辑表达式。其值应为逻辑量真和假,逻辑表达式和关系表达式的值相同,以0代表假,1代表真。v4.逻辑运算符的结合性为从左到右。逻辑运算符的结合性为从左到右。v例:如a=4,b=5则:v!a 为假。因为a=4(非0)为真,所以!a为假(0)。2022-4-14234.3.4 C51位操作及其表达式位操作及其表达式vC51提供6种位运算符:v & 位与;
22、v| 位或;v 位异或;v 位取反;v 右移;v除按位取反运算符“”以外,以上位操作运算符都是双目运算符,及要求运算符两侧各有一个运算对象。2022-4-14244.3.5 运算符的优先级运算符的优先级v 当一个表达式中有多个运算符参加运算时,将按表4-6所规定的优先级进行运算。表中优先级从上往下逐渐降低,同一行优先级相同。2022-4-14254.4 C51流程控制语句流程控制语句v 顺序结构、选择结构和循环结构是实现所有程序的三种基本结构,也是C51语言程序的三种基本构造单元。v 选择结构体现了程序的逻辑判断能力,分支结构分为简单分支(两分支)和多分支两种情况。一般采用if语句实现简单分支
23、结构的程序,用switch-case语句实现多分支结构程序。循环结构解决了重复性的程序段的设计,主要有for语句、while语句以及do-while语句。2022-4-14264.4 C51流程控制语句流程控制语句v4.4.1 C51的顺序结构的顺序结构v4.4.2 C51的选择结构的选择结构v4.4.3 C51的循环结构的循环结构2022-4-14274.4.1 C51的顺序结构的顺序结构v 顺序结构是一种基本、最简单的编程结构。在这种结构中,程序由低地址向高地址顺序执行指令代码。如图4-3所示,程序先执行A操作,再执行B操作,两者是顺序执行的关系。2022-4-14284.4.2 C51的
24、选择结构的选择结构v 在C51中,选择语句有条件语句和开关语句两种。选择结构的流程图参考图4-4。2022-4-14294.4.3 C51的循环结构的循环结构v 循环结构是结构化程序设计的3种基本结构之一,因此掌握循环结构的概念是程序设计,尤其是C程序设计最基本的要求。循环程序结构流程图参考图4-5。2022-4-1430v在C51语言中,实现循环的语句主要有3种。v1.While语句的一般形式语句的一般形式vWhile(表达式)v语句; /*循环体*/v2.do-while 语句的一般形式语句的一般形式vdov语句; /*循环体*/vwhile (表达式);v3.for 语句的一般形式语句的
25、一般形式vfor (表达式1;表达式2;表达式3)v语句; /*循环体*/2022-4-14314.5 C51的数组的数组v 在程序设计中,为了处理方便,把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类型数据元素的集合称为数组。v 在C语言中,数组属于构造数据类型。一个数组可以分解为多个数据元素,这些数据元素可以是基本的数据类型或是构造类型。因此按数组元素的类型不同,数组又可分为数值数组、字符数组、指针数组、结构数组等各种类别。2022-4-14324.5 C51的数组的数组v4.5.1 一维数组一维数组v4.5.2 二维数组二维数组v4.5.3 字符数组字符数组v4.5.4
26、查表查表2022-4-14334.5.1 一维数组一维数组v1.一维数组的定义方式一维数组的定义方式v 类型说明符 数组名 整型常量表达式;例如:int a10;v它表示数组名为a,此数组有10个元素。v2.一维数组的初始化一维数组的初始化v对数组元素的初始化可以用以下方法实现:v1)在定义数组时对数组元素赋予初值。例如:vint a10=0,1,2,3,4,5,6,7,8,9;v2)可以只给一部分元素赋值。例如:vint a10=0,1,2,3,4;v3)在对全部数组元素赋初值时,可以不指定数组的长度。例如:vint a5=1,2,3,4,5;v也可以写成: int a=1,2,3,4,5;
27、2022-4-1434v3.一维数组元素的引用一维数组元素的引用v数组必须先定义,后使用。C51语言规定只能逐个引用数组元素而不能一次引用整个数组。数组元素的表示形式为:v数组名下标 , 下标可以是整型常量或整型表达式。如:va0=a5+a7-a2*3;2022-4-14354.5.2 二维数组二维数组v1.二维数组定义的一般形式二维数组定义的一般形式v类型说明符 数组名常量表达式 常量表达式v例如 int a34,b510;v定义a为3x4(3行4列)的数组,b为5x10(5行10列)的数组。数组元素为int型数据。vC51语言对二维数组采用这样的定义方式,使我们可以把二维数组看作一种特殊的
28、一维数组:它的元素又是一维数组。例如把a看做一个一维数组,它有3个元素:a0、a1、a2,每一个元素又是一个包含4个元素的一维数组,如图所示。2022-4-1436v2.二维数组的初始化二维数组的初始化v(1) 按行赋初值v数据类型 数组名行常量表达式列常量表达式=第0行初值表,第1行初值表,最后1行初值表;v(2) 按二维数组在内存中的排列顺序给各元素赋初值v数据类型 数组名 行常量表达式 列常量表达式=初值表;v3.二维数组元素的引用二维数组元素的引用v数组名 行下标表达式 列下标表达式v(1)“行下标表达式”和“列下标表达式”,都应是整型表达式或符号常量。v(2)“行下标表达式”和“列下
29、标表达式”的值,都应在已定义数组大小的范围内。v(3) 对基本数据类型的变量所能进行的操作,也适合于相同数据类型的二维数组元素。2022-4-14374.5.3 字符数组字符数组v 字符数组就是元素类型为字符型(char)的数组,字符数组是用来存放字符的。在字符数组中,一个元素存放一个字符,可以用字符数组来存储长度不同的字符串。v1.字符数组的定义字符数组的定义v字符数组的定义和数组定义的方法类似。v如 char str10, 定义str为一个有10个字符的一维数组。v2.字符数组置初值字符数组置初值v最直接的方法是将各字符逐个赋给数组中的各元素。如:vchar str10=M,I,A,N,
30、,Y,A,N,G,0; /* 0表示字符串的结束标志。*/vC语言还允许用字符串直接给字符数组置初值。其方法有以下两种形式:vchar str10=Cheng Du; char str10=Bei Jing2022-4-14384.5.4 查表查表v 在C51编程中,数组的一个非常有用的功能之一就是查表。v 在实际单片机应用系统中,希望单片机能进行高精度的数学运算,但这并非单片机的特长,也不是完全必要的。许多嵌入式控制系统的应用中,人们更愿意用表格而不是数学公式,特别是在A/D转换中对模拟量的标定,使用表格查找法避免数值计算。在LED数码显示、LCD的汉字显示系统中,一般将字符或汉字的点阵信息
31、存放在表格中,表格可事先计算好装入EPROM中。2022-4-14392022-4-14404.6 指针指针v4.6.1 指针的基本概念指针的基本概念v4.6.2 指针变量的使用指针变量的使用v4.6.3 数组指针和指向数组的指针变量数组指针和指向数组的指针变量v4.6.4 指向多维数组的指针和指针变量指向多维数组的指针和指针变量v4.6.5 关于关于KEIL C51的指针类型的指针类型 v4.6.6 避免使用浮点指针避免使用浮点指针2022-4-14414.6.1 指针的基本概念指针的基本概念v1.地址地址v 对于变量,实际存在3个基本要素,即变量名、变量的地址和变量的值。变量名是变量的外在
32、表现形式,方便用户对数据进行引用;变量的值是变量的核心内容,是设置变量的目的,设置变量就是为了对其中的值进行读写访问,变量的值存放在内存单元中;变量的地址则起到纽带的作用,把变量名和变量的值联系起来,通过变量名得到变.v 对于内存单元,也要明确两个概念,一个是内存单元的地址,一个是内存单元的内容。前者是内存对该单元的编号,它表示该单元在整个内存中的位置。后者指的是在该内存单元中存放着的数据。量的地址,再通过变量地址在内存中寻址找到变量值2022-4-1442v2.指针指针v 变量存储单元的分配、地址的记录以及寻址过程虽然是在系统内部自动完成的,一般用户不需要关心其中的细节,但是出于对变量灵活使
33、用的需要,有时在程序中围绕变量的地址展开操作,这就引入“指针”的概念。变量的地址称为变量的指针,指针的引入把地址形象化了,地址是找变量值的索引或指南,就像一根“指针”一样指向变量值所在的存储单元,因此指针即是地址,是记录变量存储单元位置的正整数。v3.指针变量指针变量v图4-7反映了指针变量与指针、指针与指针所指变量之间的关系。变量n是一般变量,变量n的指针(地址)又存放在指针变量p中,因此要存取变量n的值可以通过指针变量p以“间接访问”的方式进行:先从指针变量p中得到存放在其中的指针,即变量n的地址,在根据这个指针(地址)寻址,找到对应的存储单元,实现对变量 n的访问。2022-4-1443
34、4.6.2 指针变量的使用指针变量的使用v1.指针变量的定义指针变量的定义vC语言规定,所有的变量在使用前必须定义,以确定其类型。指针变量也不例外,由于它是专门存放地址的,因此必须将它定义为“指针类型”。v指针定义的一般形式为: 类型识别符 *指针变量名;v如: int *ap; float *pointer;v2.指针变量的赋值指针变量的赋值取地址运算符取地址运算符“&”v将指针变量指向某个变量的赋值格式通常是:指针变量名=&所指向的变量名;v如:要建立图4-5中指针变量p与一般变量n的指向关系,则需要进行一下的定义和赋值。v int *p,n=10; p=&n;20
35、22-4-1444v3.指针变量的引用指针变量的引用-指针运算符指针运算符“*”v 在进行了变量和指针变量的定义之后,如果对这些语句进行编译,C编译器就会为每个变量和指针变量在内存中安排相应的内存单元,如: v定义变量和指针变量:vint x=1,y=2,z=3; /* 定义整型变量x,y,z */vint *x_point; /* 定义指针变量x_point */vint x=1,y=2,z=3; /* 定义整型变量x,y,z */vint *x_point; /* 定义指针变量x_point */vint *y_point; /* 定义指针变量y_point */vint *z_point
36、; /* 定义指针变量z_point */2022-4-14454.6.3 数组指针和指向数组的指针变量数组指针和指向数组的指针变量v 指针既然可以指向变量,当然也可以指向数组。所谓数组的指针,就是数组的起始地址。若有一个变量用来存放一个数组的起始地址(指针),则称它为指向数组的指针变量.v1.指向数组的指针变量的定义、引用和赋值指向数组的指针变量的定义、引用和赋值v首先定义一个数组a10和一个指向数组的指针变量array_ptr:vint a10; /* 定义a为包含10个整型元素的数组*/vint *array_ptr; /* 定义array_ptr为指向整型数据的指针*/v为了将指针变量
37、指向数组a10,需要对array_ptr进行引用,有如下两种引用方法。v1) array_ptr=&a0v2)array_ptr =a2022-4-1446v2. 通过指针引用数组元素通过指针引用数组元素v引用数组元素,可以使用数组下标法如a4,也可以使用指针法。与数组下标法相比,使用指针法引用数组元素能使目标代码效率高(占用内存少,运行速度快)。v通过指针引用数组元素:设指针变量array_ptr的初值为&a0,如图4-9所示.2022-4-1447v3.关于指针变量的运算关于指针变量的运算v p+ (或者或者 p+=1)v该操作将使指针变量p指向数组a 的下一个元素,即 a
38、1。若再执行x=*p,则将a1的值赋给变量x。v *p+v由于+运算符优先级高于*,故*p+等价于*(p+)。其作用是先得到p所指向的变量的值(即*p),再执行p自加运算。v *p+ 和和*+p作用不同作用不同v*p+ 先取*p的值,后使p自加1;*+p 先使p自加1,再取*p的值。v (*p)+v表示p所指向的元素值加1,而不是指针变量值加1。若p=a,即p指向&a0,且a0=12,则(*p)+等价于(a0)+。此时a0=13。v 若若p当前指向数组的第当前指向数组的第i个元素个元素ai,则,则:v*(p-)与ai-等价,相当于先执行*p,然后再使p自减1。v*(+p)和 a+i等价
39、,相当与先执行p自加1,再执行*p运算。v*(-p)与a-i等价,相当与先执行p自减1,再执行*p运算。2022-4-14484.6.4 指向多维数组的指针和指针变量指向多维数组的指针和指针变量v以二维数组为例来说明指向多维数组的指针和指针变量的使用方法。v现在定义一个三行四列的二维数组a34。v同时,定义这样一个(*p)4。它的含义是:p是一个指针变量,指向一个包含4个元素的一维数组。下面使指针变量p指向a34的首地址:p=a或者p=&a0。则此时p和a等价,均指向数组a34的第0行首址(a00)。vp+1和a+1等价,均指向数组a34的第1行首址(a10)。vp+2和a+2等价,均
40、指向数组a34的第2行首址(a20)。v v而 (p+1)+3 与 &a13等价,指向a13的地址。v*(*(p+1)+3) 与 a13等价,表示a13的值。v一般,对于数组元素aij来讲,有:v(p+i)+j 就相当于 &aij,表示数组第i行第j列元素的地址。v*(*(p+i)+j) 就相当于aij,表示数组第i行第j列元素的值。2022-4-14494.6.5 关于关于KEIL C51的指针类型的指针类型 v1.基于存储器的指针基于存储器的指针v定义指针变量时,若指定了它所指向的对象的存储类型时,该变量就被认为是基于存储器的指针。例如:vchar xdata *px;v定
41、义了一个指向xdata存储器中字符类型(char)的指针。指针本身在默认存储器(决定于编译模式),长度为2字节(值为00 xffff)。vchar xdata * data pdx;v2.一般指针一般指针v定义一般指针变量时,若未指定它所指向的对象的存储类型,该指针变量就认为是一个一般指针。一般指针包括三个字节: 2字节偏移和1字节存储器类型,如表4-7所示2022-4-14504.6.6 避免使用浮点指针避免使用浮点指针v在C51编译器上使用32位浮点数是得不偿失的,会浪费大量的时间,所以当要在系统中使用浮点数的时候,要确定这是否一定需要,可以通过提高数值数量级和使用整型运算来消除浮点指针,
42、,处理ints和longs比处理doubles和floats要方便得多。代码执行起来更快,也不用连接处理浮点指针的模块。如果一定要采用浮点指针的话,应该采用西门子80517和达拉斯半导体公司的80320,这些单片机已经对数据处理进行过优化。v如果不得不在代码中加入浮点指针, 那么代码长度会增加,程序执行速度会比较慢,如果浮点指针运算能被中断的话,必须确保要么中断中不会使用浮点指针运算,要么在中断程序前使用fpsave指令,把中断指针推入堆栈,在中断程序执行后,使用fprestore指令把指针恢复。还有一种方法是,当要使用像sinO这样的浮点运算程序时,禁止使用中断,在运算程序执行完之后再使能它
43、。2022-4-14512022-4-14524.7 C51的函数的函数v4.7.1 函数的分类函数的分类v4.7.2 函数的参数传递和函数值函数的参数传递和函数值v4.7.3 函数的调用函数的调用v4.7.4 C51函数的定义函数的定义2022-4-14534.7.1 函数的分类函数的分类vC51函数的一般定义形式为:v返回值类型 函数名(形式参数列表) 编译模式reentrantinterrupt musing nv 函数体v(1)当函数没有返回值时,应用关键字void明确说明返回值类型。形式参数的类型要明确说明,对于无形参的函数,括号也要保留。v(2)编译模式为small、compact
44、或large,用来指定函数中局部变量参数和参数在存储器空间。v(3)reentrant 用于定义可重入函数。vinterrupt m 用于定义中断函数,m为中断号,可以为031, 但具体的中断号要取决于芯片的型号,像 AT89c51 实际上就使用 04 号中断。每个中断号都对应一个中断向量,具体地址为 8n+3, 中断源响应后处理器会跳转到中断向量所在的地址执行程序,编译器会在这地址上产生一个无条件跳转语句,转到中断服务函数所在的地址执行程序。v(4)Using n 用于确定中断服务函数所使用的工作寄存器组,n为工作寄存器组号,取值为03。这个选项是指定选用 51单片机芯片内部 4 组工作寄存
45、器中的那个组。开始学习者能不必去做工作寄存器设定,而由编译器自动选择。2022-4-14542022-4-14554.8 任务3 C51与汇编语言的混合编程实例与汇编语言的混合编程实例v4.8.1 C51中调用汇编程序中调用汇编程序v4.8.2 在在C51中嵌入汇编代码中嵌入汇编代码2022-4-14564.8.1 C51中调用汇编程序中调用汇编程序2022-4-14574.8.2 在在C51中嵌入汇编代码中嵌入汇编代码v 程序中需要用到一些简短的汇编指令时,可以采用在C51函数中直接嵌入汇编代码的办法,但这需要对Keil编译器(见本书1.2.2节)进行一些设置,方法如下:v将嵌有汇编代码的C
46、51源文件加入当前工程文件中,右键单击工程管理窗口“Project”中的C51文件名,单击菜单项“Option for File,将属性“Properties”中的“Generate Assembler SRC File”与“Assemble SRC File”两项设置为力深黑色“”(生成汇编SRC文件)。v根据采用的编译模式,将相应的库文件加入当前工程文件中。对于Small模式,其路径及库文件名是KeilC51LibC51S.Lib。对于Cmpact和Large模式,其库文件名分别是C51C.Lib和C51. Lib。注意,该库文件应为当前工程的最后一个文件,即需要先先加入C51源文件,后加
47、入库文件。2022-4-14582022-4-1459v【例题4-4】混合编程实例-键控流水灯,电路如图4-11所示,键控流水灯的C语言程序中的延时函数delay(第3章中实例7)用汇编语言实现,完成系统的混合编程。v实例中的延时函数是无返回型,但有一个char型输入参数。根据4.8.1关于在C51中调用汇编程序的要求,本实例采用大写形式且加“_”前缀的同名“函数”来实现延时功能,具体内容如下:2022-4-14602022-4-1461v例题4-4的编程界面如图4-12所示。2022-4-14624.9 任务任务4 简易密码锁设计简易密码锁设计v4.9.1 键盘工作原理键盘工作原理v4.9.
48、2 独立式按键独立式按键v4.9.3 矩阵式按键矩阵式按键v4.9.4 矩阵键盘密码锁设计矩阵键盘密码锁设计v4.9.5 程序分析程序分析v4.9.6 调试与仿真运行调试与仿真运行2022-4-14634.9.1 键盘工作原理键盘工作原理v1.开关的分类开关的分类v2键输入原理键输入原理v3键盘与单片机接口需解决的问题键盘与单片机接口需解决的问题2022-4-1464v(1)键盘开关状态的可靠输入v单片机应用系统通常使用触点式按键开关,其主要功能是把机械上的通断转换成为电气上的连接关系。触点式按键按下或释放时,由于机械弹性作用的影响,触点通常伴随有一定时间的机械抖动,从而使输入到单片机的电压信
49、号也出现抖动,其抖动过程如图4-14(a)所示。抖动时间的长短与开关的机械特性有关,一般为510 ms。v(2)对按键进行编码以给定键值v一组按键或键盘都要通过单片机I/O口线查询按键的开关状态。根据键盘结构的不同,采用不同的编码方法。无论有无编码,以及采用什么编码,最后都要转换成为与累加器中数值相对应的键值,以实现按键功能程序的跳转2022-4-14654.9.2 独立式按键独立式按键v1.独立式按键结构独立式按键结构v 独立式按键电路结构 键控流水灯扫描流程图2022-4-1466v2. 独立式按键的程序设计独立式按键的程序设计v 在程序设计中,监测独立式按键的的开关状态常采用查询方式。电
50、路如图4-11所示,在图4-11中,先逐位查询每根I/O口线的输入状态,如某一根I/O口线输入为“0”(低电平),则可确认该I/O口线所对应的按键已按下;而无键按下时,I/O口线输入为“1”(高电平)。当确认某键按下后,再转向该键的功能处理程序。扫描流程图所示。2022-4-14674.9.3 矩阵式按键矩阵式按键v1.矩阵式按键的结构矩阵式按键的结构v矩阵式按键由行线和列线组成,按键位于行、列线的交叉点上,其结构如图所示。2022-4-1468v2. 矩阵式按键的程序设计矩阵式按键的程序设计v矩阵式按键识别按键的方法很多,其中,最常见的是动态扫描法。其识别按键的过程分2步:首先确定是否有键闭
51、合,然后逐一扫描以进一步确定是哪一键闭合。下面以图所示电路为例说明动态扫描法识别按键的过程。v(1)识别有无按键闭合v图中行线为输入,列线为输出。没有键按下时,行线列线之间断开,行线端口输入全为高电平。有键按下时,键所在行线与列线短路,故行线输入的电平为列线输出的状态,若列线输出低电平,则按键所在行线的输入也为低电平。因此,通过检测行线的状态是否全为高电平1,就可以判断是否有键按下。v(2)进一步确定闭合的按键v 图中,可以采用逐列扫描法,原理同上,此时逐个给每列输出低电平0,读取行线的状态,若行值全为高电平1,则说明此列无键闭合,继续扫描下一列,使下一列输出为低电平0。若行值中某位为低电平0
52、,则说明此行、列交叉点处的按键被闭合。2022-4-1469v【例4-5】一种矩阵式按键电路如图4-18所示。试采用动态扫描方式编写16个按键监测与键功能处理程序。v 图是一种简化后的键盘接口电路,该键盘是由单片机P1口构成的44键盘。键盘的列线与P1口的高4位相连,键盘的行线与P1口的低4位相连,因此,P1.4P1.7是键输入线,P1.0P1.3是扫描输出线。图中的4输入与门用于产生按键中断,其输入端与各列线相连,再通过上拉电阻接至+5V电源,输出端接至单片机的外部中断0( )。 具体工作过程是:当键盘无键按下时,与门各输入端均为高电平,保持输出端为高电平;当有键按下时,与门输出端为低电平,
53、向CPU申请中断,若开放外部中断,则CPU会响应中断请求,转去执行键盘扫描子程序。2022-4-14704.9.4 矩阵键盘密码锁设计矩阵键盘密码锁设计v1. 硬件电路设计硬件电路设计v下面以4*4矩阵键盘为例讲解其工作原理和检测方法。将16个按键排成4行4列,将第一行的每个按键一端连接在一起构成第一根行线,将第一列的每个按键的另外一端连接在一起构成第一根列线,用同样的方法将第二、三、四列的按键连接,这样一共有4行4列共8根线,将这8根线连接到单片机的I/O口上,通过程序扫描键盘就可以检测16个键。v对于矩阵键盘密码锁,16个按键的每一端都与I/O口相连接,硬件电路与仿真如图4-19所示。矩阵
54、键盘的4行分别与单片机的P2.0P2.3口相连,矩阵键盘的4列分别与单片机的P2.4P2.7口相连。用单个共阴极的数码管显示键值,指示:灯与P1.0口连接,三极管的基极与P1.7口连接,通过控制三极管的导通和截止使继电器吸合与断开,从而控制电机转动与否进行开锁与上锁。.2022-4-1471v2. 程序设计程序设计2022-4-1472#include #include #include#define uchar unsigned char #define uint unsigned intsbit LED=P10;sbit relay=P17;uchar code a16=0 x3F,0 x
55、06,0 x5B,0 x4F,0 x66,0 x6D,0 x7D,0 x07,0 x7F, 0 x6F,0 x77,0 x7C,0 x39,0 x5E,0 x79,0 x71;uchar code set_mima6=1,2,3,4,5,6;/设置的密码 vvoid delay(uint i)/延时程序vuint j;vfor(j=0;ji;j+);vvuchar checkkey()/检测有没有键按下vuchar i ;v uchar j ;v j=0 xf0; v P2=j; /4行(P2.0P2.3)输出全“0”v i=P2; /读P2口v i=i&0 xf0; /屏蔽P2口的低
56、4位v if (i=0 xf0) return (0); /P2口的高4位全“1”无键按下,返回“0”v else return (0 xff); / 有键按下,返回“0 xff”v vuchar keyscan()/键盘扫描程序,无键按下返回值为FF,有键按下返回键值vvuchar scancode;vuchar codevalue;vuchar a;vuchar m=0;vuchar k;vuchar i,j;vif (checkkey()=0) return (0 xff); /无键按下返回值为FFv else v delay(100);v if (checkkey()=0) retur
57、n (0 xff); /无键按下返回值为FFvelse /有键按下逐行扫描v v scancode=0 xfe;m=0 x00; /键盘行扫描初值,m为每行首键号vfor (i=1;i=4;i+)/i为行数vv k=0 x10; v P2=scancode;v a=P2;v for (j=0;j4;j+)/J为列数v if (a&k)=0) v v codevalue =m+j; /计算键值v while (checkkey()!=0); /等待键释放v return (codevalue);v v else k=k1; v m=m+4;/每一行有4个按键,行增加1,键值加4v /sc
58、ancode=_crol_(scancode,1);v scancode=scancode1;v scancode=scancode|0 x01;v v v v vvoid main() /主函数v v uchar i;v uchar data int_mima6;v int x;v P3=0 x00;vwhile(1) v uchar data int_mima6=0,0,0,0,0,0;v if (checkkey()=0 x00) continue; / 无键按下checkkey()返回值为0 ,返到while(1)继续v else / 有键按逐行扫描返回值送int_mimav v fo
59、r(i=0;i6;i+)v v int_mimai=keyscan();v P3=aint_mimai;v while(checkkey()=0); /等待v vif( int_mima0=set_mima0&int_mima1=set_mima1&int_mima2=set_mima2&int_mima3=set_mima3&int_mima4=set_mima4& int_mima5=set_mima5)v LED=0;/密码相同LED灯点亮v relay=0;/密码相同,继电器吸合v v v 4.9.5 程序分析程序分析v(1)主函数中i变量是用来
60、记录密码输入个数,此设计是6位密码,每次输入的密码放在int_mimai中。v(2)“P3=aint_mimai;”是在数码管上显示按下的键值v(3)“if( int_mima0=set_mima0&int_mima1=set_mima1&int_mima2=vset_mima2&int_mima3=set_mima3&int_mima4=set_mima4& int_mima5=set_mima5 )”v一句是判断输入的密码是否与初始设置密码一致,方法是将存放输入密码的数组与存放初始密码的数组一一进行比较。如果if语句里的条件成立,那么使指示灯点亮,并且继电器吸合。2022-4-14784.9.6 调试与仿真运行调试与仿真运行v 在程序的调试过程中排除输入和编辑过程中出现的错误,将Keil的输出设置为生成HEX义件,源程序
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 电子质检员考试试题及答案
- 风机工考试试题及答案
- 电动汽车电力系统解析试题及答案
- 车辆电气系统发展现状试题及答案
- 重点剖析2025年商务英语考试试题及答案
- 趣味试卷幼儿园数学试题及答案
- 注册土木工程师考试考试动态跟踪试题及答案
- 2025-2030中国塑筋软管行业市场发展分析及前景趋势与投资研究报告
- 2025-2030中国土豆行业市场发展现状及前景趋势与投资风险研究报告
- 2025-2030中国口腔种植体行业市场深度调研及发展分析与投资前景研究报告
- 2025-2030中国环境监测发展分析及发展趋势与投资前景研究报告
- 2025年教师资格证面试结构化模拟题:教师心理健康维护试题集
- 大疆精灵4 RTK无人机操作与测绘培训指南
- 2025届江苏省南京一中高三第二次模拟考试物理试卷含解析
- 初中语文第16课《有为有不为》课件-2024-2025学年统编版语文七年级下册
- 2025年内蒙古化工职业学院单招职业技能考试题库必考题
- 2025年陕西延长石油(集团)有限责任公司招聘笔试参考题库含答案解析
- 2024-2025下学期高二化学鲁科版期中必刷题之化学键与物质的性质
- 线上医药销售培训
- 鼻肠管的应用及护理课件
- 2025年宪法知识竞赛全套题库及答案(共150题)
评论
0/150
提交评论