第4章_单片机的C51编程语言课件

PPT
  • 阅读 44 次
  • 下载 0 次
  • 页数 92 页
  • 大小 341.001 KB
  • 2022-11-24 上传
  • 收藏
  • 违规举报
  • © 版权认领
下载文档30.00 元 加入VIP免费下载
此文档由【小橙橙】提供上传,收益归文档提供者,本网站只提供存储服务。若此文档侵犯了您的版权,欢迎进行违规举报版权认领
第4章_单片机的C51编程语言课件
可在后台配置第一页与第二页中间广告代码
第4章_单片机的C51编程语言课件
可在后台配置第二页与第三页中间广告代码
第4章_单片机的C51编程语言课件
可在后台配置第三页与第四页中间广告代码
第4章_单片机的C51编程语言课件
第4章_单片机的C51编程语言课件
还剩10页未读,继续阅读
【这是免费文档,您可以免费阅读】
/ 92
  • 收藏
  • 违规举报
  • © 版权认领
下载文档30.00 元 加入VIP免费下载
文本内容

【文档说明】第4章_单片机的C51编程语言课件.ppt,共(92)页,341.001 KB,由小橙橙上传

转载请保留链接:https://www.ichengzhen.cn/view-44644.html

以下为本文档部分文字说明:

2024/12/41第4章单片机的C51编程语言(8学时)22024/12/4第4章单片机的C51编程语言◼4.1C51编程语言概述◼4.2C51的标识符和关键字◼4.3C51的变量与数据类型◼4.4C51语言的数组、指针与结构◼4.5C51的运算符

和表达式◼4.6C51语言的程序结构◼4.7C51语言的函数◼4.8中断服务程序◼4.9C51的预处理◼4.10C51的库函数◼4.11使用C5I编译器时的注意事项32024/12/44.1C51编程语言概述C语言是一种结构化语言,可产生紧凑代码C语言可以进行许多机器级函数控制而不用汇编语言

。C语言目前已成为电子工程师进行单片机系统编程时的首选编程语言。用C语言来编写目标系统软件,会大大缩短开发周期,且明显地增加软件的可读性,便于改进和扩充。基于51系列单片机的C语言或C语言编译器简称为C51语言

或C51。42024/12/44.1.1C51语言编程与汇编语言编程相比的优势1.可读性好、编程调试灵活方便2.生成的代码编译效率高3.完全模块化4.可移植性好5.便于项目维护管理52024/12/44.1.2单片机C51与标准ANSlC编译器的主要区别以Keil公司的KeilC5l

(以下简称C5l)编译器为例⚫C5l系列头文件集中体现了各系列芯片的不同功能⚫C5l比ANSIC多一种“位”类型⚫数据存储类型有很大的区别⚫函数的使用上,由于单片机系统的资源有限,它的编译系统不允许太多

的程序嵌套⚫C5l与标准ANSIC库函数,由于部分库函数不适合单片机处理系统,因此被排除在外,如字符屏幕和图形函数。也有一些库函数继续使用,但这些库函数是厂家针对硬件特点相应开发的,它们与ANSIC的构成及用法都有很大的区别,如printf和s

canf。在ANSIC中这两个函数通常用于屏幕打印和接收字符,而在C5l中,它们则主要用于串行通信口数据的发送和接收。62024/12/44.1.3C51的开发过程例4-1设图1-2系统要求是:当S1闭合时

,报警灯亮;而S1打开时,报警灯灭。用C51语言编写实现该功能的程序,程序名为ex4-1.c:#include<reg51.h>//定义MCS-51的特殊功能寄存器SFRsbitP32=P3^2;//定义P3.2为P32sbitP20=P2

^0;//定义P2.0为P20main(){while(1){P32=1;if(P32==0){P20=1;}else{P20=0;}}}在C51中,使用“/**/”和“//”符号进行注释。注释不影响程序的功能,用

于说明程序的用途、功能,增加程序的可读性和可维护性。编译后注释不存在,不影响运行文件的大小。优秀的程序设计人员要养成良好的注释习惯,一般在程序的开始要写注释,表明程序的要求、功能,编写人员,编写日期,版本号等信息。72024/12/4使用任何文本编辑软件,或KEILC集成

的编辑系统书写C以上程序。使用KEILC的C51编译器和连接软件(用KEILC集成开发工具uVision中的Buildtarget批处理),生成可以写入单片机的目标文件,通常为HEX文件(ex4-1.hex)用程序烧录器将该文件写入单片机,单片机上电即可运行。同时Buildtarget还生

成许多中间文件,用于程序的调试,例如,从ex4-1.lst文件中可以看见C程序编译后生成的汇编程序,由此可以理解单片机硬件具体的执行过程,还可以对C程序编程的效率进行了解。82024/12/4ex4-1.lst文件0000?C0001

:0000D2B2SETBP32000220B204JBP32,?C00030005D2A0SETBP20000780F7SJMP?C00010009?C0003:0009C2A0CLRP20000B80F3SJMP?C0001可以看出,

C编译器编译的结果与我们大多人用汇编语言的编程结果相同,但是C51语言的可读性更好,特别是当程序更加复杂时,C51语言有明显的优势。92024/12/4C51程序的结构102024/12/4✓标识符用来标识源程序中某个对象的名字,这些对象可

以是语句、数据类型、函数、变量、数组等。✓C语言是区分大小写的一种高级语言。✓标识符由字符串、数字和下划线等组成,第一个字符必须是字母或下划线✓错误的标识符,编译时会有错误提示。✓C5l中有些库函数的标识符是以下划线开头的,所以一般不要以

