案例解说单片机C语言开发:基于8051+Proteus仿真(txt+pdf+epub+mobi电子书下载)


发布时间:2020-07-16 18:54:31

点击下载

作者:程国钢

出版社:电子工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

案例解说单片机C语言开发:基于8051+Proteus仿真

案例解说单片机C语言开发:基于8051+Proteus仿真试读:

前言

一、行业背景

51单片机具有体积小、功能强、价格低的特点,在工业控制、数据采集、智能仪表、机电一体化、家用电器等领域有着广泛的应用。其应用可以大大提高生产、生活的自动化水平。近年来,随着嵌入式的应用越来越广泛,51 单片机的开发也变得更加灵活和高效,51 单片机的开发和应用已经成为嵌入式应用领域的一个重大课题。

二、关于本书

本书以Proteus硬件仿真环境和Keil μVision为依托,介绍了51单片机的应用方法,包括51单片机的体系结构、C51语言、内部资源的应用、外部器件的扩展方法,以及51单片机综合应用系统的开发方法和实例。

本书对于各个内部资源/外部器件内容的组织结构如下:器件基础、Proteus 中的器件库说明、Proteus应用电路、应用代码、仿真结果和总结。这样,读者既可以了解该器件的基础知识和对应的驱动代码,也可以在Proteus中进行仿真并且观察仿真结果。为与Proteus软件中的电路图保持一致,本书电路中电阻、电容单位的不规范处不做更改,如10k不改为10kΩ,10uF不改为10μF,读者能够理解即可。

本书各章内容说明如下:

● 第1章是51单片机应用基础的介绍,包括51单片机的体系结构、C51语言和KeilμVision软件开发环境的应用基础;

● 第2章是Proteus硬件仿真环境的基础使用方法介绍,包括其与Keil uVision软件开发环境的联合调试方法;

● 第3章主要介绍51单片机的内部资源、Keil μVision提供的相应库函数的使用方法及如何建立用户自己的库函数,并且给出了 3 个最常用的串行扩展库函数的应用代码;

● 第4章主要介绍51单片机的人机交互通道的使用方法,包括发光二极管、数码管、液晶模块、数字键盘等;

● 第5章主要介绍51单片机的信号采集通道的使用方法,包括A/D通道、时钟日历芯片、温度传感器等;

● 第6章主要介绍51单片机的信号输出通道的使用方法,包括D/A通道、I/O扩展芯片等;

● 第7章主要介绍51单片机的存储器的使用方法,包括RAM、2EPROM和MMC卡;

● 第8章主要介绍51单片机的执行机构的使用方法,包括三极管、电机、蜂鸣器等;

● 第 9 章主要介绍 51 单片机的通信扩展模块的使用方法,包括 RS-232、RS-422 和RS-485通信扩展;

● 第10章是51单片机的综合应用实例,这是对前面所有章节内容的综合实践,提供了频率计、波形发生器、密码保险柜、电子钟和RTX51操作系统等应用实例。

三、本书特色

本书的特色有:

● 适合于具有初步单片机基础的单片机工程师进阶学习,以及高等院校电子类专业的学生和单片机爱好者阅读;

● 涵盖了51单片机从内部资源到用户输入通道、A/D信号采集、温度/湿度传感芯片、有线通信模块等常用资源或扩展器件;

● 基于Proteus硬件开发环境提供了相应的仿真运行实例及其输出结果;

● 对于相应的资源或器件的介绍,都按照基础知识、Proteus库介绍、实例的设计思路和应用代码、实例的仿真运行输出和总结这一循序渐进的方式进行;

● 提供了大量的Proteus应用电路和KeilμVision的工程文件,读者可以直接运行、仿真。

本书主要由程国钢负责编写。参与编写工作的还有孙明、唐伟、王杨、顾辉、李成、刘启才、陈杰、郑宏、张霁芬、张计、陈军、张强、杨明、张玉兰。在此,对以上人员致以诚挚的谢意。由于时间仓促、程序和图表较多,受学识水平所限,错误之处在所难免,请广大读者给予批评指正。

本书提供免费的源代码和PPT,有需要的读者可登录华信教育资源网(www.hxedu.com.cn)免费下载。

编著者第1章 51单片机的应用基础

