740 likes | 896 Views
单片机接口及 C 程序设计. 广东机电职业技术学院 智能电子教研室. 项目二 8051 C 语言基本应用. 2.1 8051 数据类型. 1 、数据与数据类型. ( 1 )关键字与标识符. 标识符: 是用来标识源程序中某个对象的名字的,这些对象可以是语句、数据类型、函数、变量、数组等等。 C 语言是大小字敏感的一种高级语言,如果我们要定义一个定时器 1 ,可以写做“ Timer1” ,如果程序中有“ TIMER1” ,那么这两个是完全不同定义的标识符。标识符由字符串,数字和下划线等组成,注意的是第一个字符必须是字母或下划线.
E N D
单片机接口及C程序设计 广东机电职业技术学院 智能电子教研室
项目二 8051 C语言基本应用 2.1 8051数据类型 1、数据与数据类型
(1)关键字与标识符 标识符:是用来标识源程序中某个对象的名字的,这些对象可以是语句、数据类型、函数、变量、数组等等。 C 语言是大小字敏感的一种高级语言,如果我们要定义一个定时器1,可以写做“Timer1”,如果程序中有“TIMER1”,那么这两个是完全不同定义的标识符。标识符由字符串,数字和下划线等组成,注意的是第一个字符必须是字母或下划线 关键字:则是编程语言保留的特殊标识符,它们具有固定名称和含义,在程序编写中不允许标识符与关键字相同。 在KEIL uVision2 中的关键字除了有ANSI C 标准的32个关键字外 还根据51 单片机的特点扩展了相关的关键字。其实在KEIL uVision2 的文本编辑器中编写C 程序,系统可以把保留字以不同颜色显示,缺省颜色为天蓝色。
(2) int 整型 int 整型长度为两个字节,用于存放一个双字节数据。分有符号int 整型数signed int和无符号整型数unsigned int,默认值为signed int类型。 (3) long 长整型 long长整型长度为四个字节,用于存放一个四字节数据。分有符号long长整型signed long和无符号长整型unsigned long,默认值为signed long类型。 (4) float 浮点型 占用四个字节
(5)* 指针型 指针型本身就是一个变量,在这个变量中存放的指向另一个数据的地址。这个指针变量要占据一定的内存单元,对不同的处理器长度也不尽相同,在C51 中它的长度一般为1~3个字节。指针变量也具有类型。 (6) bit 位标量 bit 位标量是C51 编译器的一种扩充数据类型,利用它可定义一个位标量,但不能定义位指针,也不能定义位数组。它的值是一个二进制位,不是0就是1,类似一些高级语言中的Boolean 类型中的True 和False。
(7) sfr 特殊功能寄存器 sfr 也是一种扩充数据类型,点用一个内存单元,值域为0~255。利用它可以访问51单片机内部的所有特殊功能寄存器。如用sfr P1 = 0x90这一句定P1 为P1 端口在片内的寄存器,在后面的语句中我们用以用P1 = 255(对P1 端口的所有引脚置高电平)之类的语句来操作特殊功能寄存器。 (8)sfr16 16 位特殊功能寄存器 sfr16 占用两个内存单元,值域为0~65535。sfr16 和sfr 一样用于操作特殊功能寄存器,所不同的是它用于操作占两个字节的寄存器,如定时器T0和T1。
(9) sbit 可录址位 sbit 同位是C51 中的一种扩充数据类型,利用它可以访问芯片内部的RAM 中的可寻址位或特殊功能寄存器中的可寻址位。 如先前我们定义了 sfr P1 = 0x90; //因P1 端口的寄存器是可位寻址的,所以我们可以定义 sbit P1_1 = P1^1; //P1_1 为P1 中的P1.1 引脚 //同样我们可以用P1.1 的地址去写,如sbit P1_1 = 0x91; 这样我们在以后的程序语句中就可以用P1_1 来对P1.1 引脚进行读写操作了。
2 常量与变量 常量:在程序运行过程中,其值不能改变的量 变量:在程序运行中,其值可以改变的量。 #define CONST 60 void main() { int variable, result ; variable = 20; result = variable * CONST ; printf(“result = %d\n”,result); }
3、Cx51存储器类型与8051存储器间的对应关系 8051单片机存储器结构
Cx51存储类型及其大小和值域 此表值得商榷
变量的存储类型定义举例: char data char1 ; bit bdata flags ; float idata s ; unsigned char name[3][20] ;
4、存储模式 存储模式决定了变量默认存储类型、参数传递区和存储类型说明变量的存储类型。 定义一个变量的格式如下: [存储种类] 数据类型 [存储器类型] 变量名表 存储种类有四种: 自动(auto),外部(extern),静态(static)和寄存器(register),缺省类型为自动(auto)。
P63 注:如果省略存储器类型,系统则会按编译模式SMALL,COMPACT或 LARGE所规定的默认存储器类型去指定变量的存储区域。
7、位变量(BIT)及其定义 1、位变量Cx51定义的语法 例如: bit direction_bit ; bit lock_pointer; bit display_invers ; 2、sbit定义特殊位 程序举例。
void main(void) //主函数名 { //这是第一种注释方式 unsigned int a; //定义变量a 为int 类型 /* 这是第二种注释方式 */ do{ //do while 组成循环 for (a=0; a<50000; a++); //这是一个循环 P1_0 = 0; //设P1.0 口为低电平,点亮LED for (a=0; a<50000; a++); //这是一个循环 P1_0 = 1; //设P1.0 口为高电平,熄灭LED } while(1); }
8、 Cx51构造数据类型 字符型(char)、整型(int)和浮点型(float)等数据,都属于基本数据类型。 C语言还提供了一些扩展的数据类型。它们是对基本数据类型的扩展,称之为构造数据类型。些按一定规则构成的数据类型有:数组、结构、指针、共用体和枚举等。
数 组 数组是一组具有固定数目和相同类型成分分量的有序集合。其成分分量的类型为该数组的基本类型. 如整型变量的有序集合称为整型数组,字符型变量的有序集合称为字符型数组。这些整型或字符型变量是各自所属数组的成分分量,称为数组元素。 注: 1、构成一个数组的各元素必须是同一类型的变量,不允许在同一数组中出现不同类型的变量。 2、数组数据是用同一个名字的不同下标访问的,数组的下标放在方括号中,而且下标从0开始
一维数组 1.一维数组的定义方式 类型说明符 数组名[整型表达式] 2.数组的初始化 ①在定义数组时对数组的全部元素赋予初值。 例: int idata a[6]={0,l,2,3,4,5} ; ②只对数组的部分元素初始化。 例: int idata a[10]={0,l,2,3,4,5} ; ③在定义数组时,若不对数组的全部元素赋初值,则数组的全部元素被缺省地赋值为0。
二维数组 1.二维数组定义的一般形式 类型说明符数组名[常量表达式][常量表达式]; 例 int data char[3][8] ; 二维数组的存取顺序是: 按行存取,先存取第一行元素的第O列,1列,2列,……,直到第一行的最后一列;然后返回到第二行开始,再取第二行的第O列,1列,……,直到第二行的最后一列。如此顺序下去,直到最后一行的最后一列。
2.二维数组的初始化 (1)对数组的全部元素赋初值 ①分行给二维数组的全部元素赋初值 ②也可以将所有数据写在一个花括号内,按数组的排列顺序对各元素赋初值 (2)对数组中部分元素赋初值
2.2 运算符与表达式 1. 算术运算符及其表达式 +加法运算符,或正值符号; -减法运算符,或负值符号; * 乘法运算符; /除法运算符; %模(求余)运算符。 算术表达式——用算术运算符和括号将运算对象连接起来的式子称为算术表达式。其中的运算对象包括常量、变量、函数、数组和结构等 优先级——指当运算对象两侧都有运算符时,执行运算的先后次序。 结合性——指当一个运算对象两侧的运算符的优先级别相同的运算顺序。 算术运算符的优先级规定为:先乘除模,后加减,括号最优先。
2、Cx51关系运算符、表达式及优先级 < 小于 >大于 <=小于或等于 >=大于或等于 ==测试等于 != 测试不等于 • 前4种关系运算符(<、>、<=、>=)优先级相同,后两种也相同;前4种优先级高于后两种。 • 关系运算符的优先级低于算术运算符。 优先级 • 关系运算符的优先级高于赋值运算符。 算术运算符 • 关系运算符的结合性为从左至右 关系运算符 • 关系运算符:用关系运算符将两个表达式 赋值运算符 • (可以是算术表达式、关系表达式、逻辑表达式及字符表达式等)连接起来的式子称为关系表达式 • 关系表达式的结果:由于关系运算符总是二目运算符,故它作用在运算对象上产生的结果为一个逻辑值,即真或假。C语言以1代表真,以0代表假。 (高) ↑ ↑ (低)
3、Cx51逻辑运算符、表达式及优先级 &&逻辑“与”(AND) || 逻辑“或”(OR) ! 逻辑“非”(NOR) “&&”和“||”是双目运算符,要求有两个运算对象;而“!”是单目运算符,只要求有一个运算对象。 优先级 (高) !(非) 算术运算符 关系运算符 &&和|| 赋值运算符 Cx51逻辑运算符与算术运算符、关系运算符和赋值运算符之间优先级的次序:“!”(非)优先级最高,算术运算符次之,“&&”和“||”一再再次之,最低为赋值运算符。 ↑ ↑ ↑ • 逻辑表达式的结合性为自左向右 • 逻辑表达式:用逻辑运算符关系运算符或逻辑量连接起来的式子称为逻辑表达式。 • 逻辑表达式的值应该是一个逻辑量真或假 • 逻辑表达式的值与关系表达式的值相同,以0代表假,以1代表真。 ↑ (低)
4、Cx51位操作及其表达式 & 按位与 | 按位或 ^按位异或 ~ 按位取反 <<位左移 >> 位右移 • 除了按位取反运算符“~”以外,以上位操作运算符都是两目运算符,即要求运算符两侧各有一个运算对象。 • 位运算只能是整型或字符型数,不能为实型数据。 • “&”:参加运算的两个运算对象,若两者相应的位都为1,则该位结果值为1,否则为0。 • “|”:参加运算的两个对象,若两者相应的位中有一个为1,则该位结果为1。 • “^”:参加运算的两个对象,若两者相应的位值相同,则结果为0;若两者相应的位值相异,则结果为1。 • “~”是一个单目运算符,用来对一个二进制数按位进行取反,即0变1,1变0。 • 位左移、位右移运算符“<<”和”>>”,用来将一个数的各二进制位的全部左移或右移若干位;移位后,空白位补0,而溢出位舍弃。
5、自增减运算符、复合运算符及其表达式 • 自增减运算的作用是使变量值自动加1或减1。如: • ++i、--i在使用之前,先使i值加(减)1。 • i++、i--在使用之后,再使i值加(减)1。 • 粗略地看,++i和i++的作用都相当于i=i+1,但++i和i++的不同之处在于++i先执行i=i+1,再使用i的值;而i++则是先使用i的值,再执行i=i+1。 • 注意: • 自增运算(++)和自减运算 (--)只能用于变量,而不能用于常量表达式。 • (++)和(--)的结合方向是“自右向左”。 凡是二目运算符,都可以与赋值运算符“=”一起组成复合赋值运算符。Cx51共提供10种复合赋值运算符,即:+=,-+,*=,/=,%=,<<=,>>=,&=,^=,|= a+=b 相当于 a=a+b a-=b 相当于 a=a-b a*=b 相当于 a=a*b a/=b 相当于 a=a/b a%=b 相当于 a=a%b a<<=b 相当于 a=a<<b a>>=b 相当于 a=a>>b …… 等等
2.3 流程控制 C语言有3种基本结构: 顺序结构 选择结构 循环结构
1、顺序结构及其流程图 main( ) { loop1: P0=shuma[k/10000]; P2=0xf7; for(i=0;i<100;i++); P0=shuma[k%10000/1000]; P2=0xef; for(i=0;i<100;i++); P0=shuma[k%1000/100]; P2=0xdf; for(i=0;i<100;i++); P0=shuma[k%100/10]; P2=0xbf; for(i=0;i<100;i++); P0=shuma[k%10]; P2=0x7f; for(i=0;i<100;i++); goto loop1; } A B
2、选择结构及选择语句 在选择结构中,程序首先对一个条件语句进行测试。当条件为真(True)时,执行一个方向上的程序流程;当条件为假(False)时,执行另一个方向上的程序流程。如图所示,P代表一个条件。当P条件成立(为真)时,执行A操作,否则执行B操作;但两者只能选择其一。两个方向上的程序流程最终将汇集到一起,从一个出口中退出。 P为真? A B
常见的选择语句有:if、else if语句。 选择结构可以派生出另一种基本结构——多分支结构。在多 分支结构中口分为串行多分支结构和并行多分支结构两种情况 程序示例: #include<reg51.h> sbit P37=P3^7; main( ) { loop1: if(P37==1) { P0=0x00; P2=0xff;} else { P0=0xff; P2=0x00;} goto loop1; }
start N Y P3.1=0 Y N P3.2=0 P3.2=0 N Y Yellow Green Red END (1)程序流程框图 (2)依照该流程图编写程序。
并行多分支语句:开关语句 switch语句的一般形式如下: switch(表达式) { case常量表这式1:{语句1;}break; case常量表达式2:{语句2;)break; i case常量表达式n:{语句n;}break; default :{语句n+1;} }
多分支语句:开关语句 void Lcd12864_Location_XY(uchar x,uchar y) { switch(y) { case 0: y=0x80;break; case 1: y=0x90;break; case 2: y=0x88;break; case 3: y=0x98;break; default: y=0x80; } x=x&0x07; Lcd12864_Write_Command(x+y); }
2、循环语句 在许多实际问题中。需要进行具有规律性的重复操作,如求累加和、数据块的搬移等。而计算机的基本特性之一就是具有重复执行一组语句的能力,即循环能力。利用这种循环能力,程序员只要编写一个包含重复执行语句的简短程序,就能执行所需的成千上万次的重复操作。 几乎所有的实用程序都包含有循环结构。循环结构是结构化程序设计的3种基本结构之一。它和顺序结构、选择结构一起共同作为各种复杂程序的基本构造单元。 作为构成循环结构的循环语句,一般是由循环体及循环终止条件两部分组成的。一组被重复执行的语句称为循环体,能否继续重复执行下去,则取决于循环终止条件。 在C语言中用来实现循环的语句有3种:while语句、do while语句、for语句
进入WHILE循环 N 表达式为真? Y 循环体内重复 操作语句 退出WHILE循环 执行下面的语句 while语句 while语句的一般形式为: while(表达式) {语句/*循环体*/} 在这里,表达式是while循环能否继续的条件,而语句部分是循环体,是执行重复操作的部分。只要表达式为真,就重复执 循环体内的语句;反之,则终止while循环,执行循环之外的下一语句。
进入DO WHILE循环 循环体内语句 Y 表达式为真? N 循环体外下一个语句 do while语句 do while语句的一般形式为: do {语句/*循环体*/} while(表达式); do while循环语句的执行过程如下: 首先执行循环体语句,然后执行圆括号中的表达式。如果表达式的结果为真(1),则循环继续,并再一次执行循环语句。只有当表达式的结果为假(0)时,循环才会终止,并以正常方式执行程序后面的语句。
for 循环语句 在c语言中,for循环语句是循环语句中最为灵活也是最为复杂的一种。 它不仅可以用于循环次数已经确定的情况,而且可以用于循环次数不确定但已经给出循环条件的情况。它既可以包含一个索引计数变量,也可以包含任何一种表达式。除了被重复的循环指令体外,表达式模块由3部分组成: 第一部分是初始化表达式。对c语言而言,任何表达式在开始执行时都应该做一次初始化。 第二部分是对结束循环进行测试。对c语言而言,可以是任何一种测试,一旦测试为假,就会结束循环。 第三部分是尺度增量。
for(表达式l;表达式2;表达式3) {语句;) /*循环体*/ for循环的语句执行过程如下: ①先对表达式1赋初值,进行初始化。 ②判断表达式2是否满足给定的循环条件,若满足循环条件,则执行循环体内语句,然后执行第③步;若不满足循环条件,则结束循环,转到第⑤步。 ③若表达式2为真,则在执行指定的循环语句后,求解表达式3。 ④回到第②步继续执行。 ⑤退出for循环,执行下面一条语句。
程序举例: for循环的语句执行过程如下: ①先对表达式1赋初值,进行初始化。 ②判断表达式2是否满足给定的循环条件,若满足循环条件,则执行循环体内语句,然后执行第③步;若不满足循环条件,则结束循环,转到第⑤步。 ③若表达式2为真,则在执行指定的循环语句后,求解表达式3。 ④回到第②步继续执行。 ⑤退出for循环,执行下面一条语句。 int i,sum ; sum = 0 ; for(i=0; i<10;i++) sum+=i ;
2.3.1 模拟交通灯 1、软件实现 #include<reg51.h> sbit S2=P3^2; sbit S3=P3^3; void main() { while(1) { if( S2==0) if(S3==0) P1=0x7f; // Yellow light on else P1=0xdf; // Red light on else if(S3==0) P1=0xbf; //Green light on else P1=0x7f; // Yellow light on } }
2.4 数码管显示(数组的应用) 2.4.1 数码管的原理 1、数码管内部结构
LED数码管分类: 按其内部结构可分为共阴型和共阳型; 按其外形尺寸有多种形式,使用较多的是0.5"和0.8"; 按显示颜色也有多种形式,主要有红色和绿色; 按亮度强弱可分为超亮、高亮和普亮。 正向压降一般为1.5~2V,额定电流为10mA,最大电流为40mA。
3、静态显示方式及其典型应用电路 LED数码管显示分类:静态显示方式和动态显示方式。 ⑴ 静态显示方式:每一位字段码分别从I/O控制口输出,保持不变直至CPU刷新。 特点:编程较简单,但占用I/O口线多,一般适用于显示位数较少的场合。 ⑵ 动态显示方式:在某一瞬时显示一位,依次循环扫描,轮流显示,由于人的视觉滞留效应,人们看到的是多位同时稳定显示。 特点:占用I/O端线少,电路较简单,编程较复杂,CPU要定时扫描刷新显示。一般适用于显示位数较多的场合。