下划线开头命名标识符。4.2C51的标识符和关键字112024/12/4表4-1ANSIC标准关键字关键字用途说明auto存储种类说明用于声明局部变量,为默认值break程序语句退出最内层循环体case程序语句switch语句中的选择

项char数据类型声明单字节整型数或字符型数据const存储种类说明在程序执行过程中不可修改的值continue程序语句转向下一次循环default程序语句switch语句中缺省选择项do程序语句构成do…while循环结构do

uble数据类型声明双精度浮点数else程序语句构成if…else条件结构enum数据类型声明枚举类型数据extern存储种类说明在其他程序模块中声明了的全局变量float数据类型声明单精度浮点数for程序语句构成for循环结构goto程序语句构成goto循环结构if程序语句构成if…else

条件结构int数据类型声明整型数122024/12/4long数据类型声明长整型数register存储种类说明使用CPU内部寄存器变量return程序语句函数返回short数据类型声明短整型signed数据类型声明有符号整型数sizeof运算符计算表达式或数据类型的字节数static存储种类说

明静态变量struct数据类型声明结构体类型数据switch程序语句构成switch选择结构typedef数据类型声明重新进行数据类型定义union数据类型声明联合类型数据unsigned数据类型声明无符号数据void数据类型声明无类型数据或函数volatile数据

类型声明声明该变量在程序执行中可被隐含地改变while程序语句构成while和do…while循环结构132024/12/4表4-2C51编译器扩充关键字关键字用途说明_at_地址定位为变量进行绝对地址定位_priority_多任务优先声明规定RTX51或RTX51Tiny的任务

优先级_task_任务声明定义实时多任务函数alien函数特性声明用于声明与PL/M51兼容的函数bdata存储器类型声明可位寻址的MCS-51内部数据存储器bit位变量声明声明一个位变量或位类型函数code存储器类型声明MCS-51的程序存储空间compact存储器模式按compact模式分配变

量的存储空间data存储器类型声明直接寻址MCS-51的内部数据寄存器142024/12/4idata存储器类型声明间接寻址MCS-51的内部数据寄存器interrupt中断函数声明定义一个中断服务函数large存储器模式按large模式分配变量的存储空间pdata存储器类型声明分页寻址的MCS-

5外部数据空间sbit位变量声明声明一个位变量sfr特殊功能寄存器声明声明一个8位特殊功能寄存器sfr16特殊功能寄存器声明声明一个16位特殊功能寄存器small存储器模式按small模式分配变量的存储空间using寄存器组定义定义MCS-5的工作寄存

器组xdata存储器类型声明定义MCS-5外部数据空间152024/12/44.3C51的变量与数据类型1.常量常量又称为标量,它的值在程序执行过程中不能改变,常量的数据类型有整型、浮点型,字符型和字符串型等。实际使用中用#define定义在程序中经常用

到的常量,或者可能需要根据不同的情况进行更改的常量,例如译码地址。而不是在程序中直接使用常量值。这样一方面有助于提高程序的可读性,另一方面也便于程序的修改和维护,例如:#definePI3.14//以后的编程中用PI代替浮点数常量3.14,便于阅读#defin

eSYSCLK12000000//长整型常量用SYSCLK代替12MHz时钟#defineTRUE1//用字符TRUE,在逻辑运算中代替1#defineSTAR‘*’//用STAR表示字符“*”#defineuintunsignedint//用uint代替unsignedint,简化编

辑4.3.1常量与变量162024/12/4例如语句:if(key==TRUE){},与语句if(key==1){}相同。C51语言(汇编语言也是同样)编辑时,除注释外,要使用英文符号,例如上述定义的字符“*”,在程序中是用英文的单引号,而不是中文符号单引号。由双引号作为界限符:当字符串中需要出现

双引号时,需使用转义字符“\”来表示。172024/12/4常量分为:1)整型常量。整型常量值:可用十进制表示,如128,-35等;也可以用十六进制表示,如0x1000。2)浮点型常量。如0.12、-10.3等。3

)字符型常量。字符型常量是用单引号括起来的一个字符,如‘A’、‘0’、‘=’等,编译程序将把这些字符型常量转换为ASCII码,例如‘A’等于0x41。对于不可显示的控制字符,可直接写出字符的ASCII码,或者在字符前加上反斜杠“\”组成转义符。转义符可以完成一

些特殊功能和格式控制。4)字符串型常量。字符串型常量用一对双引号括起一串字符来表示,如“Hello”、“OK”等字符串型常量182024/12/4表4-3常用的转义符转义字符含义ASCII码16进制(10进制)\0空字符(NULL)0x00\n换行符(LF)0x0

A\r回车符(CR)0x0D\t水平制表符(HT)0x09\’单引号0x27\”双引号0x22\\反斜杠0x5C192024/12/42、变量变量是一种在程序执行过程中,其数值不断变化的量。C51规定变量必须先定义后使用。C51的变量主要有表4-4中的各种数据类型,而sf

r、sfr16、sbit三种数据类型用于对MCS-51单片机的特殊功能寄存器(SFR)的操作,不是我们传统意义上的变量。C51对变量定义的格式如下:[存储种类]数据类型[存储器类型]变量名表202024/12/4[存储种类]数据类型[存储

器类型]变量名表auto(自动)extern(外部)static(静态)register(寄存器)DATA区BDATA区IDATA区PDATA区XDATA区CODE区unsignedcharsignedcharunsignedintsign

edintunsignedlongsignedlongfloat*指针bitsfr、sfr16、sbit。212024/12/4存储种类变量的存储种类反映了变量的作用范围和寿命,将影响到编译器对变量在RAM中位置的安