单片机是单片微型计算机的简称,是一种将运算控制器、存储器、寄存器 I/O 接口及一些常用的功能模块都集成到一块芯片上的计算机,用于工业控制、小型家电等需要嵌入式控制的场合。Intel 的 8051 系列单片机是历史最悠久,应用最广泛的单片机系列,发展到今天已经有30多年历史,该内核被ATMEL、飞利浦等公司采用,生产出了一大批具有相同内核构造但是有不同功能的单片机,这些单片机统称为51系列单片机。本章将简要介绍51单片机的体系结构、C51语言和KeilμVision软件开发环境。1.1 51单片机的体系结构介绍

51单片机通常由8位处理器、时钟模块、I/O端口、程序存储器、数据存储器、8/16位定时/计数器、中断系统和一个串行模块组成,如图1.1所示。图1.1 51单片机的内部结构

51单片机内部模块的功能介绍如下。

● 8 位处理器:这是 51 单片机的核心部件,执行预先设置好的代码,负责数据的计算和逻辑的控制等。

● 程序存储器:用于存放待执行的程序代码。

● 数据存储器:用于存放程序执行过程中的各种数据。

● 中断系统:根据 51 单片机相应的寄存器的设置来监测和处理单片机的各种中断事件并且提交给处理器处理。

● 时钟模块:以外部时钟源为基准,产生单片机各个模块所需要的各个时钟信号。

● 串行模块:根据相应的寄存器设置进行串行数据通信。

● 8/16位定时/计数器:根据相应寄存器的设置进行定时或计数。

● I/O端口:作为数据、地址或控制信号通道和外围器件进行数据交换。1.1.1 51单片机的8位处理器

8 位处理器是 51 单片机的核心模块,由运算逻辑模块和控制逻辑模块组成。运算逻辑模块由算术逻辑运算器ALU,累加器ACC,寄存器B,暂存寄存器TR,程序状态字寄存器PSW,布尔处理器,程序计数器PC,数据指针DPRT,堆栈指针SP组成;控制逻辑模块则由指令寄存器IR、指令译码器和定时控制逻辑电路等组成。

1.算术逻辑运算器ALU

算术逻辑运算器 ALU 主要负责对数据进行算术运算操作和逻辑运算操作,其具体的运算操作如下:

● 带进位加法;

● 不带进位加法;

● 带借位减法;

● 8位无符号数乘、除法;

● 自加1、自减1操作;

● 左右移位操作;

● 半字节交换;

● 比较和条件转移等操作。

以上操作都对应有专用的指令,读者可以自行查阅相应的手册。ALU 的操作数一般存放在累加器 ACC 或暂存寄存器 TR 中,其运算结果则可以选择保存在 ACC、通用寄存器或其他普通存储单元中。在乘、除法运算中,则使用寄存器B存放一个操作数并且在运算结束之后存放8位结果数据。

注意:操作数是指令的操作对象,运算结果是指令的操作结果,指令则是对操作数进行操作的命令。

2.累加器ACC和寄存器B

累加器 ACC 是处理器模块中使用最为频繁的寄存器,全部的算术运算操作及绝大多数的数据传送操作都需要使用ACC。

● 加法和减法:使用ACC存放运算结果。

● 乘法:使用ACC存放一个操作数,使用寄存器B存放另外一个操作数,运算结果则放在ACC和寄存器B组成的AB寄存器对中。

● 除法:使用 ACC 存放被除数,使用寄存器 B 存放除数,计算得到的商数放在 ACC中,而余数放在寄存器B中。

3.程序状态字寄存器PSW

程序状态字寄存器 PSW 用于指示程序运行过程中的系统相关状态,其中 7 位用于存放ALU 单元运算结果的特征信息,1 位为保留位(未使用)。程序状态字寄存器的具体含义如表1.1所示。表1.1 程序状态字寄存器的具体含义

程序状态字的内部位定义如下。

● CY:进位、借位标志。在计算过程中如果有进位、借位产生时,该位被置 1,否则清0。

● AC:半进位标志。当参与计算的数据的第 3 位向第 4 位有进位或借位产生时,该位被置1,否则清0。

● F0:供用户自由使用的的标志位,常常用于控制程序的跳转,需要用户自己控制其置1或清0。

● RS1,RS0:寄存器组选择位,由用户自行置 1 或清 0,用于选择使用的工作寄存器区。RS1,RS0和对应的工作寄存器组如表1.2所示。

