大学单片机原理与应用-胡辉-PPT文稿资料课件PPT
收藏
资源目录
压缩包内文档预览:(预览前20页/共30页)
编号:21836274
类型:共享资源
大小:17.22MB
格式:ZIP
上传时间:2019-09-06
上传人:QQ24****1780
认证信息
个人认证
王**(实名认证)
浙江
IP属地:浙江
25
积分
- 关 键 词:
-
大学
单片机
原理
应用
利用
运用
胡辉
ppt
文稿
资料
课件
- 资源描述:
-
大学单片机原理与应用-胡辉-PPT文稿资料课件PPT,大学,单片机,原理,应用,利用,运用,胡辉,ppt,文稿,资料,课件
- 内容简介:
-
第10章 单片机应用 系统设计,10.1 单片机应用系统设计的开发步骤,一个完备的单片机应用系统包括硬件和软件两大部分,其中硬件部分包括扩展的存储器、键盘、显示、前向通道、后向通道、控制接口电路以及相关芯片的外围电路等,软件的功能就是指挥单片机按预定的功能要求进行操作的程序。,10.1.1 系统总体设计,系统总体设计是单片机系统设计的前提,合理的总体设计是系统成败的关键。总体设计关键在于对系统功能和性能的认识和合理分析。系统单片机及关键芯片的选型,系统基本结构的确立和软、硬件功能的划分也是系统总体设计的重要组成部分。,10.1.2 硬件设计,1程序存储器 2数据存储器 3I/O接口 4总线驱动器 5抗干扰电路,10.1.3 软件设计,1系统定义,(1)定义说明各输入/输出口的功能。 (2)在程序存储器和数据存储器区域中,合理分配存储空间。 (3)对面板控制开关、按键等输入量以及显示、打印等输出量也必须给予定义。 (4)针对可能出现的由干扰引起的错误进行容错设计,给出错误处理方案。,2软件结构设计,10.1.4 系统总体调试,(1)硬件调试 (静态调试和动态调试) (2)软件调试 (3)系统联调 (4)现场调试,10.1.5 程序固化,系统独立运行 将程序固化在单片机系统的程序存储器当中,目标系统就可以独立运行了。目标样机独立运行一段时间进行老化后,如果没有故障产生,即可认为整个系统开发成功。,10.2 设计实例1步进电机的控制,1.设计目的 (1)掌握单片机对步进电机的控制方法 (2)掌握步进电机正转、反转、速度及步数控制的方法 2.技术要求 (1)使用三向六拍步进电机,编程使步进电机正向/反向旋转10圈 (2)旋转时间为2秒 (3)旋转方向由手动控制,步进电机控制原理 (1)单相三拍方式:按单相绕组施加电流脉冲 正转:ABCA 反转:ACBA (2)双相三拍方式:按双相绕组施加电流脉冲 正转:ABBCCAAB 反转:ACCBBAAC (3)三相六拍方式:单相绕组和双相绕组交替施加电流脉冲 正转:AABBBCCCAA 反转:AACCCBBBAA,3.设计方案,步进电机速度控制的方法就是改变各通电脉冲的时间间隔,由脉冲延时程序控制即可。在输出控制电平后,由延时程序控制每一步的时间,即可达到控制步进电机速度的目的。如本设计要求2秒旋转10圈,则每一步需要的时间为: t=2s/10NZr=2000ms/103240=833s。 其中N=MCC,即运行拍数,其中MC为绕组相数(本题为三相),C为状态系数。三拍时,C=1;六拍时,C=2。Zr为转子齿数(40个)。步进电机的步数控制由要求旋转圈数除以每一步旋转的角度即可。设计要求旋转10圈,则10360o/1.5=2400圈(960H)。,4.电路,5.参考程序 ORG 1000H AA1: MOV R3,#960H ;确定步进电机前进步数 AA2: MOV R4,#00H MOV DPTR,#STEP;控制模型首地址送DPTR JNB P1.4,FAN ;判断正转还是反转 ZHENG: MOV A,R4 MOVC A,A+DPTR JZ AA2 ;旋转一圈后转回AA2 MOV P1,A ;控制步进电机旋转 ACALL DELAY ;延时,控制速度 INC R4 ;控制步数加1 DJNZ R3,ZHENG ;步数未完继续 RET,FAN: MOV A,R4;取反向控制模型偏移量 ADD A,#07H MOV R4,A AJAMP ZHENG DELAY: (延时833s) STEP: DB 01H,03H,02H,06H,04H,05H,00H;正向控制模型 DB 01H,05H,04H,06H,02H,03H,00H;反向控制模型,10.3 设计实例2数字电压表的设计,END,第10章 单片机应用系统设计 10.1 单片机应用系统设计的开发步骤 一个完备的单片机应用系统包括硬件和软件两大部分,其中硬件部分包括扩展的存储器、键盘、显示、前向通道、后向通道、控制接口电路以及相关芯片的外围电路等,软件的功能就是指挥单片机按预定的功能要求进行操作的程序。 10.1.1 系统总体设计 系统总体设计是单片机系统设计的前提,合理的总体设计是系统成败的关键。总体设计关键在于对系统功能和性能的认识和合理分析。系统单片机及关键芯片的选型,系统基本结构的确立和软、硬件功能的划分也是系统总体设计的重要组成部分。10.1.2 硬件设计1程序存储器 2数据存储器 3I/O接口 4总线驱动器 5抗干扰电路 10.1.3 软件设计 1系统定义 (1)定义说明各输入/输出口的功能。 (2)在程序存储器和数据存储器区域中,合理分配存储空间。(3)对面板控制开关、按键等输入量以及显示、打印等输出量也必须给予定义。 (4)针对可能出现的由干扰引起的错误进行容错设计,给出错误处理方案。 2软件结构设计10.1.4 系统总体调试 (1)硬件调试 (静态调试和动态调试)(2)软件调试 (3)系统联调 (4)现场调试 10.1.5 程序固化,系统独立运行 将程序固化在单片机系统的程序存储器当中,目标系统就可以独立运行了。目标样机独立运行一段时间进行老化后,如果没有故障产生,即可认为整个系统开发成功。 10.2 设计实例1步进电机的控制1.设计目的(1)掌握单片机对步进电机的控制方法(2)掌握步进电机正转、反转、速度及步数控制的方法2.技术要求(1)使用三向六拍步进电机,编程使步进电机正向/反向旋转10圈(2)旋转时间为2秒(3)旋转方向由手动控制步进电机控制原理 (1)单相三拍方式:按单相绕组施加电流脉冲正转:ABCA反转:ACBA(2)双相三拍方式:按双相绕组施加电流脉冲正转:ABBCCAAB反转:ACCBBAAC(3)三相六拍方式:单相绕组和双相绕组交替施加电流脉冲正转:AABBBCCCAA反转:AACCCBBBAA3.设计方案 步进电机速度控制的方法就是改变各通电脉冲的时间间隔,由脉冲延时程序控制即可。在输出控制电平后,由延时程序控制每一步的时间,即可达到控制步进电机速度的目的。如本设计要求2秒旋转10圈,则每一步需要的时间为:t=2s/10NZr=2000ms/103240=833s。其中N=MCC,即运行拍数,其中MC为绕组相数(本题为三相),C为状态系数。三拍时,C=1;六拍时,C=2。Zr为转子齿数(40个)。步进电机的步数控制由要求旋转圈数除以每一步旋转的角度即可。设计要求旋转10圈,则10360o/1.5=2400圈(960H)。4.电路 5.参考程序 ORG1000HAA1:MOVR3,#960H;确定步进电机前进步数AA2: MOVR4,#00H MOVDPTR,#STEP;控制模型首地址送DPTR JNBP1.4,FAN;判断正转还是反转ZHENG:MOVA,R4 MOVCA,A+DPTR JZAA2;旋转一圈后转回AA2 MOVP1,A;控制步进电机旋转 ACALLDELAY;延时,控制速度 INCR4;控制步数加1 DJNZ R3,ZHENG ;步数未完继续 RETFAN: MOVA,R4;取反向控制模型偏移量 ADDA,#07H MOVR4,A AJAMPZHENGDELAY:(延时833s)STEP:DB 01H,03H,02H,06H,04H,05H,00H;正向控制模型 DB 01H,05H,04H,06H,02H,03H,00H;反向控制模型10.3 设计实例2数字电压表的设计END第11章 单片机 C51程序设计,C51语言概述,在学会使用汇编语言后,学习C语言编程是一件比较容易的事。下面是一个简单的例子: 89S52的P1引脚上接8个发光二极管,我们的任务是让接在P1引脚上的发光二极管按要求发光。,111 简单的C程序介绍,例1-1: 让接在P1.0引脚上的LED发光。 /*/ 单灯闪烁程序 /*/ #include “reg51.h” sbit P1_0=P10; void main( ) P1_1=0; ,这个C语言程序包含了哪些信息,1.“文件包含”处理 所谓“文件包含”是指一个文件将另外一个文件的内容全部包含进来,所以这里的程序虽然只有4行,但C编译器在处理的时候却要处理几十或几百行。这里程序中包含REG51.h文件的目的是为了要使用P1这个符号,即通知C编译器,程序中所写的P1是指80C51单片机的P1端口而不是其它变量。,reg51.h 文件包含以下内容:,/*-REG51.H Header file for generic 80C51 and 80C31 microcontroller. Copyright (c) 1988-2001 Keil Elektronik GmbH and Keil Software, Inc. All rights reserved. - - -*/ /* BYTE Register */ sfr P0 = 0x80; sfr P1 = 0x90; sfr P2 = 0xA0; sfr P3 = 0xB0; sfr PSW = 0xD0; sfr ACC = 0xE0;,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 PX1 = 0xBA; 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;,注意:,sfr P1 = 0x90; 这样的一行(上文中用黑体表示),即定义P1与地址0x90对应,P1口的地址就是0x90(0x90是C语言中十六进制数的写法,相当于汇编语言中写90H)。 sfr是标准C语言的关键字,而是Keil为能直接访问80C51中的SFR而提供了一个新的关键词,其用法是: sfrt 变量名=地址值。,2.符号P1_0来表示P1.0引脚,在C语言里,如果直接写P1.0,C编译器并不能识别,而且P1.0也不是一个合法的C语言变量名,所以得给它另起一个名字,这里起的名为P1_0,可是P1_0是不是就是P1.0呢?你这么认为,C编译器可不这么认为,所以必须给它们建立联系,,这里使用了Keil C的关键字sbit来定义,sbit的用法有三种: 第一种方法:sbit 位变量名地址值 第二种方法:sbit 位变量名SFR名称变量位地址值 第三种方法:sbit 位变量名SFR地址值变量位地址值,如定义PSW中的OV可以用以下三种方法:,sbit OV=0xd2 (1)说明:0xd2是OV的位地址值 sbit OV=PSW2 (2)说明:其中PSW必须先用sfr定义好 sbit OV=0xD02 (3)说明:0xD0就是PSW的地址值 因此这里用sfr P1_0=P10;就是定义用符号P1_0来表示P1.0引脚,如果你愿意也可以起P10一类的名字,只要下面程序中也随之更改就行了。,3.main称为“主函数”。,每一个C语言程序有且只有一个主函数,函数后面一定有一对大括号“ ”,在大括号里面书写其它程序。 从上面的分析我们了解了部分C语言的特性,下面再看一个稍复杂一点的例子。 例1-2 让接在P1.0引脚上的LED闪烁发光,/* 单灯闪烁程序 */ #include “reg51.h“ #define uchar unsigned char #define uint unsigned int sbit P10=P10; /*延时程序由Delay参数确定延迟时间*/ void mDelay(unsigned int Delay) unsigned int i; for(;Delay0;Delay-) for(i=0;i124;i+) ; ,void main() for(;) P10=!P10; /取反P1.0引脚 mDelay(1000); 程序分析:程序第二行是“P1_0=!P1_0;”,在P1_0前有一个符号“!”,符号“!”是C语言的一个运算符,就像数学中的“+”、“-”一样,是一种运算任号,意义是“取反”,即将该符号后面的那个变量的值取反。,注意:,取反运算只是对变量的值而言的,并不会自动改变变量本身。可以认为C编译器在处理“!P1_0”时,将P1_0的值给了一个临时变量,然后对这个临时变量取反,而不是直接对P1_0取反,団此取反完毕后还要使用赋值符号(“”)将取反后的值再赋给P1_0,这样,如果原来P1.0是低电平(LED亮),那么取反后,P1.0就是高电平(LED灭),反之,如果P1.0是高电平,取反后,P1.0就是低电平,这条指令被反复地执行,接在P1.0上灯就会不断“亮”、“灭”。,for(;),这行程序连同其后的一对大括号“”构成了一个无限循环语句,该大括号内的语句会被反复执行。 第三行程序是:“mDelay(1000);”,这行程序的用途是延时1s时间。 这里mDelay(1000)并不是由Keil C提供的库函数。在下面的程序中有void mDelay() 一段,如果你的程序中没有这么一段程序行,那就不能使用mDelay(1000)了。 mDelay后面有一个小括号,小括号里有数据(1000),这个1000被称之“参数”,用它可以在一定范围内调整延时时间的长短,这里用1000来要求延时时间为1000毫秒。,C语言的一些特点,1、C程序是由函数构成的,一个C源程序至少包括一个函数,一个C源程序有且只有一个名为main()的函数,也可能包含其它函数,因此,函数是C程序的基本单位。主程序通过直接书写语句和调用其它函数来实现有关功能,这些其它函数可以是由C语言本身提供给我们的,这样的函数称之为库函数,也可以是用户自己编写的,这样的函数称之为用户自定义函数。那么库函数和用户自定义函数有什么区别呢?简单地说,任何使用Keil C语言的人,都可以直接调用C的库函数而不需要为这个函数写任何代码,只需要包含具有该函数说明的相应的头文件即可;而自定义函数则是完全个性化的,是用户根据自己需要而编写的。Keil C提供了100多个库函数供我们直接使用。,2、一个函数由两部份组成:,(1)函数的首部、即函数的第一行。包括函数名、函数类型、函数属性、函数参数(形参)名、参数类型。 例如:void mDelay (unsigned int DelayTime) 一个函数名后面必须跟一对圆括号,即便没有任何参数也是如此。 (2)函数体,即函数首部下面的大括号“”内的部份。如果一个函数内有多个大括号,则最外层的一对“”为函数体的范围。 函数体一般包括: 声明部份:在这部份中定义所用到的变量, 执行部份:由若干个语句组成。,C51的一般格式如下: 类型 函数名(参数表) 参数说明; 数据说明部分; 执行语句部分; ,在某此情况下也可以没有声明部份,甚至即没有声明部份,也没有执行部份,如: void mDelay() 这是一个空函数,什么也不干,但它是合法的。 通过上述的几个例子,可以得出一些结论: 在编写程序时,可以利用空函数,比如主程序需要调用一个延时函数,可具体延时多少,怎么个延时法,暂时还不清楚,我们可以主程序的框架结构弄清,先编译通过,把架子搭起来再说,至于里面的细节,可以在以后慢慢地填,这时利用空函数,先写这么一个函数,这样在主程序中就可以调用它了。,3、一个C语言程序,总是从main函数开始执行的,而不管物理位置上这个main( )放在什么地方。 4、主程序中的mDelay如果写成mdelay就会编译出错,即C语言区分大小写,这一点往往让初学者非常困惑,尤其是学过一门其它语言的人,有人喜欢,有人不喜欢,但不管怎样,你得遵守这一规定。 5、C语言书写的格式自由,可以在一行写多个语句,也可以把一个语句写在多行。没有行号(但可以有标号),书写的缩进没有要求。但是建议读者自己按一定的规范来写,可以给自己带来方便。,6、每个语句和资料定义的最后必须有一个分号,分号是C语句的必要组成部份。 7、可以用/*/的形式为C程序的任何一部份作注释。 Keil C也支持C+风格的注释,就是用“/”引导的后面的语句是注释, 例:P1_0=!P1_0; /取反P1.0 这种风格的注释,只对本行有效,所以不会出现上面的问题,而且书写比较方便,所以在只需要一行注释的时候,我们往往采用这种格式。但要注意,只有Keil C支持这种格式,早期的Franklin C以及PC机上用的TC都不支持这种格式的注释,用上这种注释,编译时通不过,会报告编译错误。,11.2 C51的数据结构,C51的常量与变量,其值不能改变的量称为常量。常量可以有不同的数据类型。如0,1,2,-3为整型常量;4.6,-1.23等为实型常量;a、为字符型常量。可以用一个标识符号代表一个常量。 在程序运行中,其值可以改变的量称为变量。一个变量主要由两部分构成:一个是变量名,一个是变量值。每个变量都有一个变量名,在内存中占据一定的存储单元(地址),并在该内存单元中存放该变量的值。,#define CONST 60 main( ) int var,res; var=20; res=var*CONST printf(“res=%dn”,res); 程序运行结果: res=1200 在程序开头define CONST 60这一行定义了一个符号常量CONST,其值为60。这样在后面的程序中,凡是出现CONST的地方,都代表常量60。,11.3 C51 的运算符和表达式,1. 赋值运算符和表达式 变量表达式; 例如: tmp9; /*将常数9赋给变量tmp */ ij8; /*将常数8同时赋给变量i和j*/ C51提供了10种复合运算符:+=、-=、*=、/=、%=、=、&=、=、!=。,2. 算术运算符和算术表达式 C51有+、-、*、/、% 五种运算符 3. 关系运算符,4. 逻辑运算符 C语言中有3种逻辑运算符: (1)逻辑非(!) (2)逻辑与(&) (3)逻辑或(|) 5. 逗号运算符 在C51语言中,逗号“,”是一个特殊的运算符,可以用它将两个(或多个)表达式连接起来,称为逗号表达式。,6. 条件运算符 表达式“? :”是C51中唯一的三目运算符,要求有3个运算对象,它将三个表达式连接构成一个条件表达式。 7. 自增和自减运算符 C51语言中,除了基本的加、减、乘、除运算符之外,还提供一种特殊的运算符:“+”自增运算符;“-”自减运算符。,8. 指针和地址运算符 指针在C51语言中指示变量的地址,另外,还可以定义一个指向某个变量的指针变量。为了表示指针变量和它所指向的变量地址之间的关系,C51语言提供了两个专门的运算符:取内容()和取地址(&)。 9. 位运算符 位运算符的作用是按位对变量进行运算,并不改变参与运算的变量的值。,10. 强制类型转换运算符 强制类型转换运算符的作用是将表达式或变量的类型强制转换成所指定的类型。在C51程序中进行算术运算时,编译器自动处理数据类型转换。当自动类型转换不能实现目的时,可以使用强制类型转换。强制类型转换的一般格式为: (类型名)(表达式) 例如: (double) a /*将a转换成double类型*/ (int) (x+y) /*将x+y的值转换成整型*/,11.3.2 运算符的优先级和结合性 在表达式中,不同运算符连接的对象的运算顺序不完全按照表达式中书写的先后顺序进行的,各运算符参与运算的先后顺序不仅要遵守运算符优先级别的规定,还要受运算符结合性的制约。,11.4 C51的存储结构,11.4.1 存储区域 8051单片机有4个存储空间:片内程序存储空间,片外程序存储空间,片内数据存储空间和片外数据存储空间。 11.4.2存储模式 1. Small模式 2. 紧凑模式(Compact)模式 3. Large模式 4. 混合存储模式,11.5 C51的基本程序结构,1.If语句 (1)If (条件表达式) 动作 如果条件表达式的值为真(非零的数),则执行 内的动作,如果条件表达式为假,则略过 该动作继续往下执行。 (2) If (条件表达式) 动作 1 else 动作 2 如果条件表达式的值为真(非零的数),则执行动作1,(则略过else)如果条件表达式为假,则执行动作2。,(3)If (条件表达式1) 动作 1 else if (条件表达式2) 动作 2 else if (条件表达式3) 动作 3 else 动作 4 ,2switch-case语句,switch (条件表达式) case条件值1: 动作1 break; case条件值2: 动作2 break; case条件值3 动作3 break; default: 动作4 break; ,switch内的条件表达式的结果必须为整数或字符。switch以条件表达式的值来与各case的条件值对比,如果与某个条件值相符合,则执行该case的动作,如果所有的条件值都不符合,则执行default的动作,每一个动作之后一定要写break,否则会有错误。 case之后的条件值必须是数据常数,不能是变量。 任何由switch、for、while、do-while构成的循环,都可以用break来跳出,必须注意的是break一次只能跳出1层循环。,例1,void switch Dem(void) switch (Outputstate) case 1: P1_0=0; P1_1=0; Pl_2=0; break; case 2: P1_0=1; P1_1=0; P1_2=0; break; default: break; ,3while循环语句,while (条件表达式) 动作 先测试条件表达式是否成立,当条件表达式为真时,则执行循环内动作,做完后又继续跳回条件表达式作测试,如此反复直到条件表达式为假为止。 例2 while(P1_0= =0) /先测试条件:表达式,成立后再执行动作 Delayxlms(1); If(Pl_0= =0) Dutycount+; ,4do-while循环语句,do 动作 while (条件表达式); 先执行动作后,再测试条件表达式是否成立。当条件表达式为真,则继续回到前面执行动作,如此反复直到条件表达式为假为止,使用时要避免条件永真,造成死循环。,例3,void DowhileDem。(void) Byte i=0,j,k; Byte soundLong,soundTone; Word m; do /先执行动作后 soundLong=MUSIC_SOUNDLONGli; soundTone=MUSIC SOUNDTONEli; i+; for j=0; jSoundLong;j+ /sound long for (k=0; k12;k+) for (m=0;mSound Tone*l; m+) Pl_0=0; for (m=0;mSound Tone*l; m+) Pl_0=1; delay50us(6); while (MUSIC SOUNDTONEli! =0x00); /最后再测试条件去达式是否成立。,5for循环语句,for(表达式1;表达式2;表达式3) 动作 表达式1:通常是设定起始值。 表达式2:通常是条件判断式,如果条件为真时,则执行动作,否则终止循环。 表达式3:通常是步长表达式,执行动作完毕后,必须再回到这里做运算,然后再到表达式2做判断。,例4,void ForDemo (Byte ontime,Byte offtime) Byte i; for (i=0;i3;i+) Ledon(); Delayx l0rns(ontime); Ledoff(); Delayxl0ms(offtime); i+ ,从i=0开始执行,当i3时(即表达式2条件成立),则执行括号内 内的动作,否则跳出循环,继续执行。 continue:当程序执行for或while时,则可使用continue叙述来略过该循环,使得程序跳到下一次循环的开始,但并不跳出循环,只是忽略了continue后面的语句,11.6 C51的函数,11.6.1 函数的定义 C51函数的定义性说明格式为: 存储类说明返回值类型说明 函数名(形式参数列表)存储模式说明 重入说明 中断说明 寄存器组访问说明 参数说明; 局部变量说明部分; 执行语句部分; ,11.6.2 函数的调用 1. 形式参数和实际参数 2. 函数调用方式 11.6.3 数组与函数调用,数组,数组就是一组具有固定数目和相同类型成分分量的有序集合。 1.一维数组 一维数组的定义方式 类型说明符 数组名 整型表达式 例 char ch 10 定义了ch0 ch9十个元素。 数组的初始化 例 int idata a6=0,1,2,3,4,5;,2.二维数组,二维数组定义的一般形式: 类型说明符 数组名常量表达式常量表达式 ; 例 int a35 定义了3行5列共15个元素的数组。 二维数组的初始化 例 int a34=1,2,3,4,5,6,7,8,9,10,11,12; Int a34=1,2,3,4,5,6,7,8,9,10,11,12;,3.字符数组,数组中的元素用来存放字符,就称为3.字符数组。 字符数组的定义 字符数组的定义与数组定义的方法类似 例char a10 定义a为一个有10个字符的一维字符数组字符数组置初值 例: char a10=A,B C,D,E,I,G,F,J,K char a10=“BEI JING”,4.查表,数组的一个非常有用的功能之一就是查表。 数组的使用非常适合于这种查表方法。 例 #define uchar unsigned char uchar code pinf =0,1,4,9,16,25,36,49,64,81; uchar erte (uchar shy) return pinf shy; Main( ) x= erte(6); ,11.7 指针,指针就是变量的指针,即变量的地址。 例如:变量a的存放地址为1000,那么其指针就是1000。 指针变量就是用一个变量专门来存放另一个变量的地址,该变量称为指向变量的指针变量,简称指针变量。 如果定义一个变量ap专门用来存放1000,那么说a的指针变量就是ap。,例,指针变量的定义,定义的一般形式: 类型识别符 *指针变量名; 例 int *ap 指针变量的引用 指针变量的引用是通过取地址运算符“,指针运算,*ap与a是等价的,即*ap=a。 &*ap:由于*ap与a等价,则&*ap与&a等价。 * & a:由于ap与&a等价,则*&a与*ap等价,即*&a与*a等价。 *ap+相当于a+。,11.8 C51的程序应用,11.8.1 延时程序 【例11-10】系统时钟fosc=6MHz,1ms的延时程序: #include void delay1ms() unsigned char i; for(i=0;i166;i+) ; ,11.8.2 DAC0832波形生成程序,【例11-11】 0832的地址为07FFFH,P1.0与一拔码开关相连,要求P1.0接高电平时输出锯齿波,P1.0接低电平时,输出方波。程序如下: #include #include /*内部包含了允许直接访问8051不同区域存储器的宏*/ #define dac0832 XBYTE0x7fff /* XBYTE 是absacc.h 内部函数,允许8051访问片外RAM,0832端口地址7FFFH*/ sbit P10=P10; void delay(unsigned char timer) /*延时程序*/ while(-timer); void saw(void) /*锯齿波发生函数*/ unsigned char i; for (i=0;i255;i+) dac0832=i; ,void square(void) /* 方波发生函数*/ dac0832=0x00; delay(0x7f); dac0832=0xff; delay(0x7f); void main(void) unsigned char ctl; ctl=P10; /*波形控制*/ if(ctl=1) for(; ;) saw(); /*生成锯齿波 */ else for(; ;) square(); /* 生成方波 */ ,第11章 单片机C51程序设计C51语言概述在学会使用汇编语言后,学习C语言编程是一件比较容易的事。下面是一个简单的例子:89S52的P1引脚上接8个发光二极管,我们的任务是让接在P1引脚上的发光二极管按要求发光。 111简单的C程序介绍例1-1:让接在P1.0引脚上的LED发光。/*/单灯闪烁程序/*/#include“reg51.h”sbitP1_0=P10;voidmain( )P1_1=0;这个C语言程序包含了哪些信息 1.“文件包含”处理所谓“文件包含”是指一个文件将另外一个文件的内容全部包含进来,所以这里的程序虽然只有4行,但C编译器在处理的时候却要处理几十或几百行。这里程序中包含REG51.h文件的目的是为了要使用P1这个符号,即通知C编译器,程序中所写的P1是指80C51单片机的P1端口而不是其它变量。reg51.h 文件包含以下内容:/*-REG51.HHeaderfileforgeneric80C51and80C31microcontroller.Copyright(c)1988-2001KeilElektronikGmbHandKeilSoftware,Inc.Allrightsreserved.- - -*/*BYTERegister*/sfrP0=0x80;sfrP1=0x90;sfrP2=0xA0;sfrP3=0xB0;sfrPSW=0xD0;sfrACC=0xE0;sfrB=0xF0;sfrSP=0x81;sfrDPL=0x82;sfrDPH=0x83;sfrPCON=0x87;sfrTCON=0x88;sfrTMOD=0x89;sfrTL0=0x8A;sfrTL1=0x8B;sfrTH0=0x8C;sfrTH1=0x8D;sfrIE=0xA8;sfrIP=0xB8;sfrSCON=0x98;sfrSBUF=0x99;/*BITRegister*/*PSW*/sbitCY=0xD7;sbitAC=0xD6;sbitF0=0xD5;sbitRS1=0xD4;sbitRS0=0xD3;sbitOV=0xD2;sbitP=0xD0;/*TCON*/sbitTF1=0x8F;sbitTR1=0x8E;sbitTF0=0x8D;sbitTR0=0x8C;sbitIE1=0x8B;sbitIT1=0x8A;sbitIE0=0x89;sbitIT0=0x88;/*IE*/sbitEA=0xAF;sbitES =0xAC;sbitET1=0xAB;sbitEX1=0xAA;sbitET0=0xA9;sbitEX0=0xA8;/*IP*/sbitPS=0xBC;sbitPT1=0xBB;sbitPX1=0xBA;sbitPT0=0xB9;sbitPX0=0xB8;/*P3*/sbitRD=0xB7;sbitWR=0xB6;sbitT1=0xB5;sbitT0=0xB4;sbitINT1=0xB3;sbitINT0=0xB2;sbitTXD=0xB1;sbitRXD=0xB0;/*SCON*/sbitSM0=0x9F;sbitSM1=0x9E;sbitSM2=0x9D;sbitREN=0x9C;sbitTB8=0x9B;sbitRB8=0x9A;sbitTI=0x99;sbitRI=0x98;注意:sfrP1=0x90;这样的一行(上文中用黑体表示),即定义P1与地址0x90对应,P1口的地址就是0x90(0x90是C语言中十六进制数的写法,相当于汇编语言中写90H)。sfr是标准C语言的关键字,而是Keil为能直接访问80C51中的SFR而提供了一个新的关键词,其用法是:sfrt变量名=地址值。2.符号P1_0来表示P1.0引脚在C语言里,如果直接写P1.0,C编译器并不能识别,而且P1.0也不是一个合法的C语言变量名,所以得给它另起一个名字,这里起的名为P1_0,可是P1_0是不是就是P1.0呢?你这么认为,C编译器可不这么认为,所以必须给它们建立联系,这里使用了KeilC的关键字sbit来定义,sbit的用法有三种:第一种方法:sbit位变量名地址值第二种方法:sbit位变量名SFR名称变量位地址值第三种方法:sbit位变量名SFR地址值变量位地址值如定义PSW中的OV可以用以下三种方法:sbitOV=0xd2(1)说明:0xd2是OV的位地址值sbitOV=PSW2(2)说明:其中PSW必须先用sfr定义好sbitOV=0xD02(3)说明:0xD0就是PSW的地址值因此这里用sfrP1_0=P10;就是定义用符号P1_0来表示P1.0引脚,如果你愿意也可以起P10一类的名字,只要下面程序中也随之更改就行了。3.main称为“主函数”。每一个C语言程序有且只有一个主函数,函数后面一定有一对大括号“ ”,在大括号里面书写其它程序。从上面的分析我们了解了部分C语言的特性,下面再看一个稍复杂一点的例子。例1-2让接在P1.0引脚上的LED闪烁发光/*单灯闪烁程序*/#includereg51.h#defineucharunsignedchar#defineuintunsignedintsbitP10=P10;/*延时程序由Delay参数确定延迟时间*/voidmDelay(unsignedintDelay)unsignedinti;for(;Delay0;Delay-)for(i=0;i124;i+);voidmain()for(;)P10=!P10;/取反P1.0引脚mDelay(1000);程序分析:程序第二行是“P1_0=!P1_0;”,在P1_0前有一个符号“!”,符号“!”是C语言的一个运算符,就像数学中的“+”、“-”一样,是一种运算任号,意义是“取反”,即将该符号后面的那个变量的值取反。注意:取反运算只是对变量的值而言的,并不会自动改变变量本身。可以认为C编译器在处理“!P1_0”时,将P1_0的值给了一个临时变量,然后对这个临时变量取反,而不是直接对P1_0取反,団此取反完毕后还要使用赋值符号(“”)将取反后的值再赋给P1_0,这样,如果原来P1.0是低电平(LED亮),那么取反后,P1.0就是高电平(LED灭),反之,如果P1.0是高电平,取反后,P1.0就是低电平,这条指令被反复地执行,接在P1.0上灯就会不断“亮”、“灭”。for(;),这行程序连同其后的一对大括号“”构成了一个无限循环语句,该大括号内的语句会被反复执行。第三行程序是:“mDelay(1000);”,这行程序的用途是延时1s时间。这里mDelay(1000)并不是由KeilC提供的库函数。在下面的程序中有voidmDelay() 一段,如果你的程序中没有这么一段程序行,那就不能使用mDelay(1000)了。 mDelay后面有一个小括号,小括号里有数据(1000),这个1000被称之“参数”,用它可以在一定范围内调整延时时间的长短,这里用1000来要求延时时间为1000毫秒。C语言的一些特点1、C程序是由函数构成的,一个C源程序至少包括一个函数,一个C源程序有且只有一个名为main()的函数,也可能包含其它函数,因此,函数是C程序的基本单位。主程序通过直接书写语句和调用其它函数来实现有关功能,这些其它函数可以是由C语言本身提供给我们的,这样的函数称之为库函数,也可以是用户自己编写的,这样的函数称之为用户自定义函数。那么库函数和用户自定义函数有什么区别呢?简单地说,任何使用KeilC语言的人,都可以直接调用C的库函数而不需要为这个函数写任何代码,只需要包含具有该函数说明的相应的头文件即可;而自定义函数则是完全个性化的,是用户根据自己需要而编写的。KeilC提供了100多个库函数供我们直接使用。2、一个函数由两部份组成:(1)函数的首部、即函数的第一行。包括函数名、函数类型、函数属性、函数参数(形参)名、参数类型。例如:voidmDelay(unsignedintDelayTime)一个函数名后面必须跟一对圆括号,即便没有任何参数也是如此。(2)函数体,即函数首部下面的大括号“”内的部份。如果一个函数内有多个大括号,则最外层的一对“”为函数体的范围。函数体一般包括:声明部份:在这部份中定义所用到的变量,执行部份:由若干个语句组成。C51的一般格式如下:类型 函数名(参数表)参数说明; 数据说明部分; 执行语句部分; 在某此情况下也可以没有声明部份,甚至即没有声明部份,也没有执行部份,如:voidmDelay()这是一个空函数,什么也不干,但它是合法的。通过上述的几个例子,可以得出一些结论:在编写程序时,可以利用空函数,比如主程序需要调用一个延时函数,可具体延时多少,怎么个延时法,暂时还不清楚,我们可以主程序的框架结构弄清,先编译通过,把架子搭起来再说,至于里面的细节,可以在以后慢慢地填,这时利用空函数,先写这么一个函数,这样在主程序中就可以调用它了。3、一个C语言程序,总是从main函数开始执行的,而不管物理位置上这个main( )放在什么地方。4、主程序中的mDelay如果写成mdelay就会编译出错,即C语言区分大小写,这一点往往让初学者非常困惑,尤其是学过一门其它语言的人,有人喜欢,有人不喜欢,但不管怎样,你得遵守这一规定。5、C语言书写的格式自由,可以在一行写多个语句,也可以把一个语句写在多行。没有行号(但可以有标号),书写的缩进没有要求。但是建议读者自己按一定的规范来写,可以给自己带来方便。6、每个语句和资料定义的最后必须有一个分号,分号是C语句的必要组成部份。7、可以用/*.*/的形式为C程序的任何一部份作注释。 KeilC也支持C+风格的注释,就是用“/”引导的后面的语句是注释,例:P1_0=!P1_0;/取反P1.0这种风格的注释,只对本行有效,所以不会出现上面的问题,而且书写比较方便,所以在只需要一行注释的时候,我们往往采用这种格式。但要注意,只有KeilC支持这种格式,早期的FranklinC以及PC机上用的TC都不支持这种格式的注释,用上这种注释,编译时通不过,会报告编译错误。11.2 C51的数据结构C51的常量与变量 其值不能改变的量称为常量。常量可以有不同的数据类型。如0,1,2,-3为整型常量;4.6,-1.23等为实型常量;a、为字符型常量。可以用一个标识符号代表一个常量。在程序运行中,其值可以改变的量称为变量。一个变量主要由两部分构成:一个是变量名,一个是变量值。每个变量都有一个变量名,在内存中占据一定的存储单元(地址),并在该内存单元中存放该变量的值。 #define CONST 60main( )int var,res;var=20;res=var*CONSTprintf(“res=%dn”,res);程序运行结果:res=1200在程序开头define CONST 60这一行定义了一个符号常量CONST,其值为60。这样在后面的程序中,凡是出现CONST的地方,都代表常量60。 11.3 C51 的运算符和表达式1. 赋值运算符和表达式变量表达式;例如:tmp9;/*将常数9赋给变量tmp */ij8;/*将常数8同时赋给变量i和j*/C51提供了10种复合运算符:+=、-=、*=、/=、%=、=、&=、=、!=。 2. 算术运算符和算术表达式C51有+、-、*、/、% 五种运算符3. 关系运算符 4. 逻辑运算符C语言中有3种逻辑运算符:(1)逻辑非(!) (2)逻辑与(&) (3)逻辑或(|) 5. 逗号运算符在C51语言中,逗号“,”是一个特殊的运算符,可以用它将两个(或多个)表达式连接起来,称为逗号表达式。 6. 条件运算符表达式“? :”是C51中唯一的三目运算符,要求有3个运算对象,它将三个表达式连接构成一个条件表达式。7. 自增和自减运算符C51语言中,除了基本的加、减、乘、除运算符之外,还提供一种特殊的运算符:“+”自增运算符;“-”自减运算符。 8. 指针和地址运算符指针在C51语言中指示变量的地址,另外,还可以定义一个指向某个变量的指针变量。为了表示指针变量和它所指向的变量地址之间的关系,C51语言提供了两个专门的运算符:取内容()和取地址(&)。9. 位运算符位运算符的作用是按位对变量进行运算,并不改变参与运算的变量的值。 10. 强制类型转换运算符强制类型转换运算符的作用是将表达式或变量的类型强制转换成所指定的类型。在C51程序中进行算术运算时,编译器自动处理数据类型转换。当自动类型转换不能实现目的时,可以使用强制类型转换。强制类型转换的一般格式为:(类型名)(表达式)例如:(double) a/*将a转换成double类型*/ (int) (x+y) /*将x+y的值转换成整型*/ 11.3.2 运算符的优先级和结合性在表达式中,不同运算符连接的对象的运算顺序不完全按照表达式中书写的先后顺序进行的,各运算符参与运算的先后顺序不仅要遵守运算符优先级别的规定,还要受运算符结合性的制约。 11.4 C51的存储结构11.4.1 存储区域8051单片机有4个存储空间:片内程序存储空间,片外程序存储空间,片内数据存储空间和片外数据存储空间。 11.4.2存储模式1. Small模式2. 紧凑模式(Compact)模式3. Large模式4. 混合存储模式11.5 C51的基本程序结构1.If语句(1)If (条件表达式) 动作 如果条件表达式的值为真(非零的数),则执行 内的动作,如果条件表达式为假,则略过 该动作继续往下执行。(2) If (条件表达式) 动作 1 else 动作 2 如果条件表达式的值为真(非零的数),则执行动作1,(则略过else)如果条件表达式为假,则执行动作2。(3)If (条件表达式1) 动作 1 else if (条件表达式2) 动作 2 else if (条件表达式3) 动作 3 else 动作 4 2switch-case语句switch (条件表达式)case条件值1:动作1break;case条件值2:动作2break;case条件值3动作3break;default:动作4break;switch内的条件表达式的结果必须为整数或字符。switch以条件表达式的值来与各case的条件值对比,如果与某个条件值相符合,则执行该case的动作,如果所有的条件值都不符合,则执行default的动作,每一个动作之后一定要写break,否则会有错误。 case之后的条件值必须是数据常数,不能是变量。 任何由switch、for、while、do-while构成的循环,都可以用break来跳出,必须注意的是break一次只能跳出1层循环。例1void switch Dem(void)switch (Outputstate)case 1:P1_0=0;P1_1=0;Pl_2=0;break;case 2:P1_0=1;P1_1=0;P1_2=0;break;default:break; 3while循环语句while (条件表达式)动作先测试条件表达式是否成立,当条件表达式为真时,则执行循环内动作,做完后又继续跳回条件表达式作测试,如此反复直到条件表达式为假为止。例2while(P1_0= =0) /先测试条件:表达式,成立后再执行动作Delayxlms(1);If(Pl_0= =0)Dutycount+;4do-while循环语句 do 动作while (条件表达式);先执行动作后,再测试条件表达式是否成立。当条件表达式为真,则继续回到前面执行动作,如此反复直到条件表达式为假为止,使用时要避免条件永真,造成死循环。例3void DowhileDem。(void)Byte i=0,j,k;Byte soundLong,soundTone;Word m;do /先执行动作后soundLong=MUSIC_SOUNDLONGli;soundTone=MUSIC SOUNDTONEli;i+;for j=0; jSoundLong;j+/sound longfor (k=0; k12;k+)for(m=0;mSound Tone*l; m+)Pl_0=0;for(m=0;mSound Tone*l; m+)Pl_0=1; delay50us(6);while (MUS
- 温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

人人文库网所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。