排。C51有四种存储种类:auto(自动)、extern(外部)、static(静态)、register(寄存器)。如果不声明变量的存储种类,则该变量将为auto变量。[存储种类]数据类型[存储器类型]变量名表222024/12/4存储器类型与PC机的C编程相比,C51的存储类型复杂很多,这是由于

MCS-51单片机存储器类型的多样性决定的。可以通过存储器类型的定义,将变量安排在不同的存储区域。存储种类和存储器类型是可选项。如果没有定义变量的存储种类或存储器类型,C51编译器将根据变量定义的位置以及存储器模式,由C51编译器分配变量的在RAM中的位置(地址)。[存储种类]数据类型

[存储器类型]变量名表232024/12/44.3.2数据类型数据类型决定变量的类型以及在存储器中的长度,变量名表中各个变量用逗号隔开。例如:inti,j,k;//定义三个整型变量i,j,kunsignedintsi,sk;//定义无符号整型变量si,s

kbitmy_bit;//定义位变量my_bit[存储种类]数据类型[存储器类型]变量名表242024/12/4局部变量和全局变量根据变量作用域的不同,变量可分为。1)局部变量:局部变量也称为内部变量,是指在函数内部或以花

括号“{}”括起来的功能模块内部定义的变量。局部变量只在定义它的函数或功能模块内有效,在该函数或功能模块以外不能使用。在C5l语言中局部变量必须定义在函数或功能模块的开头。2)全局变量。全局变量也称为外部变量,是指在程序开始处或各个功能函数的外面定义的变量。在程序开始

处定义的全局变量对于整个程序都有效,可供程序中所有的函数共同使用;而在各功能函数外面定义的全局变量只对全局变量定义语句后定义的函数有效,在全局变量定义之前定义的函数不能使用该变量。一般在程序开始处定义全局变量。252024/12/4全局变量的缺点◼(1)全局变量由C编译器在动态区外的固定存储区域中

存储,它在整个程序执行期间均占用存储空间,这将增大程序执行时所占的内存。◼(2)全局变量是外部定义的,这将破坏函数的模块化结构,不利于函数的移植。◼(3)由于多个模块均可对全局变量进行修改,处理不当时可能导致程序错误,且难以调试。因此应避免使用不必要

的全局变量。◼有时函数需要引用一个在其后面定义的变量或在另一个程序文件中定义的变量,可使用exten关键字进行外部变量声明。外部变量声明不同于外部变量定义,外部变量只定义一次,而可以多次使用外部变量声明。262024/12/4C51具有ANSIC的所有标

准数据类型,包括:char、int、short、long、float和double,对KeilC的C51编译器来说,short类型和int类型相同,double类型和float类型相同。除此之外,为了更加有利地利用MCS-5

1的结构,C51还增加了一些特殊的数据类型,包括bit、sfr、sfr16、sbit。数据类型[存储种类]数据类型[存储器类型]变量名表272024/12/4表4-4C51变量的数据类型数据类型长度/bit长度/Byte值域un

signedchar810~255signedchar或char81-128~+127unsignedint1620~65535signedint162-32768~+32768unsignedlong3240~429496

7295signedlong324-2147483648~+2147483647float324-1.175494E-38~+3.402823E+38*指针1~3bit10或1282024/12/41.

char字符类型char类型的长度是8位,1字节(简称1B),通常用于定义处理字符数据的变量或常量。分无符号字符类型unsignedchar和有符号字符类型signedchar,默认值为signedchar类型。unsignedch

ar类型用字节中所有的位表示数值,可以表达的数值范围是0~255。signedchar类型用字节中最高位表示数据的符号,0表示正数,1表示负数,负数用补码表示,能表示的数值范围是-128~+127。unsignedchar常用于处理ASCII字符或用于处理小于或等于255

的整型数。292024/12/42.int整型int整型长度为16位,2字节(2B),用于存放一个双字节数据。分有符号int整型数signedint和无符号int整型数unsignedint,默认值为signedint类

型。signedint表示的数值范围是-32768~+32767,字节中最高位表示数据的符号,0表示正数,1表示负数。unsignedint表示的数值范围是0~65535。302024/12/43.long长整型long长整型长度为32位,4字节(4B),用于存放一个4B数据。分有符号lon

g长整型signedlong和无符号long长整型unsignedlong,默认值为signedlong类型。signedint表示的数值范围是-2147483648~+2147483647,字节中最高位

表示数据的符号,0表示正数,1表示负数。unsignedlong表示的数值范围是0~4294967295。312024/12/44.float浮点型float浮点型在十进制中具有7位有效数字,是符合IEEE-754标准(32)的单精度浮点型

数据,占用4B。具有24位精度。322024/12/45.*指针型指针型本身就是就是一个变量,在这个变量中存放的指向另一个数据的地址。在C51中,这个指针的长度一般为1-3个字节。332024/12/46.bit类型bit类

型存放逻辑变量,占用一个位地址,C51编译器将把bit类型的变量安排在单片机片内RAM的位寻址区。342024/12/44.3.3变量的存储器类型定义变量时,根据51单片机存储器的特点,必须指明该变量所处的单片机的内存空间

。C5l编译器支持MCS-51单片机的硬件结构,可完全访问MCS-51硬件系统的所有部分。编译器通过将变量或者常量定义成不同的存储类型(data,bdata,idata,pdata,xdata,code)的方法,将它们定位在不同的存储区中。[存储种类]数据类型[存储器类型]变量名表352

024/12/4[存储种类]数据类型[存储器类型]变量名表auto(自动)extern(外部)static(静态)register(寄存器)DATA区BDATA区IDATA区PDATA区XDATA区CODE区unsignedchar