● OV:溢出标志位。当带符号数的运算结果超出-128~+127的范围、无符号数运算结果超过255或无符号除法除数为0时,OV被置1,否则被清0。

● P:奇偶标志位,用于表示累加器 ACC 中“1”的个数,当该个数为奇数时,P 被置1,否则被清0。表1.2 RS1,RS0和对应的工作寄存器组

51 单片机共有 4 个寄存器组,每个寄存器组含有 8 个单字节寄存器,这些寄存器常用于保存程序执行过程中各个变量的值。合理使用寄存器组进行切换有利于加快程序代码的执行速度。

4.布尔处理器

布尔处理器用于 51 单片机的位操作,在位操作中使用进位标志 CY 作为累加器,可以对位变量进行置位、清除,取反,位逻辑与,位逻辑或,位逻辑异或,数据传送及相应的判断跳转操作。位操作是51单片机中非常重要的操作,充分体现了嵌入式处理器的特点。

5.程序计数器PC

程序计数器 PC 是一个 16 位计数器,用于存放下一条指令在程序存储器中的地址,可寻址范围为0~64KB。

6.数据指针DPTR

数据指针DPTR用于寻址外部数据存储器,其寻址范围为0~64KB。

7.堆栈指针SP

堆栈是一种将数据按序排列的数据结构,51 单片机的堆栈是内存中一段连续的空间。堆栈指针 SP 用来指示堆栈顶部在单片机内部数据存储器中的位置,可以由用户的程序代码修改。当执行进栈操作时,SP 自动加 1,然后把数据放入堆栈;当执行出栈操作时,SP 自动减1,然后把数据送出堆栈。当单片机被复位后,SP初始化为0x07H。

8.指令寄存器IR和指令译码器

指令寄存器 IR 用于存放 51 单片机当前正在执行的指令,而指令译码器用于对 IR 中的指令操作码进行分析解释,产生相应的控制逻辑。1.1.2 51单片机的存储器

51 单片机的存储器采用的是哈佛结构,其分别有独立的寻址指令、编址空间和相应的控制寄存器,如图1.2所示是51单片机的存储器组成结构,从图中可以看出51单片机的存储器有片内程序存储器、片外程序存储器、片内数据存储器和片外数据存储器四个部分,每个部分都有独立的地址编码。图1.2 51单片机的存储器组成结构

注意:51单片机的存储器包含很多存储单元,为区分不同的存储单元,单片机对每个存储器单元进行编号,存储器单元的编号就称为存储器单元的地址,每个存储器单元存储的若干位二进制数据称为存储器单元的数据。

1.51单片机的程序存储器

51 单片机的程序存储器由片内程序存储器和片外程序存储器组成,用于存放待执行的程序代码。因为PC程序指针和地址总线是16位的,所以片内和片外程序存储器的最大编址总和为 64KB,其中片外程序存储器的低部分编址和片内程序存储器的编址重合,代码只能选择存放到其中一个地方,使用外部引脚 EA 来选择。当该引脚加上高电平时,PC 程序指针起始指向的是片内程序存储器,程序代码从片内存储器开始执行;当该引脚加上低电平时,PC程序指针起始指向的是片外程序存储器,程序代码从片外程序存储器开始执行。

单片机复位之后,PC 程序指针被初始化为 0x000,指向程序代码空间的最低位。PC 程序指针在程序执行过程会自动增加指向下一条待执行的指令。当程序代码大小超过了片内程序存储器时,就需要为单片机外扩片外程序存储器,这样程序代码执行到存放在片内程序存储器中的最后一条指令之后会自动跳转到片外程序寄存器继续执行。

51 单片机的片内程序存储器的部分地址用于中断系统,是这些中断服务子程序的程序代码的入口,一般在该位置放置相应的跳转指令,使得 PC 程序指针跳转到相应的程序代码块的起始存放地址,如表1.3所示。表1.3 51单片机中断系统的入口地址

注意:某些 51 单片机内部集成了较多的资源,因此对应有更多的中断系统入口地址,具体的地址可以通过查看相应的手册得知。

51 单片机通常使用的程序存储器类型有:掩膜 ROM;OTP(一次性编程)ROM;MTP(多次编程)ROM,包括EPROM、EEPROM及FLASH等。通常使用编程器、ISP等多种方式将数据写入程序存储器,在执行过程中程序存储器多为只读属性。随着单片机技术的发展,出现了IAP(在应用中编程)技术,使得程序存储器在程序执行过程中也可以对自身编程。

