1、第第7 7章章 单片机单片机C C语言设计语言设计7.1 C51语言简介语言简介7.2 C51的函数的函数7.3 C51的指针类型的指针类型7.4 MCS-51单片机单片机C51语言程序设计语言程序设计7.5 汇编语言与汇编语言与C51的混合编程的混合编程本章重点本章重点u了解了解C51C51的特点;的特点;u掌握单片机的掌握单片机的C51C51编程编程 ;u了解汇编语言与了解汇编语言与C51C51语言的混合编程。语言的混合编程。7.1 C51 7.1 C51 语言简介语言简介 C C语言是一种源于语言是一种源于UNIXUNIX操作系统的语言,它是一种结构化语言,操作系统的语言,它是一种结构化
2、语言,可产生紧凑代码。可产生紧凑代码。C C语言可以进行许多机器级函数控制,与汇编语言语言可以进行许多机器级函数控制,与汇编语言相比,有如下优点:相比,有如下优点:(1 1)不需要了解单片机指令集,也不需要了解其存储结构。)不需要了解单片机指令集,也不需要了解其存储结构。(2 2)寄存器分配和寻址方式由编译器进行管理,程序员可以忽略)寄存器分配和寻址方式由编译器进行管理,程序员可以忽略这些问题。这些问题。(3 3)编程时可使用与其他程序设计时相同的关键字和操作函数。)编程时可使用与其他程序设计时相同的关键字和操作函数。(4 4)程序的开发和调试时间大大缩短。)程序的开发和调试时间大大缩短。(5
3、 5)C C语言中的库文件提供许多标准的函数,如数学运算。开发语言中的库文件提供许多标准的函数,如数学运算。开发者可以直接调用,而不必使用烦琐的汇编语言来实现。者可以直接调用,而不必使用烦琐的汇编语言来实现。(6 6)C C语言可移植性好且非常普及,语言可移植性好且非常普及,C C语言编译器几乎适用于所有语言编译器几乎适用于所有的目标系统。的目标系统。(7 7)C C语言在模块化开发、可移植性、代码管理上有它明显的优语言在模块化开发、可移植性、代码管理上有它明显的优势。势。7.1.1 C7.1.1 C语言与汇编语言的比较语言与汇编语言的比较1)C51继承了标准继承了标准C语言的绝大部语言的绝大
4、部分的特性,基本语法相同,但分的特性,基本语法相同,但C51其本身又在特定的硬件结构上有所其本身又在特定的硬件结构上有所扩展,如定义了关键字扩展,如定义了关键字sbit、xdata、idata、code等。等。C51与标准与标准ANSI-C从从库函数的方向来说有很库函数的方向来说有很大的不同。大的不同。编译生成的编译生成的.m51文件,包含文件,包含了硬件资源使用的情况。应了硬件资源使用的情况。应用用C51编程可以通过该文件编程可以通过该文件了解系统资源。了解系统资源。C51头文件集体现了各种头文件集体现了各种系列系列MCS51芯片的不芯片的不同功能。同功能。12347.1.2 C517.1.
5、2 C51与与ANSI-CANSI-C的主要区别的主要区别 7.1.3 C517.1.3 C51的程序结构的程序结构 C C语言程序是由若干个函数单元组成的,每个函数都是完成某语言程序是由若干个函数单元组成的,每个函数都是完成某个特殊任务的子程序段。组成一个程序的若干个函数可以保存在一个特殊任务的子程序段。组成一个程序的若干个函数可以保存在一个源程序文件中,也可以保存在几个源程序文件中,最后再将它们个源程序文件中,也可以保存在几个源程序文件中,最后再将它们连接在连接在起。起。C C语言源程序文件的扩展名为语言源程序文件的扩展名为“.c”.c”,如,如hello.chello.c,ihao.c等
6、。等。一个一个C C语言程序必须有而且只能有一个名为语言程序必须有而且只能有一个名为main()main()的函数、它的函数、它是一个特殊的函数,也称为该程序的主函数,程序的执行都是从是一个特殊的函数,也称为该程序的主函数,程序的执行都是从main()main()函数开始的。函数开始的。7.1.4 C517.1.4 C51的数据类型和存储类型的数据类型和存储类型数据类型数据类型基本类型基本类型位型(位型(bitbit)字符型(字符型(charchar)整型(整型(intint)长整型(长整型(longlong)浮点型(浮点型(floatfloat)双精度浮点型(双精度浮点型(doubledou
7、ble)构造类型构造类型数组类型(数组类型(arrayarray)结构体类型(结构体类型(structstruct)共用体(共用体(unionunion)枚举(枚举(enumenum)指针类型指针类型空类型空类型 C51 C51定义的任何变量必须以一定的存储类型的方式定位在定义的任何变量必须以一定的存储类型的方式定位在8xx518xx51的某一存储区中,否则没有意义。因此,在定义变量类型时,还必的某一存储区中,否则没有意义。因此,在定义变量类型时,还必须定义它的存储类型,须定义它的存储类型,C51C51的变量的存储类型如表所示。的变量的存储类型如表所示。乘法运算符乘法运算符“*”:双目运:双目
8、运算符,具有左结合性。算符,具有左结合性。加法运算符加法运算符“+”:加法运:加法运算符为双目运算符,即应算符为双目运算符,即应有两个量参与加法运算,有两个量参与加法运算,如如a+b,4+8等。等。减法运算符减法运算符“-”-”:减法运算符:减法运算符为双目运算符,但为双目运算符,但“-”-”也可作也可作为负值运算符,此时为单目运为负值运算符,此时为单目运算,如算,如-x,-5-x,-5等具有左结合性。等具有左结合性。除法运算符除法运算符“/”:双目运算:双目运算符,具有左结合性。参与运符,具有左结合性。参与运算量均为整型时,结果也为算量均为整型时,结果也为整型,舍去小数。如果运算整型,舍去小
9、数。如果运算量中有一个是实型,则结果量中有一个是实型,则结果为双精度实型。为双精度实型。12345求余运算符(模运算符)求余运算符(模运算符)“%”:双:双目运算,具有左结合性。要求参与目运算,具有左结合性。要求参与运算的量均为整型。运算的量均为整型。求余运算的结求余运算的结果等于两数相除后的余数。果等于两数相除后的余数。7.1.5 C517.1.5 C51的算术运算符和表达式的算术运算符和表达式1.1.基本的算术运算符基本的算术运算符2.2.算术表达式和运算符的优先级算术表达式和运算符的优先级 表达式是由常量、变量、函数和运算符组合起来的式子。一个表达式有一表达式是由常量、变量、函数和运算符
10、组合起来的式子。一个表达式有一个值及其类型,个值及其类型,它们等于计算表达式所得结果的值和类型。表达式求值按运它们等于计算表达式所得结果的值和类型。表达式求值按运算符的优先级和结合性规定的顺序进行。单个的常量、变量、函数可以看做是算符的优先级和结合性规定的顺序进行。单个的常量、变量、函数可以看做是表达式的特例。表达式的特例。1 1)算术表达式)算术表达式算术表达式是由算术运算符和括号连接起来的式子。以下是算术表达式的例子:算术表达式是由算术运算符和括号连接起来的式子。以下是算术表达式的例子:a+ba+b(a(a*2)2)c c(x+r)(x+r)*8-(a+b)8-(a+b)7 7+i+isi
11、n(x)+sin(y)sin(x)+sin(y)(+i)-(j+)+(k-)(+i)-(j+)+(k-)2 2)运算符的优先级)运算符的优先级 C51C51语言中,运算符的运算优先级共分为语言中,运算符的运算优先级共分为1515级,级,1 1级最高,级最高,1515级最低。在表级最低。在表达式中,优先级较高的先于优先级较低的进行运算。而在一个运算量两侧的运达式中,优先级较高的先于优先级较低的进行运算。而在一个运算量两侧的运算符优先级相同时,则按运算符的结合性所规定的结合方向处理。算符优先级相同时,则按运算符的结合性所规定的结合方向处理。3.3.强制类型转换强制类型转换强制类型转换的一般形式为:
12、强制类型转换的一般形式为:(类型说明符类型说明符)()(表达式表达式)其功能是把表达式的运算结果强制转换成类型说明符所表示的类型。其功能是把表达式的运算结果强制转换成类型说明符所表示的类型。例如:例如:(float)a/(float)a/*把把a a转换为实型转换为实型*/(int)(x+y)/(int)(x+y)/*把把x+yx+y的结果转换为整型的结果转换为整型*/4.4.自增、自减运算符自增、自减运算符 自增自增1 1运算符记为运算符记为“+”+”,其功能是使变量的值自增,其功能是使变量的值自增1 1。自减。自减1 1运算符记运算符记为为“-”-”,其功能是使变量值自减,其功能是使变量值
13、自减1 1。自增自增1 1、自减、自减1 1运算符均为单目运算,都具有右结合性。可有以下几种形式:运算符均为单目运算,都具有右结合性。可有以下几种形式:+i+i:i i自增自增1 1后再参与其他运算。后再参与其他运算。-i-i:i i自减自减1 1后再参与其他运算。后再参与其他运算。i+i+:i i参与运算后,参与运算后,i i的值再自增的值再自增1 1。i-i-:i i参与运算后,参与运算后,i i的值再自减的值再自减1 1。注意:在理解和使用上容易出错的是注意:在理解和使用上容易出错的是i+i+和和i-i-。特别是当它们出在较复杂特别是当它们出在较复杂的表达式或语句中时,常常难于弄清,因此
14、应仔细分析。的表达式或语句中时,常常难于弄清,因此应仔细分析。7.1.6 7.1.6 预处理指令预处理指令 根据根据ANSIANSI的标准规定,预处理指令主要包括的标准规定,预处理指令主要包括#define#define、#error#error、#include#include、#if#if、#else#else、#endif#endif和和#undef#undef等。每个预处理指令均带有符等。每个预处理指令均带有符号号“#”#”。1.#define1.#define指令指令#define#define指令是一个宏定义指令,定义的一般形式为:指令是一个宏定义指令,定义的一般形式为:#defi
15、ne#define宏替换名字符串(或数值)宏替换名字符串(或数值)由由#define#define指令定义后,在程序中每次遇到该宏替换名时就用所定义指令定义后,在程序中每次遇到该宏替换名时就用所定义的内容代替它。例如,可用下面语句定义的内容代替它。例如,可用下面语句定义TRUETRUE表示数值表示数值1 1,FALSEFALSE表示表示0 0。#define TRUE 1#define TRUE 1#define FALSE 0#define FALSE 0 定义之后,一旦在源程序中使用了定义之后,一旦在源程序中使用了TRUETRUE和和FALSEFALSE,编译时会自动用,编译时会自动用1
16、1和和0 0代替。代替。需要说明的是,在宏定义语句后没有分号,程序中习惯用大写字符需要说明的是,在宏定义语句后没有分号,程序中习惯用大写字符作为宏替换名,而且常放在程序开头。作为宏替换名,而且常放在程序开头。2.#error2.#error指令指令 该指令用于程序的调试,当编译中遇到该指令用于程序的调试,当编译中遇到#error#error指令就停止编译。其指令就停止编译。其一般形式为:一般形式为:#error#error出错信息出错信息 出错信息不加引号,当编译器遇到这个指令时,显示下列信息并停出错信息不加引号,当编译器遇到这个指令时,显示下列信息并停止编译:止编译:FatalFatal:f
17、ilename linename error directivefilename linename error directive3.#include3.#include指令指令#include#include指令的作用是指示编译器将该指令所指出的另一个源文件指令的作用是指示编译器将该指令所指出的另一个源文件嵌入自身文件。嵌入自身文件。#include#include指令所在的程序中,文件应使用双引号或尖括号括起来。指令所在的程序中,文件应使用双引号或尖括号括起来。C C库函数的头文件一般用库函数的头文件一般用#include#include指令在程序开始处说明。例如:指令在程序开始处说明。例
18、如:#include#includestdio.hstdio.h4.#if4.#if、#else#else、#endif#endif指令指令#if#if、#else#else和和#endif#endif指令为条件编译指令,它的一般形式为:指令为条件编译指令,它的一般形式为:#if#if 常数表达式常数表达式语句段;语句段;#else#else语句段;语句段;#endif#endif上述结构的含义是:若上述结构的含义是:若#if#if指令后的常数表达式为真,则编译指令后的常数表达式为真,则编译#if#if到到#else#else之间的之间的程序段;否则编译程序段;否则编译#else#else到到
19、#endif#endif之间的程序段。例如:之间的程序段。例如:#define NUM 200#define NUM 200 main()main()#if MAX999#if MAX999printf(printf(Num999!nNum999!n););#else#elseprintf(printf(Num999!nNum999!n););#endif#endif 5.#undef5.#undef指令指令#undef#undef指令用来删除事先定义的宏定义,其一般形式为指令用来删除事先定义的宏定义,其一般形式为:#undef#undef 宏替换名宏替换名 例如:例如:#define FAL
20、SE 0#define FALSE 0#undef FALSE#undef FALSE7.2 C517.2 C51的函数的函数 函数是函数是C51C51语言的重要组成部分,是从标准语言的重要组成部分,是从标准C C语言中继承语言中继承而来的。而来的。C51C51语言不限制程序中的函数个数。任何一个完整的语言不限制程序中的函数个数。任何一个完整的C51C51程序都必须有且仅有一个主函数(程序都必须有且仅有一个主函数(mainmain函数),主函数是函数),主函数是C51C51程序的入口,所有的程序的入口,所有的C51C51程序都是从主函数开始执行的。程序都是从主函数开始执行的。为了有利于程序的模
21、块化,促进资源的共享,为了有利于程序的模块化,促进资源的共享,C51C51语言允许用语言允许用户使用自定义函数。同时,户使用自定义函数。同时,C51C51提供了大量的功能强大的库函提供了大量的功能强大的库函数。这些库函数都是编译系统自带的已定义好的函数,用户数。这些库函数都是编译系统自带的已定义好的函数,用户可以在程序中直接调用,而无须再自定义。合理使用库函数可以在程序中直接调用,而无须再自定义。合理使用库函数可以简化程序设计、加快程序执行速度。可以简化程序设计、加快程序执行速度。C51C51函数的定义通常包含以下内容:函数的定义通常包含以下内容:函数返回值类型函数返回值类型 函数名(形参表说
22、明)函数名(形参表说明)/*函数首部函数首部*/说明语句说明语句*函数体函数体 *执行语句执行语句 7.2.1 C517.2.1 C51函数的定义函数的定义 7.2.2 C517.2.2 C51函数的调用和参数传递函数的调用和参数传递 主调函数使用被调函数的功能,称为对被调函数的调用。函数调用主调函数使用被调函数的功能,称为对被调函数的调用。函数调用的基本形式是通过函数名和函数的参数。的基本形式是通过函数名和函数的参数。根据函数在主调函数中的作用,函数的调用方式,可以有以下两种根据函数在主调函数中的作用,函数的调用方式,可以有以下两种形式:形式:1.1.函数语句函数语句 被调函数在主调函数中,
23、以程序语句的方式出现。通常只完成一种被调函数在主调函数中,以程序语句的方式出现。通常只完成一种操作,不带函数会返回值。操作,不带函数会返回值。该函数调用非常简单,即在该函数调用非常简单,即在mainmain函数内调用函数函数内调用函数funcfunc,用于输出一串字用于输出一串字符。符。2.2.函数表达式函数表达式 调用函数后,取得函数的返回值,用于其他操作。调用函数后,取得函数的返回值,用于其他操作。7.2.3 C517.2.3 C51的库函数的库函数 C51C51可以使用大量标准可以使用大量标准C C语言的库函数,在用预处理器命令语言的库函数,在用预处理器命令#include#includ
24、e包含相应的头文件后,程序员就可以在程序中使用这些函数。包含相应的头文件后,程序员就可以在程序中使用这些函数。1 1)位移函数)位移函数 位移函数可以实现无符号字符型、无符号整型、无符号长整型变量的左位移函数可以实现无符号字符型、无符号整型、无符号长整型变量的左移或右移,其中左移函数包含:移或右移,其中左移函数包含:unsigned char _crol_(unsigned char val,unsigned char n);unsigned char _crol_(unsigned char val,unsigned char n);/*左移无符号字符型左移无符号字符型*/unsigned
25、int _irol_(unsigned int val,unsigned char n);unsigned int _irol_(unsigned int val,unsigned char n);/*左移无符号整型左移无符号整型*/unsigned int _lrol_(unsigned int val,unsigned char n);unsigned int _lrol_(unsigned int val,unsigned char n);/*左移无符号长整型左移无符号长整型*/这些函数的第一个参数表示要进行位移的变量,第二个参数表示要移这些函数的第一个参数表示要进行位移的变量,第二个参
26、数表示要移动的位数。动的位数。右移函数与左移函数形式一致,只是函数名不同,它们分别是:右移函数与左移函数形式一致,只是函数名不同,它们分别是:unsigned char _cror_ (unsigned char val,unsigned char n)unsigned char _cror_ (unsigned char val,unsigned char n);/*右移无符号字符型右移无符号字符型*/unsigned int _iror_ (unsigned int val,unsigned char n)unsigned int _iror_ (unsigned int val,unsi
27、gned char n);/*右右移无符号整型移无符号整型*/unsigned int _lror_ (unsigned int val unsigned int _lror_ (unsigned int val,unsigned char n)unsigned char n);/*右移无符号长整型右移无符号长整型*/2 2)空操作函数)空操作函数 空操作函数的格式如下:空操作函数的格式如下:void _nop_(void)void _nop_(void)该函数产生一个汇编指令该函数产生一个汇编指令NOPNOP,执行它没有任何实质性操作,仅仅延时一,执行它没有任何实质性操作,仅仅延时一个机器周
28、期。个机器周期。3 3)位测试函数)位测试函数 位测试函数的格式如下:位测试函数的格式如下:bit _testbit_(bit x)bit _testbit_(bit x)该函数的参数和返回值必须是位变量。该函数产生汇编指令该函数的参数和返回值必须是位变量。该函数产生汇编指令JBC xJBC x,即判,即判断位断位x x的值是的值是0 0还是还是1 1,并将其值通过,并将其值通过CyCy标志返回。标志返回。指针、地址、数组及其相互关系是指针、地址、数组及其相互关系是C C语言中最有特语言中最有特色的部分。规范地使用指针,可以使程序达到简单明色的部分。规范地使用指针,可以使程序达到简单明了。因此
29、,不但要学会如何正确地使用指针,还要学了。因此,不但要学会如何正确地使用指针,还要学会在各种情况下正确地使用指针变量。会在各种情况下正确地使用指针变量。7.3 C517.3 C51的指针类型的指针类型 7.3.1 7.3.1 指针变量的定义指针变量的定义 变量在计算机内是占有一块存贮区域的,变量的值就存放在这块区变量在计算机内是占有一块存贮区域的,变量的值就存放在这块区域之中在计算机内部,通过访问或修改这块区域的内容来访问或修改域之中在计算机内部,通过访问或修改这块区域的内容来访问或修改相应的变量。在相应的变量。在C C语言中,对于变量的访问形式之一,就是先找到变量语言中,对于变量的访问形式之
30、一,就是先找到变量的地址,然后再通过该地址对变量进行访问,这就是指针及其指针变量。的地址,然后再通过该地址对变量进行访问,这就是指针及其指针变量。所谓变量的指针,实际上是指变量的地址。变量的地址在形式上好像是所谓变量的指针,实际上是指变量的地址。变量的地址在形式上好像是一个整数,表示变量所在的地址,它属于一种新的数据类型,即指针类一个整数,表示变量所在的地址,它属于一种新的数据类型,即指针类型。型。指针变量定义的格式为:指针变量定义的格式为:类型标识符类型标识符 *标识符;标识符;其中,标识符是指针变量的名字,标识符前加其中,标识符是指针变量的名字,标识符前加*号,表示该变量是指号,表示该变量
31、是指针变量。前面的类型标识符表示该指针变量所指向的变量的类型。一个针变量。前面的类型标识符表示该指针变量所指向的变量的类型。一个指针变量只能指向同一种类型的变量。指针变量只能指向同一种类型的变量。7.3.2 7.3.2 指针变量的使用指针变量的使用指针变量只能存放地址,因此,不要试图将一个整数赋给一个指针变量只能存放地址,因此,不要试图将一个整数赋给一个指针变量。例如:指针变量。例如:int int *addressaddress;address=100address=100;这种赋值是不合法的。指针变量正确的使用方法如下:这种赋值是不合法的。指针变量正确的使用方法如下:int iint i;
32、int int*address;address;定义一个整型变量定义一个整型变量i i,还定义了一个指向整型数的指针变量,还定义了一个指向整型数的指针变量addressaddress。i i中可存放整数,而中可存放整数,而addressaddress中只能存放整型变量的地中只能存放整型变量的地址。可以把址。可以把i i的地址赋给的地址赋给addressaddress。addressaddress&i&i;此时指针变量此时指针变量addressaddress指向整型变量指向整型变量i i。7.3.3 7.3.3 指针与数组指针与数组 指针和数组有着密切的关系,任何能出数组下标完成的操作也指针和数
33、组有着密切的关系,任何能出数组下标完成的操作也都可用指针来实现,但程序中使用指针可使代码更紧凑、更灵活。都可用指针来实现,但程序中使用指针可使代码更紧凑、更灵活。采用指针访问数组元素的地址和内容有以下几种表示形式:采用指针访问数组元素的地址和内容有以下几种表示形式:1(1)p+i(1)p+i和和a+ia+i均表均表示示aiai的地址,或者的地址,或者说它们均指向数组第说它们均指向数组第i i号元素,即指向号元素,即指向aiai。2 (2)*(p+i)和和*(a+i)都都表示表示p+i和和a+i所指对象所指对象的内容,即为的内容,即为ai。3 (3)(3)指向数组元素指向数组元素的指针,也可以表
34、示的指针,也可以表示成数组的形式,如成数组的形式,如pipi与与*(p+ip+i)等价。)等价。7.3.4 7.3.4 字符指针字符指针 C C语言中操作一个字符串常量的方法有:语言中操作一个字符串常量的方法有:(1 1)把字符串常量存放在一个字符数组之中,例如:)把字符串常量存放在一个字符数组之中,例如:char cTempchar cTemp=MystringMystring;数组数组cTempcTemp共有共有9 9个元素,其中,个元素,其中,cTempcTemp8 8中的内容是中的内容是“0”0”。在。在字符数组定义的过程中,编译程序直接把字符串复制到数组中,即对数组字符数组定义的过程
35、中,编译程序直接把字符串复制到数组中,即对数组cTempcTemp进行初始化。进行初始化。(2 2)用字符指针指向字符串,然后通过字符指针来访问字符串存储)用字符指针指向字符串,然后通过字符指针来访问字符串存储区域。区域。当字符串常量在表达式中出现时,根据数组的类型转换规则,它被当字符串常量在表达式中出现时,根据数组的类型转换规则,它被转换成字符指针。例如,当定义了一字符指针转换成字符指针。例如,当定义了一字符指针pCharPointpCharPoint:char char *pCharPointpCharPoint;可用做如下操作:可用做如下操作:pCharPoint=pCharPoint=
36、MystringMystring;即将即将pCharPointpCharPoint指向字符串常量中的第指向字符串常量中的第0 0号字符号字符M M,此后可通过,此后可通过pCharPointpCharPoint来访问这一存储区域,如来访问这一存储区域,如*pCharPointpCharPoint或或pCharPointpCharPoint0 0就就是字符是字符M M,而,而pCharPointpCharPointi i或或*(pCharPoint+i)(pCharPoint+i)就相当于字符串的第就相当于字符串的第i i号字符。号字符。7.4 MCS-517.4 MCS-51单片机单片机C51
37、C51语言程序设计语言程序设计 MCS-51 MCS-51单片机的内部资源主要有并行单片机的内部资源主要有并行I/OI/O口、定时器口、定时器/计计数器、串行接口以及中断系统,数器、串行接口以及中断系统,MCS-51MCS-51单片机的大部分功能单片机的大部分功能就是通过对这些资源的利用来实现的。在开发应用程序时,就是通过对这些资源的利用来实现的。在开发应用程序时,常常对这些资源进行编程。常常对这些资源进行编程。7.4.1 MCS-517.4.1 MCS-51内部资源的编程内部资源的编程 1.1.并行输入输出端口并行输入输出端口 80518051系列单片机有系列单片机有4 4个输入输出端口,共
38、个输入输出端口,共3232根根I IO O线。在第线。在第2 2章普对单片机的输入输出端口做过一些介绍。这里作一简单回顾,章普对单片机的输入输出端口做过一些介绍。这里作一简单回顾,以方便对后面输入输山口编程的理解。以方便对后面输入输山口编程的理解。每个输入输出口都有每个输入输出口都有8 8根线,共根线,共3232根根I/OI/O线,所有的端口都是线,所有的端口都是双向口。各个端口包含一个锁存器,即专用寄存器双向口。各个端口包含一个锁存器,即专用寄存器P0P0P3P3,一个,一个输出驱动器和输入缓冲器。为方便起见,将输出驱动器和输入缓冲器。为方便起见,将4 4个端口和其锁存器都个端口和其锁存器都
39、表示为表示为P0P0P3P3。访问外部存储器的时候,地址由访问外部存储器的时候,地址由P0P0和和P2P2口送出,数据通过口送出,数据通过P0P0口口传送,这时端口是分时多路转换的双向总线。此时传送,这时端口是分时多路转换的双向总线。此时P0P0口成为地址口成为地址数据总线,不能再作为普通的数据总线,不能再作为普通的I IO O端口使用。端口使用。2.2.定时器计数器定时器计数器 在应用中,定时器在应用中,定时器/计数器作为定时器使用时可以为程序提供计数器作为定时器使用时可以为程序提供一个定时,这种由硬件完成的定时比起用软件循环完成的定时要一个定时,这种由硬件完成的定时比起用软件循环完成的定时
40、要好得多好得多:一方面定时准确,另一方面在定时时其他事件可阻继续进一方面定时准确,另一方面在定时时其他事件可阻继续进行。由于定时器的计数寄存器长度有限,所以其最长定时间隔也行。由于定时器的计数寄存器长度有限,所以其最长定时间隔也只有只有65.536ms65.536ms。如果要产生较长时间的定时间隔,就需要结合使。如果要产生较长时间的定时间隔,就需要结合使用软件循环和硬件定时。作为计数器时,定时器用软件循环和硬件定时。作为计数器时,定时器/计数器可以用来计数器可以用来计数外部的脉冲可连接流量计、频率计等信号源。对于一些使计数外部的脉冲可连接流量计、频率计等信号源。对于一些使用了用了V-FV-F转
41、换器的传感器,也可以用它来进行频率采集,只是需要转换器的传感器,也可以用它来进行频率采集,只是需要注意计数器能够采集的频率上限。注意计数器能够采集的频率上限。3.3.中断中断 80518051系列单片机提供了分为系列单片机提供了分为2 2个优先级的个优先级的5 5个中断源,每个中断个中断源,每个中断源的优先级都是可编程的。源的优先级都是可编程的。在编制实时性要求较高的程序时中断控制方式显得特别有用。在编制实时性要求较高的程序时中断控制方式显得特别有用。实际上,在一般的单片机多任务实际上,在一般的单片机多任务(如采集数据、计算、通信如采集数据、计算、通信)应用程应用程序编制中,中断编程是必小可少
42、的一部分。序编制中,中断编程是必小可少的一部分。中断服务程序在中断服务程序在C51C51中是以中断函数的形式出现的,使用中是以中断函数的形式出现的,使用interruptinterrupt修饰符可以把函数声明为中断函数。由于修饰符可以把函数声明为中断函数。由于C51C51编译器在编编译器在编译时对声明为中断函数的函数进行相应的现场保护、阻断其他中断、译时对声明为中断函数的函数进行相应的现场保护、阻断其他中断、返回时恢复现场等处理,因而在编写中断函数时可以不必考虑这些返回时恢复现场等处理,因而在编写中断函数时可以不必考虑这些问题,而把精力集中在如何处理引发中断的事件上。问题,而把精力集中在如何处
43、理引发中断的事件上。4.4.串行口串行口 80518051系列单片机提供个串行口,它是个全双工的通信端口,同时系列单片机提供个串行口,它是个全双工的通信端口,同时能够进行发送和接收。它可以作为能够进行发送和接收。它可以作为UART(UART(通用异步接收发送器通用异步接收发送器)用,也用,也可以作为同步移位寄存器用。串行口操作主要是对数据缓冲寄存器可以作为同步移位寄存器用。串行口操作主要是对数据缓冲寄存器SBUFSBUF操作,在物理上它对应着两个寄存器,一个发送、一个接收。执操作,在物理上它对应着两个寄存器,一个发送、一个接收。执行操作时,行操作时,CPUCPU向向SBUFSBUF写是修改发送
44、寄存器,读写是修改发送寄存器,读SBUFSBUF是读接收寄存器。是读接收寄存器。对于接收器,它是双缓冲的,以避免在接收时产牛两帧重叠问题。发对于接收器,它是双缓冲的,以避免在接收时产牛两帧重叠问题。发送寄存器不需要双缓冲,因为发送时送寄存器不需要双缓冲,因为发送时CPUCPU是主动的,不会发生写重叠问是主动的,不会发生写重叠问题。题。7.4.2 MCS-517.4.2 MCS-51扩展资源的编程扩展资源的编程1.1.可编程可编程I/OI/O接口控制芯片接口控制芯片82558255 对使于使用对使于使用80518051扩展扩展82558255与其他设备连接的系统,与其他设备连接的系统,编程核心在
45、于对编程核心在于对82558255相应工作方式的时序的模拟,下面相应工作方式的时序的模拟,下面以个实例来说明。以个实例来说明。【例【例7-97-9】82558255控制打印机。控制打印机。如图给出了如图给出了80518051扩展扩展82558255与打印机的接口电路。与打印机的接口电路。82558255端口地址端口地址通过译码器通过译码器74LS37374LS373确定。打印机与确定。打印机与80518051采取查询方式变换数据,采取查询方式变换数据,打印机状态信号送入打印机状态信号送入PC7PC7,忙时,忙时BUSYBUSY置置1 1,80518051可以通过读取可以通过读取82558255
46、该该端口得到打印机的状态,微型打印机的数据输入采用选通输出控制端口得到打印机的状态,微型打印机的数据输入采用选通输出控制法,当法,当STBSTB上有负跳变时数据被打入。上有负跳变时数据被打入。82558255用方式用方式0 0由由PC0PC0模拟产生模拟产生该时序。该时序。依照接口电路,端口依照接口电路,端口A A地址地址=7CH=7CH,端口,端口B B地址地址=7DH=7DH,端口,端口C C地址地址=7EH=7EH,命令端口地址,命令端口地址=7FH=7FH。82558255各端口工作方式设置为:端口各端口工作方式设置为:端口A A输输出,工作在方式出,工作在方式0 0;PC7PC7PC
47、4PC4输入,输入,PC3PC3PC0PC0输出。方式选择命令输出。方式选择命令字为字为8EH8EH。8051扩展扩展8255和打印机的接口图和打印机的接口图2.2.可编程外围定时芯片可编程外围定时芯片82538253例例 82538253作定时器使用作定时器使用用用82538253作定时器产生定时波形如下:作定时器产生定时波形如下:1通道通道0 0工作于方式工作于方式3 3,输出频率为输出频率为2kHz2kHz的方的方波波2通道通道l由由8051控制,在控制,在程序开始时产生宽度为程序开始时产生宽度为480s的单脉冲的单脉冲3通道通道2 2用硬件方式触用硬件方式触发,输出单脉冲,时发,输出单
48、脉冲,时间常数为间常数为2626。定时器模式下定时器模式下82538253与与80518051接口接口 由图可知,由图可知,74LS37374LS373和和74LS15474LS154构成了对构成了对82538253操作的译码电操作的译码电路:路:82538253的片选信号由的片选信号由74LS15474LS154送出,当选中送出,当选中82538253时时P2=80HP2=80H;由;由74LS37374LS373选择对选择对82538253内部哪个部分进行操作,通过单片机的内部哪个部分进行操作,通过单片机的ALEALE信号使得操作只有用信号使得操作只有用MOVXMOVX命令对命令对8253
49、8253的读写才是可行的。通的读写才是可行的。通过这些译码电路,过这些译码电路,82538253的各计数器和控制寄存器地址如下(均的各计数器和控制寄存器地址如下(均为片外地址,即为片外地址,即xdataxdata):):计数器计数器08000H08000H 计数器计数器18001H18001H 计数器计数器28002H28002H 控制寄存器控制寄存器8003H8003H根据设计要求,各个计数器工作方式设定如下:根据设计要求,各个计数器工作方式设定如下:(1 1)通道)通道0 0:工作方式:工作方式3 3,构成方波发生器。控制端,构成方波发生器。控制端GATE0GATE0接高接高电平,输出电平
50、,输出2 kHz2 kHz的方波,时间常数的方波,时间常数N0=1 MHzN0=1 MHz2 kHz=5002 kHz=500。(2 2)通道)通道1 1:工作方式:工作方式1 1,构成单稳态电路。,构成单稳态电路。GATE1GATE1正跳变触发,正跳变触发,输出一个宽度由时间常数决定的负脉冲。此功能一次有效。需再输出一个宽度由时间常数决定的负脉冲。此功能一次有效。需再形成一个脉冲时,不但形成一个脉冲时,不但GATE1GATE1上要有触发,通道也要重新初始化。上要有触发,通道也要重新初始化。需输出宽度为需输出宽度为480 s480 s单脉冲时,应取时间常数单脉冲时,应取时间常数N1=480 s
侵权处理QQ:3464097650--上传资料QQ:3464097650
【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。