signedcharunsignedintsignedintunsignedlongsignedlongfloat*指针bitsfr、sfr16、sbit。362024/12/4表4-5存储类型与存储空间的对应关系存储类型与存储空间的对应关系DATA直接寻址片内数据存储区,

访问速度快(128字节)BDATA可位寻址片内数据存储区,允许位与字节混合访问(16字节)IDATA间接寻址片内数据存储区,可访问片内全部RAM地址空间(256字节)PDATA分页寻址片外数据存储区(256字节),由MOVX@R0访问XDATA片外数据存储区

(64KB),由MOVX@DPTR访问CODE代码存储区(64KB),由MOVC@DPTR访问372024/12/41.DATA区当使用存储类型data,bdata定义变量时,C5l编译器会将它们定位在片内数据存储区中(片内RAM)。这个存储区的长度为128字节。能快速存取各种数据

。片内数据存储区是存放临时性传递变量或使用频率较高的变量的理想场所,所以应该把使用频率高的变量放在DATA区,由于空间有限,必须注意使用DATA区,DATA区除了包含程序变量外,还包含了堆栈和寄存器组DATA区。下面是在DATA区中声明变量的例子。unsignedchardatasystem_st

atus=0;unsignedintdataunit_id[2];chardatainp_string[16];floatdataoutp_value;mytypedatanew_var;在SMALL存

储模式下,未说明存储器类型时,变量默认被定位在DATA区。382024/12/42.BDATA区当在DATA区的位寻址BDATA区定义变量,这个变量就可进行位寻址,并且声明位变量。例如:charbdatavar8

bit;//在位寻址区,定义字符型的变量声明的变量var8bit可以进行位操作运算,可以用sbit在bdata定义变量的基础上声明新的变量,例如:sbitmy_bit2=var8bit^2;//位变量my_bit2位于变量var8bit的第2位;

下面是一些在BDATA区中声明变量和使用位变量的例子。unsignedcharbdatastatus_byte;编译器不允许在BDATA区中定义float和double类型的变量。392024/12/43.I

DATA区IDATA区也可以存放使用比较频繁的变量,使用寄存器作为指针进行寻址。在寄存器中设置8位地址进行间接寻址,与外部存储器寻址比较,它的指令执行周期和代码长度都比较短。对于AT89C52单片机中定义的IDATA变量,如果低128B的R

AM容量不够时,C51编译器会自动安排到高128B的区域。下面是一些在IDATA区中声明变量的例子。unsignedcharidatasystem_status=0;unsignedintidataunit_id[2

];charidatainp_string[16];floatidataoutp_value;402024/12/44.PDATA和XDATA区PDATA和XDATA用于单片机的片外RAM区,在这两个区声

明变量和在其他区的语法是一样的,PDATA区只有256B,而XDATA区可达65536B,举例如下。unsignedcharxdatasystem_status=0;unsignedintpdataunit_id[2];charxdatainp_string[16];floatp

dataoutp_value;对PDATA和XDATA的操作是相似的,对PDATA和XDATA的寻址要使用MOVX指令,需要2个处理周期。对PDATA区寻址需要装入8位地址,使用Ri的间接寻址方式;而对XDATA区寻址则

需要装入16位地址,使用DPTR的间接寻址方式;412024/12/45.CODE区CODE区即MCS-51单片机的程序代码区,所以代码区的数据是不可改变的,读取CODE区存放的数据相当于用汇编语言的MOVC寻

址。一般代码区中可存放数据表,跳转向量和状态表,对CODE区的访问和对XDATA区的访问的时间是一样的,代码区中的对象在编译时初始化。下面是代码区的声明例子。unsignedintcodeunit_id[2]={0x1234,0x89ab};unsignedch

arcodeuchar_data[16]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x1

5};422024/12/4432024/12/44.3.4存储模式如果在变量定义时省略了存储器类型标识符,C51编译器会选择默认的存储器类型。默认的存储器类型由SMALL、COMPACT和LARGE存储模式(memorymodels)指令决定。存

储模式是编译器的编译选项。在KEILC编译器中存储模式的选择参见附录三。1.小模式(smallmodel)。在小模式下,所有未声明存储器类型的变量,都默认驻留在内部数据区,即这种方式和用DATA进行显示说明一样。

2.紧凑模式(compactmodel)。在紧凑模式下,所有未声明存储器类型的变量,都默认驻留在外部数据区的一个页上。即这种方式和用PDATA进行变量存储器类型的说明是一样的。该模式利用R0和R1寄存器来

进行间接寻址(@R0和@Rl)。3.大模式(largemodel)。在大模式下,所有未声明存储器类型的变量,都默认驻留在外部数据存储区,即和用XDATA进行显示说明一样。此时最大可寻址64KB的存储区域,使用数据指针寄存器(DPTR)来进行间接寻址。442024/12/4存储器

类型举例在不同存储器类型下等价于下面的变量声明:unsignedchardatavar1;/*SMALL模式,var1被定位在DATA区*//*即片内直接寻址RAM*/unsignedcharpdatavar1;/*COMP

ACT模式,var1被定位在PDATA区,即片外按页面间接寻址RAM*/unsignedcharxdatavar1;/*LARGE模式,var1被定位在XDATA区*//*即片外间接寻址RAM*/为了

提高系统运行速度,建议在编写源程序时,把存储模式设定为SMALL,必要时在程序中把XDATA、PDATA和IDATA等类型变量进行专门声明。452024/12/44.3.5C51语言中的特殊数据类型由于单片机特殊的结构,为编程的需要,C51语言扩展了ANSIC的数据类型。这些数据类型与