2.51单片机的数据存储器

51 单片机的数据存储器用于存放代码执行过程中的相关数据,由片内存储器和片外存储器组成。片内存储器又可以划分为数据 RAM 区和特殊功能寄存器(SFR)区,而数据RAM 区又可以划分为工作寄存器区、位寻址区、用户区和堆栈区。51 单片机的片内数据RAM区如图2.3所示,共256字节。

片内存储器的最低空间是工作寄存器区,分为4组,每组8个单字节寄存器,均编码为R0~R7,共32个单元。当前正在使用的组由程序状态字寄存器PSW中的RS0和RS1位决定。由于可以直接使用单字节指令访问,所以放在其中的数据的访问速度是最快的。

位寻址区的 16 个字节单元支持位寻址,用户既可以使用普通的内存寻址指令对该部分内存单元进行字节寻址,也可以使用位寻址指令对该部分内存单元按照对应的位地址进行位寻址。该地址单元的字节地址和位地址对应如表 1.4 所示,这些位地址的空间编码为 00H~7FH,共128个地址。图1.3 51单片机的片内数据RAM区表1.4 51单片机的位地址空间编码

堆栈区是 51 单片机片内数据存储区中的一片连续空间,理论上来说可以设置在任何位置。执行进栈操作时,SP指针加1,然后把数据压入堆栈;执行出栈操作时,SP减1,然后把数据从堆栈中弹出。堆栈一般用于进入子程序时对相关数据的保存,堆栈区的大小决定了用户区的大小。堆栈区一般不直接寻址,需使用堆栈指令对其操作,而用户区则可以使用多种寻址方式访问。

51 单片机有较多的片上资源,如定时计数器、中断系统等,这些片上资源及单片机自身的控制寄存器被放在片内存储器的高 128 字节空间的某些地址,可以通过相应指令进行访问;某些寄存器还可以进行位寻址。常用的特殊功能寄存器列表如表1.5所示。表1.5 常用的特殊功能寄存器列表

51 单片机中有部分单片机的片内数据存储器的高位部分地址和 SFR 的地址重合,但是可以使用不同的指令来区分是否访问特殊寄存器区。从表 1.5 中可以看到,特殊寄存器区地址并没有完全用完,因此 51 单片机的扩展功能模块的相应控制寄存器也被放到这个区,具体可以参考对应的相关手册。

受到 16 位地址总线的限制,51 单片机的片外数据存储器最大为 64KB,这些地址空间通过寄存器DPTR或R0、R1间接寻址访问。

注意:51 单片机的外扩资源,如 A/D 转换器、端口扩展芯片等都被看做数据存储器,和数据存储器统一变址,占用相应的片外地址空间,也可使用片外数据存储器的操作指令进行访问。

可以看到,51单片机的数据存储器和程序存储器都有64KB的寻址空间,而且两种存储器的地址编码上是完全相同的,都是0x0000~0xFFFF,但是51单片机通过不同的指令来访问和操作这两种存储器,并且使用不同的外部引脚信号来选择它们,因此 51 单片机的存储器空间不会因为地址的重叠而出现混乱。1.1.3 51单片机的外部引脚

51单片机常见的封装形式有双列直插(DIP)封装、带引线的塑料芯片载体(PLCC)封装和贴片封装等。通常其40根外部引脚可以分为以下四种用途:

● 电源引脚,2根;

● 时钟引脚,2根;

● 控制引脚,4根;

● I/O引脚,32根。

其中某些引脚使用了引脚复用技术,有第二功能。如图 1.4 所示是 DIP 封装的 51 单片机的外部引脚和逻辑符号图。

注意:图 1.4 中上、下方的 2 根引脚分别是 VCC 和GND(2 根电源引脚),在大部分电路设计软件中这两个引脚会被自动隐藏并且直接连接到对应的电源上。图1.4 DIP封装的51单片机的外部引脚和逻辑符号图

1.电源引脚

电源引脚包括 VCC和 GND,其中 VCC是电源正信号输入引脚,GND是电源地信号引脚。

2.时钟引脚

时钟引脚是外部时钟信号的输入通道,由XTAL1和XTAL2组成,其详细说明如下。

XTAL1:内部振荡电路反相放大器输入引脚。当使用外部晶体时,该引脚连接晶体的一个引脚;当使用外部振荡源时,该引脚接地。

XTAL2:内部振荡电路反相放大器输出引脚。当使用外部晶体时,该引脚连接晶体的一个引脚;当使用外部振荡源时,该引脚接外部振荡源输入,此时XTAL1接地。

3.控制引脚

控制引脚一共有四个,包括 ALE/PROG,,RST/VDD 和/VPP,主要用于在特定模式下对单片机内、外资源的控制,其详细说明如下。

● ALE/PROG:地址锁存信号输出引脚,在访问单片机的片外数据存储器时,ALE 为高电平时,单片机的 P0 端口输出 16 位外部地址的低 8 位。由于这个信号以单片机时钟信号频率的1/6的分频产生,所以也可以用做其他芯片的时钟。在对单片机编程时,该引脚外加编程脉冲。

●:片外程序存储器读选通引脚。当单片机读片外程序存储器时,该引脚为低电平信号,以实现对片外程序存储器的读操作。

● RST/VDD:复位信号/备用电源输入引脚。当单片机有驱动时钟信号时,加在该引脚上的 2 个机器周期以上的高电平可以使得单片机复位;此引脚可以外加一个电源,当单片机的电源引脚 VCC 掉电之后,可以由这个电源通过 VDD 给单片机片内数据存储器供电,以保证数据不丢失。

●/VPP:片外程序寄存器地址允许/编程电压输入引脚。当引脚加上高电平时,复位后 PC 指针指向单片机的片内程序存储器,程序从片内程序存储器开始执行,执行完存放在片内程序存储器的程序后自动转向片外程序存储器执行;当 EA引脚加上低电平时,复位后PC指针指向单片机的片外程序存储器,程序从片外程序存储器开始执行;在单片机进行编程时,VPP被加上编程电压。

4.I/O引脚

51单片机的I/O引脚包括P0、P1、P2和P3,其详细说明如下。

● P0.0~P0.7:双向I/O引脚,既可以作为地址总线的低8位,也可以作为数据总线,还可以作为普通I/O引脚使用(此时可能需要加上拉电阻)。

● P1.0~P1.7:普通双向I/O引脚。

● P2.0~P2.7:双向I/O引脚,既可以作为地址总线的高8位,也可以作为普通I/O引脚使用。

● P3.0~P3.7:普通双向I/O引脚,并且具有第二功能。

P3.0~P3.7的第二功能说明如下。

● P3.0:RXD,串口输入引脚。

● P3.1:TXD,串口输出引脚。

● P3.2:,外部中断0的中断输入引脚。

● P3.3:,外部中断1的中断输入引脚。

● P3.4:T0,定时计数器0的外部输入引脚。

● P3.5:T1,定时计数器1的外部输入引脚。

● P3.6:,外部数据存储器的写选通引脚。

● P3.7:,外部数据存储器的读选通引脚。1.1.4 51单片机的时钟模块

时钟模块用于产生 51 单片机工作所需的各个时钟信号,单片机在这些时钟信号的驱动下工作,工作过程中的各个信号之间的关系称为单片机的时序。

1.51单片机的时钟源

51 单片机的时钟源既可以用内部振荡器产生,也可以使用外部时钟源输入产生。前者需要在XTAL1和XTAL2引脚之间跨接石英晶体(还需要30pF左右的微调电容),使石英晶体和内部振荡器之间组成稳定的自激振荡电路,其具体频率由石英晶体决定,微调电容可以对频率的大小进行略微调整;后者将晶振等外部时钟源直接连接到 XTAL2 引脚上为单片机提供时钟信号,其具体的频率由晶振决定。51单片机的时钟源电路如图1.5所示。

2.51单片机的时序

51 单片机的时序是指基于处理器指令译码产生的一系列操作在时间上的先后次序。51单片机的时序按照从小到大的顺序由振荡周期、时钟周期、机器周期、指令周期组成,如图1.6所示。

图1.5 51单片机的时钟源电路

● 振荡周期是时钟源产生的振荡输出周期。

● 时钟周期由两个被称为时钟周期的节拍的振荡周期P1和P2组成。

● 机器周期由六个被称为机器周期的状态的时钟周期S1~S6组成。

● 指令周期是指单片机完成一条指令所需要的时间。

图1.6 51单片机的时序图

注意:51 单片机的指令周期由 1~4 个机器周期构成,因此通常按照所需要的机器周期数把这些指令称为单周期指令、双周期指令等。1.1.5 51单片机的其他资源