单片机的结构以及存储区域相关。462024/12/41.8位的特殊功能寄存器sfrC51使用sfr对MCS-51中的特殊功能寄存器进行定义,这种定义方法与标准C语言不兼容,只适用于对MCS-51系列单片机进行C编程。可以把sfr认为是一种扩充数

据类型,占用一个内存单元,值域为0x80~0xFF。定义方法是引人关键字sfr,语法如下:sfr变量名=SFR中的地址注意:sfr后面必须跟一个特殊寄存器名,“=”后面的地址必须是常数,不允许带有运算符的表达式。sfrP0=0x80sfrP1=0x

90472024/12/42.16位的特殊功能寄存器sfr16sfr16用于定义存在于MCS-51单片机内部RAM的16位特殊功能寄存器。当SFR的高端地址直接位于其低端地址之后时,对SFRl6位值可以进行直接访问。例如AT89C52的定时器2就是这种情况。为了有

效地访问这类SFR,可使用关键宇“sfrl6”。16位SFR定义的语法与8位SFR相同,16位SFR的低端地址必须作为“sfrl6”的定义地址。例如:sfr16T2=0xcc//定义定时器2为T2:TL2为0CCH,TH2为0CDH等价于,对TL2和TH2分别定义。sfrTL2=0x

CC;sfrTH2=0xCD;482024/12/43.位变量bit位变量可以用来定义变量、函数返回值的类型,用bit关键字来定义。位变量是C51编译器的一种扩充数据类型,它的值是一个二进制位,不是0,就是1,类似

一些高级语言中布尔(Boolean)变量的True和False。利用bit可定义一个位变量,但不能定义位指针,也不能定义位数组。所有的位变量都存储在内部RAM的位寻址区中(20H~2FH),在一个作用域中最大可声明128个位变量。bit变量的声明与其他变量相同,例如:

bitdone_flag=0//定义位变量done_flag,初值为0bitfunc(bitbvar1){//bit类型的函数bitbvar2;……return(bvar2);//返回值是bit类型}492024/1

2/44.特殊功能位sbit用关键字sbit定义位寻址的特殊功能寄存器的位寻址对象。定义方法有如下三种:(1)sbit位变量名=位地址位地址必须位于0x80H~0xFF之间。(2)sbit位变量名=特殊功

能寄存器名^位位置位位置是一个0~7之间的常数。(3)sbit位变量名=字节地址^位位置字节地址作为基地址,在0x80H~0xFF之间。位位置是一个0~7之间的常数。502024/12/4例如可用下面三种方法定义PSW中的第7位CY,结

果相同:sbitCY=0xD7//用绝对位地址表示PSW中的第7位,参见表2-4sbitCY=PSW^7//必须事先已经定义了PSWsbitCY=0xD0^7//PSW的字节地址为0xD0,参见表2-4MCS-51单片机中的特殊功能寄存器和特殊功能寄存器可

寻址位,已被预先定义放在文件reg51.h中,在程序的开头只需加上#include<reg51.h>或#include<reg52.h>即可。sbit和bit的区别:sbit定义特殊功能寄存器中的可寻址位;而bit则定义了一个普通的位变量,一个

函数中可包含bit类型的参数,函数返回值也可为bit类型。另外,sbit还可访问MCS-51单片机片内20H~2FH范围内的位对象。C51编译器提供了一个bdata存储器类型,允许将具有bdata类型的对象放入MCS-51单片机片内可位寻址区。512024/12/

44.4C51语言的数组、指针与结构4.4.1数组与指针4.4.2对绝对地址进行访问522024/12/44.4.1数组与指针1.数组数组是一个由同种类型的变量组成的集合,它保存在连续的存储区域中,第一个元素保存在最低地址中,最末一个元素保存在最高地

址中。数组的定义方式如下:数据类型[存储器类型]数组名[常量1][常量2]…[常量n]例如在程序存储器中用一维数组定义7段共阴LED数码显示的字形表,数组值分别对应0~9的显示数字。unsignedcharcodeLEDvalue[10

]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}chararray[]=”HelloWorld”532024/12/4数组与指针2.指针指针是指某

个变量所占用存储单元的首地址。用来存放指针值的变量称为指针变量。指针变量的定义格式为:类型说明符*指针变量名其中:“*”表示定义的是指针变量;类型说明符表示该指针变量指向的变量的类型。C5l语言的指针和标准C语言中的指针功能相同。char*

s;//指向字符类型的指针char*str[4];//定义字符类型的指针数组int*numptr;//指向整型类型的指针542024/12/4由于MCS-51存储器结构的特殊性,C51语言还提供指定存储器类型的指针,在声明时定义指针指向的存储器类型,也称为基于存储器类型的指

针,例如:chardata*str;//指针指向data区的字符intxdata*numtab;//指针指向xdata区的整型变量unsignedcharcode*powtab//指针指向code区的无符号字符这种基于存储器类型的指针,因为存储器类型在编译时就已经指定了,所以指针可以

保存在一个字节(idata、data、bdata等)或两个字节(code和xdata类型指针)中。552024/12/43.指针的应用例4-3指针的应用/*ex4-3.c,将外部RAM地址1000H开始的10个字节读

入到内部RAM中*/#include<reg51.h>//定义MCS-51的特殊功能寄存器SFR#defineXRAMaddr(unsignedcharxdata*)0x1000//外部RAM的开始地址unsignedcharxdata*ptr;main(){chari

;unsignedchardataarray[10];ptr=XRAMaddr;for(i=0;i<10;i++){array[i]=ptr[i];}while(1);}562024/12/44.结构结构变