51 单片机还集成了大量其他的内部资源,以协同处理器和内存完成单片机的控制功能,如并行端口、定时计数器、串口和中断系统等,另外,单片机开发厂商可以通过增加单片机的内部资源来扩展单片机的功能。单片机内部资源的具体使用方式将在第 3 章中进行详细介绍。1.2 51单片机的C51语言

51单片机常见的编程语言有4种:汇编语言、C语言、BASIC语言和PL/M语言。目前使用最多的单片机开发语言是汇编语言和C51语言,这两种语言都有良好的编译器支持,有为数众多的开发人员。一般来说,C51 语言用于较复杂的大型程序的编写,汇编语言则用在对效率要求很高的场合,尤其是底层函数的编写。

本节将简要介绍51单片机的C51语言的基础知识。1.2.1 C51语言的数据类型、运算符和表达式

数据是 51 单片机的操作对象,是具有一定格式的数字或数值。数据按照一定的数据类型进行的排列、组合和架构称为数据结构,C51语言支持的数据类型如表1.6所示。表1.6 C51语言支持的数据类型

1.常量和变量

C51 语言的数据可以分为常量和变量。常量的值在程序执行过程中不能发生变化,变量的值在程序执行过程中可以改变;常量通常用#define 关键字来定义,而变量通常用变量名来表示,由用户自己定义,是一个起始字符为字符或下划线,随后的字符必须是字母、数字或下划线的字符组合。变量在使用之前必须先定义。

2.C51语言的存储器和寄存器变量定义

51 单片机的存储器分为片内数据存储器、片外数据存储器、片内程序存储器和片外程序存储器。另外,在片内数据存储器中还存在寄存器单元,在C51程序中可以使用不同的存储器或寄存器来存放数据。表1.7给出了数据存储空间的关键字列表。表1.7 数据存储空间的关键字列表

注意:片内位寻址空间也可以按照字节访问,且支持位、字节混合访问。

如果在定义变量时省略了关键字,C51 编译器会自动地选择默认的存储类型。在第 3 章将介绍项目存储器属性可以选择为 SMALL、COMPACT 和 LARGE 方式,在这些模式下,程序中变量的存放地点和传递方式都是固定的。同时,C51 编译器也支持混合模式,如可以在 LARGE 模式下对一些需要快速执行的函数使用 SMALL 模式来加快执行过程。C51 语言的存储模式具体如表1.8所示。表1.8 C51语言的存储模式

注意:在 C51 语言中可以在定义变量类型之前指定存储类型,也就是说 pdata char var 和 char pdata var都是合法的定义。

C51语言支持使用关键字sfr和sfr16来定义51单片机的片内寄存器,同时支持使用sbit关键字对寄存器或变量中的位进行定义。

sbit 关键字也可以对其他的变量类型或绝对地址应用,但是该变量必须存放在位寻址内存空间(IDATA/DATA)中,绝对地址必须是位地址空间。同理,还有用于定义普通位变量的关键字bit。

3.C51语言的算术、赋值、逻辑及关系运算

在 C51 语言中,把用算术运算符和括号将运算对象连接起来的表达式称为算术表达式,其中运算对象包括常量、变量、函数、数组和结构等。在算术表达式中需要遵守一定的运算优先级,其规定为先乘除(余),后加减,括号最优先,同级别从左到右,和数学计算相同。

C51语言一共支持5种算术运算符,如表1.9所示。表1.9 算术运算符

C51 语言的赋值运算符包括普通赋值运算符和复合赋值运算符两种,普通的赋值运算符使用“=”,而复合赋值运算符是在普通赋值运算符之前加上其他二目运算符所构成的赋值符,使用赋值运算符连接的变量和表达式可以构成赋值表达式。

赋值运算涉及变量类型的转换,可以分为两种:一种是自动转换;另一种是强制转换。自动转换是指不使用强制类型转化符,直接将赋值运算符号右边的表达式或变量的值类型转化为左边的类型,一般来说是从“低字节宽度”向“高字节宽度”转换。表 1.10 给出了赋值运算中的自动类型转换。强制转换则是指使用强制类型转化符将一种类型转化为另外一种类型,强制类型转化符号和变量类型相同。表1.10 赋值运算中的自动类型转换

C51语言提供了以下3种逻辑运算符。