量是将互相关联的、多个不同类型的变量结合在一起形成的一个组合形变量,简称结构。构成结构的各个不同类型的变量称为结构元素(或成员),其定义规则与变量的定义相同。一般先声明结构类型,再定义结构变量。定义一个结构类型的格式为:struct结构名{结构成员说明}结构成员还可以是其他已定义的结果,结构成员

说明的格式为:类型标识符成员名;C51结构定义的格式为:Struct结构名变量表;572024/12/4例4-4结构与结构变量的定义structdate{//定义名称为date的结构类型unsignedcharmonth;unsig

nedcharday;unsignedcharyear;}structdatedate1,date2//定义结构变量date1和date2对结构变量中成员的访问使用“.”运算符,例如:date1.year=07date1.month=1date1.day=25582024/12/44.4.2

对绝对地址进行访问1.使用指针指针是C语言中十分重要的概念,MCS-51的总线工作方式下对绝对地址的操作,在使用C51编程时常用指针操作。C51语言中提供的两个专门用于指针和地址的运算符:*取内容&取地址取内容和取地址运算的一般形式分别为:变量=*指针变量指针变量=&目

标变量592024/12/4例4-5使用指针对指定地址进行访问#defineucharunsignedchar#defineuintunsignedintvoidtest_memory(void){ucharidataiv

ar1;ucharxdata*xdp;/*定义一个指向XDATA存储器空间的指针*/chardata*dp;/*定义一个指向DATA存储器空间的指针*/ucharidata*idp;/*定义一个指向IDATA存储器空间的指针*/xdp=0x1000;/*XDATA指针赋值,指向XDATA存储器地

址1000H处*/*xdp=0x5A;/*将数据5AH送到XDATA的1000H单元*/dp=0x61;/*DATA指针赋值,指向DATA存储器地址61H处*/*dp=0x23;/*将数据23H送到DATA的61H单元*/idp=&ivar1;/*id

p指向IDATA区变量ivar1*/*idp=0x16;/*等价于ivar1=0x16*/}602024/12/42.使用C51扩展关键字_at_对确定地址进行访问使用_at_对指定的存储器空间的绝对

地址进行定位。格式如下:[存储器类型]数据类型标识符_at_常数当对外部接口的地址进行读写时,存储器类型为xdata数据类型;数据类型通常为uchar的1字节类型;使用_at_定义的变量必须为全局变量。例4-6用关键字_at_访问指定地址/*将地址为1000H的内容读入。

*/#include<reg51.h>//定义MCS-51的特殊功能寄存器SFRunsignedcharxdatay1_at_0x1000;main(){unsignedcharx1;x1=y1;while(1);}612024/12/4

3.使用C51运行库中预定义宏C51编译器提供了一组宏定义用来对MCS-51系列单片机的CODE、DATA、PDATA和XDATA空间进行绝对地址访问。函数原型如下:#defineCBYTE((unsignedcharvolatile

code*)0)#defineDBYTE((unsignedcharvolatileidata*)0)#definePBYTE((unsignedcharvolatile*pdata)0)#defineXBYTE((unsignedcharvolatile*xdata

)0)这些函数原型放在absacc.h文件中。例如ucharuc_var1;uc_var1=XBYTE[0x0002];/*访问外部RAM0002H地址的内容*/622024/12/44.5C51的运算符和表达式表达式后面加“;”号就构成了一个表达式语句。1.赋值运算符赋值运算符“=”,在C中它的

功能是给变量赋值,如x=10。2.算术运算符C51中的算术运算符如下:+加或取正值运算符-减或取负值运算符*乘运算符/除运算符%模(取余)运算符,如8%5=3,即8除以5的余数是3632024/12/43.自增自减运算自增自减运算符可用在操作数之前,也可放在其后,例

如“x=x+1”既可以写成“++x”,也可写成“x++”,其运算结果完全相同。但在表达式中这两种用法是有区别的。x=99;y=++x;则y=100,x=100,如果程序改为:x=99;y=x++;则y=99,x=100。在这两种情况下,x都被置为100

。在大多数C编译程序中,为自增和自减操作生成的程序代码比等价的赋值语句生成的代码要快。642024/12/4算术运算符及其优先级排列如下:最高++、---(取负值)*、/、%最低+、-652024/1

2/44.关系运算符关系表达式用来判别某个条件是否满足。关系运算符的运算结果只有0和1两种,也就是逻辑的真与假,条件满足时结果为1,不满足时结果为0。C51中有6种关系运算符:>大于<小于>=大于等于<=小于等于==测试等

于!=测试不等于关系和逻辑运算符的优先级比算术运算符低,例如表达式“10>x+12”的计算,应看作是“10>(x+12)”。662024/12/45.逻辑运算符用逻辑运算符将关系表达式或逻辑量连接起来就是逻辑表达式:逻辑与:条件式1&&条件式2。逻辑或:条件式1

||条件式2。逻辑非:!条件式。例如a=7,b=6,c=0时,则:!a=0,!c=1。a&&b=1;!a&&b=0;b||c=1。(a>0)&&(b>3)=1;(a>8)&&(b>0)=0。672024/12/46.位运算符C51语言能进行按位操作,从而使C51语言也具有一定的对硬件直接进行

操作的能力。位运算符的作用是按位对变量进行运算,但并不改变参与运算的变量的值。如果要求按位改变变量的值,则要利用相应的赋值运算。位运算符不能用来对浮点型数据进行操作。位运算一般的表达形式如下:变量1位运算符变量2C51中共有6

种位运算符:&按位与|按位或^按位异或~按位取反<<左移>>右移682024/12/4位运算符也有优先级,从高到低依次是:“~”(按位取反),“<<”(左移),“>>”(右移),“&”(按位与),“^”(按位异或),“|”(按位或)。如

a=0x54=01010100B,b=0x3b=00111011B,则:a&b=00010000;a|b=01111111;a^b=01101111;~a=10101011;a<<2=01010000;b>>1=00011101。692024/

12/47.复合运算符复合运算符就是在赋值运算符“=”的前面加上其他运算符。以下是C51语言中的复合赋值运算符:+=加法赋值>>=右移位赋值-=减法赋值&=逻辑与赋值*=乘法赋值|=逻辑或赋值/=除法赋值^=逻辑异或赋值%=取模赋值~=逻辑非赋值<<=左移位

赋值其含义就是变量与表达式先进行运算符所要求的运算,再把运算结果赋值给参与运算的变量。其实这是C语言中简化程序的一种方法,凡是二目运算都可以用复合赋值运算符去简化表达。例如:a+=56等价于a=a+56,y/=x+9等价于y=y/(x+9)

。702024/12/44.6C51语言的程序结构C51语言的“语句”可以是以“;”号结束的简单语句,也包括用“{}”组成的复合语句。C51语言大致可分为三种基本结构:顺序结构、选择结构和循环结构。4.6.1顺序结

构单片机上电后或复位后是从地址0000H开始执行程序顺序执行指令代码的。712024/12/44.6.2选择结构◼if语句if语句的格式为:if(表达式)语句1else语句2if语句的例子可参见例4-1。“else

语句2”也可以省略。“语句2”还可以接续另一个if语句。构成:if(表达式1)语句1elseif(表达式2)语句2elseif(表达式3)语句3else语句3……else语句n722024/12/4例4-8,当S1闭合时,报警灯亮;当计数器TL1大

于30,同时而S1打开时,报警灯灭。#include<reg51.h>//定义MCS-51的特殊功能寄存器SFRsbitP32=P3^2;//定义P3.2为P32sbitP20=P2^0;//定义P2.0为P20main