● 逻辑与:&&。

● 逻辑或:||。

● 逻辑非:!。

使用逻辑运算符将表达式或变量连接起来的表达式称为逻辑表达式,逻辑运算的内部运算次序是先逻辑非,后逻辑与和逻辑或,相同等级为从左到右。逻辑表达式的值为“真”或“假”。虽然在 C51 语言中使用“0”代表“假”,使用“非 0”代表逻辑“真”,但是逻辑表达式的结果只能使用“1”来表示“真”。

C51语言提供了以下6种关系运算符。

● 小于:<。

● 大于:>。

● 小于等于:<=。

● 大于等于:>=。

● 如果等于:==。

● 如果不等于:!=。

使用关系运算符连接的表达式或变量称为关系表达式,关系运算符中的前两种的优先级别高于后两种,同等优先级下遵守从左到右的顺序。关系表达式的运算结果是逻辑真“1”或逻辑假“0”。

4.C51语言的位操作

由于 51 单片机有位寻址空间,所以 C51 语言提供了对位变量操作的支持,包括位逻辑运算和移位运算两种类型。

位逻辑运算包括位与、位或、位异或、位取反。

● 位与:关键字为“&”。如果两位都为“1”,则位与的结果为“1”,否则为“0”。

● 位或:关键字为“|”,如果两位中有一个为“1”,则位或的结果为“1”,否则为“0”。

● 位异或:关键字为“^”,如果两位相等,则位异或的结果为“1”,否则为“0”;

● 位取反:关键字为“~”。如果该位为“1”,则位取反后的结果为“0”;如果该位为“0”,则位取反后的结果为“1”。

移位运算包括左移位和右移位运算。

● 左移位:关键字为“<<”,即将一个变量的各个位全部左移,空出来的位补 0,被移出变量的位则舍弃不要。

● 右移位:关键字为“>>”,其操作方式与左移位相同,只是移动方向变为向右。

5.C51语言的自增减、复合和逗号运算

C51语言的自增减运算分别是使变量的值增加或减少1,相当于“变量=变量+1”或“变量=变量-1”,其应用形式是“变量++”、“++变量”、“变量--”和“--变量”。

复合运算是将普通运算符和赋值符号结合起来的运算,有两个操作数的运算符都可以写成“变量、运算符=变量”的形式,相当于“变量=变量、运算符、变量”。

逗号运算的关键字为“,”,其一般应用形式为“表达式 1,表达式 2,…,表达式 n”。逗号表达式按照从左到右的方式运算,整个表达式的值取决于最后一个表达式。

6.C51语言运算符的优先级

表1.11给出了C51语言中运算符的优先级。表1.11 运算符的优先级1.2.2 C51语言的结构

为了根据不同的情况做出不同的控制动作,51 单片机的 C51 语言和普通的 C 语言一样,提供了控制流语句,通过不同的控制流语句的嵌套和组合可以控制单片机实现复杂的功能。控制流语句包括if、else if、switch、while等。

C51 语言的程序结构可以分为顺序结构、选择结构和循环结构,这三种结构可互相组合和嵌套,组成复杂的程序结构,完成相应的功能。

1.顺序结构

顺序结构是最简单和基本的程序结构,即程序从程序空间的低地址位向高地址位执行。

2.选择结构

在选择结构中,程序首先测试一个条件语句,如果条件为“真”则执行某些语句,如果条件为“假”则执行另外一些语句。选择结构可以分为单分支结构及多分支结构,多分支结构又包括串行多分支结构和并行多分支结构。选择语句构成了单片机判断和转移的基础,是模块化程序的重要组成部分。C51语言常用的选择语句有if语句、switch语句,其中if语句有if…else、if和else if三种形式。

3.循环结构

循环结构用于处理需要重复执行的代码块,即当某个条件为“真”时,重复执行某些相同的代码块。循环语句一般由循环体(循环代码)和判定条件组成。C51 语言常用的循环语句有while语句、do while语句和for语句。

4.break、continue和goto语句

在循环语句的执行过程中,如果需要在满足循环判定条件的情况下跳出代码块,可以使用break、continue语句;如果需要从任意地方跳到代码的某个地方,则可以使用goto语句。1.2.3 C51语言的函数