(){while(1){P32=1;//P32为输入端if(P32==0){//P32是低电平?如果S1按下,P32为低P20=1;//S1按下,则P20输出高电平,报警灯亮}elseif(TL1>30){//

如果S1没有按下,并且TL1>30P20=0;//则P20输出低电平,报警灯灭}}}732024/12/4⚫switch语句swhch语句用于处理多路分支的情形,格式为:switch(表达式){case常量表达式:语句1;break;case常量

表达式2:语句2;break;……case常量表达式n:语句n;break;defaultt:语句n+l;break;}742024/12/4对switch语句需要注意以下两点:(1)case分支中的常量表达式的

值必须是整型、字符型,不能使用条件运算符。(2)break语句用于跳出switch结构。若case分支中未使用break语句,则程序将继续执行到下一个case分支中的语句直至遇到break语句或整个switch语句结束。这可以用于多个分支需要执行相同的语句进行处理

的情况。例4-9,switch/case编程举例。752024/12/4⚫例4.9switch/case语句编程举例switch(k){Case0:x=1;break;Case1:a=5;b=8;break;Case6:a

=8;b=5;x=0;break;defaultt:break;}762024/12/44.6.3循环结构C语言有for、while、do……while三种语句构成循环结构。⚫for循环语句for循环语句的

一般格式为:for(表达式1;表达式2;表达式3)循环体语句⚫while语句while循环语句的格式为:while(表达式)循环体语句⚫do…while语句do…whiIe循环语句的格式为:do循环体语句while(表达式);772024/12/4⚫goto语句

goto语句的格式为:goto语句标号;goto语句是无条件转移语句,它将程序运行的流向转到指定的标号处。⚫break语句在循环语句中,break语句的作用是在循环体中控制程序立即跳出当前循环结构,转而执行循环语句的后续操作。⚫continue语句

continue语句只能用于循环体结构中,作用是结束本次循环。一且执行了continue语句,程序就跳过循环体中位于该语句后的所有语句,提前结束本轮循环并开始下一轮循环。782024/12/4例4-9用do…w

hile语句编程计算1+2+3+…+10的值。unsignedcharsum,i;sum=0;i=0;do{sum+=i;i++;}while(i<=10);程序运行结果sum=55;i=10。792024/12/44.7C51语言的函数C程序由一个主函数main()和若干个其

他函数组成。由主函数调用其他函数,其他函数也可以互相调用,同一个函数可以被调用多次。1.函数定义函数定义的一般格式为函数类型函数名(形式参数列表)[interruptn][usingn]局部变量声明部分语句(有返回值的要有return语句)函数类型定义了函数中返回语句(return)返回

值的数据类型。参数表是一个用逗号分隔的变量表,当函数被调用时这些变量接收调用参数的值。一个函数可以没有参数,这时函数参数表是空的。802024/12/42.函数返回值返回语句retum用来回送一个数值给定义的函数,从函数中退出。返回值是通过retum语句返回的。返回值的类型

如果与函数定义的类型不一致,那么返回值将被自动转换成函数定义的类型。如果函数无须返回值,可以用void类型说明符指明函数无返回值。3.形式参数与实际参数与使用变量一样,在调用一个函数之前,必须对该函数进行声明。函数声明的一般格式为函数类型函数名(形式参数列表)函数定义时

参数列表中的参数称为形式参数,简称形参。函数调用时所使用的替换参数,是实际参数,简称实参。定义的形参与函数调用的实参类型应该一致,书写顺序应该相同。812024/12/44.调用函数的方式被调用的函数必须是已经存在的函数。函数作为语旬。把函数调用作为

一个语句,不使用函数返回值,只是完成函数所定义的操作。例如:refresh_led();函数作为表达式。函数调用出现在一个表达式中,使用函数的返回值。intk;k=sum(a,b);函数作为一个参数。函数调用

作为另一个函数的实参。intk;k=sum(sum(a,b),c);822024/12/45.规定函数使用的寄存器组使用usingn函数说明属性来规定函数所使用的寄存器组,格式为函数类型函数名(形参列表)usingnusingn属性使用一个0~3的整型参数

,这个参数表示使用的寄存器组的编号。using属性一般用在中断函数中。832024/12/44.8中断服务程序中断服务程序是一种特殊的函数,又称为中断函数。使用interrupt关键字来实现。定义中断服务程序的一般格式如下:void函数名()interrup

tn[usingm]关键字interrupt后面的n是中断号,理论上可以是0~31的整型参数,用来表示中断处理函数所对应的中断号,该参数不能是带运算符的表达式。对于AT89C51单片机n的取值范围是0~4。842024/12/4表4-6中断号和中断源的对应关系中断号中断源中断向量0

外部中断00003H1定时/计数器0000BH2外部中断10013H3定时/计数器1001BH4串行口0023H使用C51编写中断服务程序,程序员无需关心ACC、B、DPH、DPL、PSW等寄存器的保护,C51编译器会根据上述寄存器的使用情况在目标代码中自动增加压栈和出

栈。852024/12/4中断函数应遵循以下规则。中断函数不能进行参数传递。中断函数没有返回值。不能在其他函数中直接调用中断函数。若在中断中调用了其他函数,则必须保证这些函数和中断函数使用了相同的寄存器组。862024/12/44.9C51

的预处理预处理功能包括宏定义、文件包含和条件编译3个主要部分。预处理命令不同于C语言语句。具有以下特点。预处理命令以“#”开头,后面不加分号。预处理命令在编译前执行。多数预处理命令习惯放在文件的开头。4.9.1宏定义宏符号名一般采用大写形式。不带参数的宏定义的

格式为:#define宏符号名常量表达式例如:#definePI3.14用宏符号名PI代替浮点数3.14。结束宏符号名的定义语句:#undef宏符号名872024/12/44.9.2包含文件包含文件的

含义是在一个程序文件中包含其他文件的内容。用文件包含命令可以实现文件包含功能,命令格式为#include<文件名>或#include“文件名”例如,在文件file1.c中:#include“file2.c”main(){…}在编译预处理时,对#in

clude命令进行文件包含处理。实际上就是将文件file2.c中的全部内容复制插入到#include“file2.c”的命令处。882024/12/44.9.3条件编译命令*提供一种在编译过程中根据所求条件的值有选择地包含不同代码的手段,实现对程序源代码的各部分有选择的进行编译,称为条件编译。#

if语句中包含一个常量表达式,若该表达式的求值结果不等于0时,则执行其后的各行,直到遇到#endif、#elif或#else语句为止(预处理elif相当于elseif)。在#if语句中可以使用一个特殊的表达式defined(标识符):当标识符已经定义时,其值1;否则,其值为0。例如,为

了保证hdr.h文件的内容只被包含一次,可以像下面这样用条件语句把该文件的内容包围起来:#ifndef(HDR)#defineHDR#include(hdr.h)#endif892024/12/44.10C51的库函数4.10.1本征库函数C51提供的本征函数在编译时直

接将固定的代码插入当前行,而不是用ACALL和LCALL语句实现的,这样就大大提供了函数访问的效率,而非本征函数则必须由ACALL及LCALL调用。_crol_,_cror_:将char型变量循环向左(右)移动指定位数后返回。_iror_,_irol_:将int型变量循环向左(右

)移动指定位数后返回。_lrol_,_lror_:将long型变量循环向左(右)移动指定位数后返回。_nop_:相当于插入汇编指令NOP。_testbit_:相当于JBCbitvar测试该位变量并跳转同时清除。_chkfloat_:测试并返回浮点数的状态。使用上述函数时,源程序开

头必须包含#inclucle<intrins.h>头文件。902024/12/4例如:#include<intrins.h>voidtst_cror(void){unsignedchara;unsignedcharb;a=0xA5;b=_crol_(a,1);/*b的结果为a循环左移一位的

值,等于0xD2*/}912024/12/44.11使用C51编译器时的注意事项1.采用短变量。减小变量的数据宽度是提高代码效率的最基本的方法。2.避免使用浮点运算。在8位CPU上进行32位浮点数运算,速度是很慢的,如果需要使用浮点数时,可以考虑是否使用整型

运算来替代浮点运算。整型(长整型)的运算速度要比浮点数(双精度)的运算速度要快得多。3.使用位变量。对于逻辑值运算应使用位变量。4.使用常量宏定义。这可以提高程序的可维护性。5.用局部变量代替全局变量。全局变量始终占用内存空间,因此使用全局变量会占用更多的内存空间。922024/12/46.尽

量使用内部数据存储区。从存储速度考虑,应按下面的顺序使用存储器DATA、IDATA、PDATA、XDATA。7.使用存储器指针。程序中使用指针时,应指定指针的类型,确定它们指向的存储区域,这样程序代码会更加紧凑,运行速度会更

快。8.使用库函数。9.使用宏替代函数。对于小段代码,使用宏来替代函数。10.存储器模式。C51编译器提供了3种存储器模式,应该尽量使用小存储器模式。作业:4.122、5

小橙橙
小橙橙
文档分享,欢迎浏览!
  • 文档 25747
  • 被下载 7
  • 被收藏 0
相关资源
广告代码123
若发现您的权益受到侵害,请立即联系客服,我们会尽快为您处理。侵权客服QQ:395972555 (支持时间:9:00-21:00) 公众号
Powered by 太赞文库
×
确认删除?