C51 语言支持把整个程序划分为若干个功能比较单一的小模块,通过模块之间的嵌套和调用来完成整个功能,这些具有单一功能的小模块称为函数,也可以称为子程序或过程。C51 程序就是由一个个函数构成的,其从一个主函数开始执行,调用其他函数后返回主函数,进行其他的操作,最后从主函数中退出整个C51程序。

1.函数的定义、参数和返回值

函数按照定义形式可以分为无参数函数和有参数函数,其定义方法如下:

函数的返回值是指在函数执行完成之后通过 return 语句返回给调用函数语句的一个值,返回值的类型和函数的类型相同。函数的返回值只能通过 return 语句返回。在一个函数中可以使用一个以上的 return 语句,但是最终只能执行其中一个 return 语句。如果函数没有返回值,则使用void标志。

2.函数的调用

一般而言,函数调用有使用函数名调用、函数结果参与运算,以及函数结果作为另外一个函数的实际参数三种调用方式,需要注意的是函数在被调用之前必须首先被声明。

C51语言的函数支持嵌套和递归调用。

3.局部变量和全局变量

局部变量是在某个函数中存在的变量,也可以称为内部变量,它只在该函数内部有效。局部变量可以分为动态局部变量和静态局部变量。一般使用关键字auto定义动态局部变量,使用关键字static定义静态局部变量。

全局变量是在整个源文件中都存在的变量,又称为外部变量。全局变量的有效区间是从定义点开始到源文件结束,其间的所有函数都可以直接访问该变量。如果定义点之前的函数需要访问该变量,则需要使用 extern 关键字对该变量进行声明;如果全局变量声明文件之外的源文件需要访问该变量,也需要使用extern关键字进行声明。1.2.4 C51语言的数组和指针

数组是一组由若干个具有相同类型的变量所组成的有序集合。它一般被存放在内存中一块连续的存储空间里,数组中的每一个元素都相继占有相同大小的存储单元。数组的每一个元素都有一个唯一的下标,通过数组名和下标可以访问数组的元素。构成数组的变量类型既可以是基本的数据类型,也可以是 1.2.5 节中讲到的用户自定义的结构、联合等类型。由整型变量组成的数组称为整型数组,由字符型变量组成的数组称为字符型数组,同理还有浮点型数组和结构型数组等。数组可以是一维的、二维的和多维的,其定义方式如下:

当一个数组被创建时,C51 编译器就会在存储空间里开辟一个连续的区域用于存放该数组的内容。对于一维数组来讲,会根据数组的类型在内存中连续开辟一块大小等于数组长度乘以数组类型长度(即类型占有的字节数)的区域。

当 C51 语言定义一个变量后,C51 编译器就会给这个变量在内存中分配相应的存储空间。例如,对于字符型(char)变量就会在内存中分配一字节内存单元,而对于一个整型(int)变量则会分配两字节内存单元。

假设程序中定义了 3 个整型变量 i、j、k,它们的值分别是 1、3,5,假设 C51 编译器将地址为1000和1001的两字节内存单元分配给了变量i,将地址为1002和1003的两字节内存单元分配给了变量 j,将地址为 1004 和 1005 的两字节内存单元分配给了变量 k。变量和内存地址的对应关系如图1.7所示。

在内存中,变量名 i、j、k 是不存在的,对变量的存取都是通过地址进行的。而存取的方式又分为两种:一种是直接存取方式,如int x=i*3,这时读取变量 i 的值是直接找到变量 i 在内存中的位置,即地址1000,然后从 1000 开始的两个字节中读取变量 i 的值,再乘以 3 作为结果赋给变量 x;另一种是间接存取方式,在这种方式下,变量 i 的地址 1000 已经存于某个地址(如 2000)中,这时要想存取变量 i 的值,可以先从地址 2000 处读出变量 i 的地址 1000,然后再从 1000 开始的两个字节中读取变量 i 的值,这就是指针。图1.7 变量和内存地址的对应关系

关于指针有两个重要的概念:变量的指针和指向变量的指针变量。

● 变量的指针:变量的指针就是变量的地址。例如,在上面介绍的例子中,变量i的指针就是地址1000。

● 指向变量的指针变量:在上面介绍的例子中,如果把用来存放变量i的地址的内存单元2000和一个变量关联,就像变量i关联地址单元1000一样,则这个变量就称为指向变量i的指针变量。显然指针变量的值是指针(变量的地址)。

指针变量定义的一般形式为

指针变量的引用是通过取地址运算符——“&”来实现的,在定

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载