单片机应用技术项目教程(C语言版)
上QQ阅读APP看书,第一时间看更新

知识链接

一、仿真软件Proteus的使用

仿真软件Proteus是英国Labcenter electronics公司出品的EDA工具软件。它不仅具有其他EDA工具软件的仿真功能,还能仿真单片机及外围器件。它是目前最好的仿真单片机及外围器件的工具。虽然目前国内推广刚起步,但已受到单片机爱好者、从事单片机教学的教师、致力于单片机开发应用的科技工作者的青睐。Proteus是世界上著名的EDA工具(仿真软件),从原理图布图、代码调试到单片机与外围电路协同仿真,一键切换到PCB(印制电路板)设计,真正实现了从概念到产品的完整设计。迄今为止是世界上唯一将电路仿真软件、PCB设计软件和虚拟模型仿真软件三合一的设计平台。

仿真软件Proteus包括两个环境:ISIS和ARES。电路图设计是在ISIS中,ARES用于PCB设计。Proteus ISIS是基于Windows平台的电路分析与实物仿真软件,可以仿真、分析(SPICE)各种模拟器件和集成电路,该软件的特点如下:

(1)实现了单片机仿真和SPICE电路仿真相结合。具有模拟电路仿真、数字电路仿真、单片机及其外围电路组成的系统的仿真、RS-232动态仿真、I2C调试器、SPI调试器、键盘和LCD系统仿真的功能;有各种虚拟仪器,如示波器、逻辑分析仪、信号发生器等。

(2)支持主流单片机系统的仿真。目前支持的单片机类型有:68000系列、8051系列、AVR系列、PIC12系列、PIC16系列、PIC18系列、Z80系列、HC11系列以及各种外围芯片。

(3)提供软件调试功能。具有全速、单步、设置断点等调试功能,同时可以观察各个变量、寄存器等的当前状态;同时支持第三方的软件编译和调试环境,如Keil C51μVision2等软件。

(4)具有强大的原理图绘制功能。

二、功能感受——Proteus仿真单片机播放音乐

(1)安装Proteus仿真软件,打开配套光盘中的“仿真实例\PlayMusic”文件夹,双击“PlayMusic.DSN”彩色图标,弹出如图2-1所示的Proteus仿真原理图。

(2)单击仿真工具栏中的仿真启动按钮,系统就会启动仿真。如果计算机上接有音箱,就能听到优美的音乐。

图2-1 Proteus仿真原理图

Proteus仿真设计快速入门

1.Proteus7Professional界面简介

安装完Proteus后,运行Proteus的ISIS模块,进入仿真软件的主界面,如图2-2所示。

如图2-2所示,区域①为主菜单及标准工具栏,区域②为预览窗口,区域③为对象选择器窗口,区域④为图形编辑窗口,区域⑤为绘图工具栏,区域⑥为元器件调整工具栏,区域⑦为运行工具条。下面简单介绍各部分的功能:

(1)图形编辑窗口:顾名思义,它是用来绘制原理图的。区域④为可编辑区,元件要放到它里面。注意,这个窗口是没有滚动条的,可用预览窗口来改变原理图的可视范围。

(2)预览窗口:它可显示两个内容,一个是当你在元件列表中选择一个元件时,它会显示该元件的预览图;另一个是,当你的鼠标光标落在图形编辑窗口时(即放置元件到图形编辑窗口后或在图形编辑窗口中单击后),它会显示整张原理图的缩略图,并会显示一个绿色的方框,绿色的方框里面的内容就是当前图形编辑窗口中显示的内容,因此,可用鼠标在它上面单击来改变绿色方框的位置,从而改变原理图的可视范围。

图2-2 仿真软件的主界面

(3)绘图工具栏:左侧绘图工具栏中包括了模型选择工具栏、配件、2D图形等。

①模型选择工具栏(ModeSelectorToolbar)。具体如下:

:用于即时编辑元件参数(先单击该图标再单击要修改的元件)。

:选择元件(components)(默认选择)。

:放置连接点。

:放置标签(用总线时会用到)。

:放置文本。

:用于绘制总线。

:用于放置子电路。

②配件(Gadgets)。具体如下:

:终端接口(terminals):有VCC、地、输出、输入等接口。

:器件引脚:用于绘制各种引脚。

:仿真图表(graph):用于各种分析,如NoiseAnalysis。

:录音机。

:信号发生器(generators)。

:电压探针:使用仿真图表时要用到,数字电路记录逻辑电平及强度,模拟电路中记录实际值。

:电流探针:使用仿真图表时要用到,仅在模拟电路中使用。

:虚拟仪表:有示波器等。

③2D图形(2DGraphics)。具体如下:

:画各种直线。

:画各种方框。

:画各种圆。

:画各种圆弧。

:画各种多边形。

:写各种文本。

:画符号。

:画原点等。

(4)对象选择器窗口。用于显示所挑选元件(components)、终端接口(terminals)、信号发生器(generators)、仿真图表(graph)等。例如,当选择“元件(components)”后,单击“P”按钮会弹出挑选元件对话框,选择一个元件后(单击OK按钮后),该元件会在对象选择器窗口中显示,以后要用到该元件时,只需要在元件列表中选择即可。

(5)方向工具栏。具体如下:

旋转:旋转角度只能是90°的整数倍。

翻转:完成水平翻转和垂直翻转。

使用方法:先右击元件,再单击(左击)相应的旋转图标。

(6)仿真工具栏。具体如下:

:运行:单步运行:暂停:停止。

2.Proteus仿真软件的基本操作步骤

1)Proteus电路设计

(1)新建设计。运行Proteus仿真软件的ISIS模块,进入仿真软件的主界面。单击工具栏上的“新建”按钮,新建一个设计文档。单击“保存”按钮,弹出如图2-3所示的“保存ISIS设计文件”对话框,在“保存在”下拉列表框中选择保存路径,在“文件名”文本框中输入“LED”(简单实例的文件名),再单击“保存”按钮,完成新建设计文件操作,其后缀名自动为.DSN。

(2)选取元器件。此简单实例需要如下元器件:

①单片机:AT89C51。

②发光二极管:LED-RED。

③片电容器:CAP*。

④电阻器:RES*。

⑤晶振:CRYSTAL。

⑥按钮:BUTTON。

单击图2-4中的P按钮,弹出图2-5所示的选取元器件窗口,在此对话框左上角“Keywords(关键词)”一栏中输入元器件名称,如“AT89C51”,系统在对象库中进行搜索查找,并将与关键词匹配的元器件显示在Results栏中。在Results栏中的列表项中,双击“AT89C51”,则可将“AT89C51”添加至对象选择器窗口。按照此方法完成其他元器件的选取,如果忘记关键词的完整写法,可以用“*”代替,如“CRY*”可以找到晶振。被选取的元器件均加入到ISIS对象选择器中,如图2-6所示。

图2-3 “保存设计文件”对话框

图2-4 单击P按钮选取元器件

图2-5 选取元器件窗口

图2-6 被选取的元器件均加入到ISIS对象选择器中

(3)放置元器件至图形编辑窗口。在对象选择器窗口中,选中AT89C51,将鼠标置于图形编辑窗口该对象的欲放置的位置,单击,完成该对象的放置。同理,将BUTTON、RES等放置到图形编辑窗口中,如图2-7所示。

图2-7 各元器件放在ISIS编辑窗口中合适的位置

若元器件方向需要调整,先在ISIS对象选择器窗口中单击选中该元器件,再单击工具栏上相应的转向按钮,把元器件旋转到合适的方向后再将其放置于图形编辑窗口中。

若对象位置需要移动,将光标移到该对象上,右击,此时注意到,该对象的颜色已变至红色,表明该对象已被选中,按下鼠标左键,拖动鼠标,将对象移至新位置后,松开鼠标左键,完成移动操作。

通过一系列的移动、旋转、放置等操作,将元器件放在ISIS编辑窗口中合适的位置,如图2-7所示。

(4)放置终端(电源、地)。放置电源操作:单击工具栏中的终端接口按钮,在对象选择器窗口中选择POWER,如图2-8所示,再在图形编辑区中选择要放电源的位置,单击完成。放置地(GROUND)的操作与此类似。

图2-8 放置终端符号

(5)元器件之间的连线。Proteus的智能化可以在用户想要画线的时候进行自动检测。下面,将电阻器R1的右端连接到LED显示器的左端,如图2-7所示。当鼠标的指针靠近R1右端的连接点时,跟着鼠标的指针就会出现一个“□”号,表明找到了R1的连接点,单击,移动鼠标(不用拖动鼠标),将鼠标的指针靠近LED的左端的连接点时,跟着鼠标的指针就会出现一个“□”号,表明找到了LED显示器的连接点,单击即可完成电阻器R1和LED的连线。

Proteus具有线路自动路径功能(简称WAR),当选中两个连接点后,WAR将选择一个合适的路径连线。WAR可通过使用标准工具栏里的“WAR”命令按钮来关闭或打开,也可以在菜单栏的Tools下找到这个图标。

同理,可以完成其他连线。在此过程的任何时刻,都可以按【Esc】键或者右击来放弃画线。

(6)修改、设置元器件的属性。Proteus库中的元器件都有相应的属性,要设置修改元器件的属性,只需要双击ISIS编辑区中的该元器件。例如,发光二极管的限流电阻器R1,双击,弹出图2-9所示的属性窗口,在窗口中已经将电阻器的阻值修改为330Ω。图2-10是编辑完成的简单实例的电路。

图2-9 设置限流电阻器阻值为330Ω

2)Proteus仿真

(1)加载目标代码文件。双击编辑窗口的AT89C52器件,在弹出图2-11所示属性编辑对话框ProgramFile一栏中单击“打开”按钮,弹出“文件浏览”对话框,找到FLASH_LED.HEX(用Keil C51软件生成)文件,单击“打开”按钮,完成文件添加。在Clock Frequency栏中把频率设置为12MHz,仿真系统则以12MHz的时钟频率运行。因为单片机运行的时钟频率以属性设置中的Clockfrequency为准,所以在编辑区设计MCS-51系列单片机系统电路时,可以略去单片机振荡电路,并且复位电路也可以略去。

图2-10 编辑完成的简单实例的电路图

图2-11 加载目标代码文件窗口

(2)仿真。单击按钮,启动仿真,仿真运行片段如图2-12所示。发光二极管间隔500ms闪烁。

图2-12 仿真运行片段

三、Keil C51软件的使用

(一)Keil C51软件概述

Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统。使用接近于传统C语言的语法来开发,与汇编语言相比,C语言在功能上、结构性上、可读性上、可维护性上有明显的优势,因而易学易用,而且大大地提高了工作效率和项目开发周期,它还能嵌入汇编,用户可以在关键的位置嵌入,使程序达到接近于汇编的工作效率。

Keil C51软件提供丰富的库函数和功能强大的集成开发调试工具,全Windows界面,使用户能在很短的时间内就能学会使用Keil C51来开发单片机应用程序。另外重要的一点,只要看一下编译后生成的汇编代码,就能体会到Keil C51生成的目标代码效率非常高,多数语句生成的汇编代码很紧凑,容易理解。在开发大型软件时更能体现高级语言的优势。

C51工具包可以完成编辑、编译、连接、调试、仿真等整个开发流程。开发人员可用集成开发环境(IDE)本身或其他编辑器编辑C或汇编源文件。然后分别由C51及C51编译器编译生成目标文件(.OBJ)。目标文件可由LIB51创建生成库文件,也可以与库文件一起经LIB51连接定位生成绝对目标文件(.ABS)。ABS文件由OH51转换成标准的hex文件,以供调试器dScope51或tScope51使用,进行源代码级调试;也可供仿真器使用,直接对目标板进行调试;也可以直接写入程序存储器如EPROM中。

(二)Keil C51软件的使用

双击桌面快捷图标,启动软件,启动界面如图2-13所示。几秒后出现软件操作界面如图2-14所示。

图2-13 启动界面

图2-14 软件操作界面

1.建立工程

(1)单击Project菜单,在弹出的下拉菜单中选择NewProject命令,如图2-15所示。弹出CreateNew Project窗口,在“文件名”文本框中输入C程序项目名称(只要符合Windows文件规则的文件名都可以),这里用“FLASH_LED”作为文件名,在“保存在”下拉列表框中选择项目保存路径,如图2-16所示,然后单击“保存”按钮。

(2)这时会弹出一个对话框,要求选择单片机的型号。用户可以根据所使用的单片机来选择,Keil C51几乎支持所有的51核的单片机,这里以用得比较多的Atmel的AT89C51来说明,如图2-17所示,选择AT89C51之后,右边栏是对这个单片机的基本的说明,单击“确定”按钮后,出现图2-18所示对话框,单击“否”按钮,返回主界面。

图2-15 选择NewProject命令

图2-16 CreateNewProject窗口

图2-17 器件选择窗口

图2-18 “是”“否”对话框

到现在为止,还没有编写一句程序,下面开始编写第一个程序。

(3)单击File菜单,在弹出的下拉菜单中选择New命令,弹出的界面如图2-19所示。此时光标在编辑窗口里闪烁,这时可以输入用户的应用程序了。输入源程序后如图2-20所示,然后单击“保存”按钮,弹出SaveAs对话框,如图2-21所示。在“文件名”文本框中输入欲使用的文件名,同时,必须输入正确的扩展名,在这里输入FLASH_LED.C。[注意,如果用C语言编写程序,则扩展名为(.c);如果用汇编语言编写程序,则扩展名必须为(.asm)。]然后,单击“保存”按钮。

图2-19 New命令

图2-20 输入用户源程序

图2-21 输入文件名FLASH_LED.C

(4)单击Target1前面的“”号,出现下一层的Source Group1,这时的工程还是一个空的工程,里面没有文件,需要把编写好的源程序加入,单击“Source Group1”使其反白显示,然后右击,出现如图2-22所示的下拉菜单。选择Add file to Group‘Source Group1’命令,弹出图2-23所示对话框,要求寻找源文件FLASH_LED.C,单击Add按钮。(注意,该对话框下面的“文件类型”默认为.csourcefile(*.c),也就是以.c为扩展名的文件,如为汇编文件,需要将文件类型改为“.Asm”。)

图2-22 选择Add Files to Group‘Source Group1’命令

图2-23 加入源文件

2.工程设置

工程建立好以后,还要对工程进行进一步的设置,以满足要求。首先单击左边Project窗口的Target1,然后单击Project菜单,在弹出的下拉菜单中选择Option for target‘target1’命令,即出现对工程设置的对话框,这个对话框可谓非常复杂,共有8个选项卡,要全部搞清楚可不容易。在这里只有Target,Output选项卡中有选项需要稍做修改,其余绝大部分设置默认值就可以了。

(1)设置对话框中的Target选项卡。Target选项卡设置如图2-24所示。Target选项卡中Xtal(MHz)为12.0,其余选项选择默认值。Xtal(MHz)表示晶振频率值,默认值是所选目标CPU的最高可用频率值,根据需要进行设置。该数值与最终产生的目标代码无关,仅用于软件模拟调试时显示程序执行时间。正确设置该数值可使显示时间与实际所用时间一致,一般将其设置成与硬件所用晶振频率相同,如果没必要了解程序执行的时间,也可以不设。

图2-24 Taret选项卡设置

(2)设置对话框中的Output选项卡。Output选项卡设置如图2-25所示。在Output选项卡中,选中CreateHEXFile复选框,这样能够保证在编译、连接之后能产生hex为后缀的文件,从而供第三方软件使用,比如Proteus仿真软件。

图2-25 Output选项卡设置

(3)设置对话框中的Debug选项卡。Debug选项卡设置如图2-26所示。该选项卡分为左右两半,左边是软件仿真设置,而右边是硬件仿真设置,当用户使用软件仿真时,选中左边的UseSimulator单选按钮;当用户使用硬件仿真器时,选中右边的UseKeilMonitor-51Driver单选按钮,同时把硬件仿真器连接到计算机串口上。在这里使用软件仿真,因此只要选中左边的UseSimulator单选按钮,其余选项保持默认值。

图2-26 Debug选项卡设置

3.编译、连接

(1)单击图标进行编译,编译成功后,源程序编译相关的信息会出现在输出窗口中,显示编译结果为0Error(s),0Warning(s),如图2-27所示。如有语法错误,会给出提示,应修改出错处后,再次编译。

图2-27 源程序编译

(2)单击Project菜单,在弹出的下拉菜单中选择BuiltTarget命令(或者使用快捷键【F7】或单击图标),显示连接结果为0Error(s),0Warning(s),同时产生了目标文件FLASH_LED.hex,如图2-28所示。

图2-28 链接结果

(3)编译通过后,打开工程文件夹,如图2-29所示,可以看到文件夹中有了“FLASH_LED.hex”图标,这就是我们需要的最终目标文件,提供给Proteus仿真软件的单片机使用,或给编程器(又称烧录器)把该文件写入单片机。

图2-29 打开工程文件夹

4.进入调试

(1)单击Debug菜单,在弹出的快捷菜单中选择Start/Stop Debug Session命令,这个命令可以打开调试也可以关闭调试,如图2-30所示。调试窗口如图2-31所示。

图2-30 打开/关闭调试选项

图2-31 调试窗口

(2)单击Peripherals菜单,在弹出的快捷菜单中选择I/O-Ports→P1命令,如图2-32所示。这样在程序运行时,就可以观察P1口每位的变化。

(3)单击进入单步执行状态,单击一次,执行一行程序,执行完该行程序以后即停止,等待命令发出后,再执行下一行程序,此时可以观察该行程序执行完以后得到的结果,是否与预期结果相同,借此可以找到程序中问题所在。下面来看看语句的执行对P1.0的影响。

从图2-33中可以看出,P1.0输出的电平有变化,从高电平变为低电平,对应的硬件电路中的发光二极管就会闪烁一次。除单步执行方式之外,还有其他方式,下面简单介绍一下:

:过程单步,是指将汇编语言中的子程序或高级语言中的函数作为一个语句来全速执行。调试光标不进入子程序的内部,而是执行完该子程序,然后直接指向下一行。

:执行完当前子程序,是指进入子程序后单击此按钮,子程序中其余没有执行的指令将一次全部执行完毕,加快程序的执行进度。

:运行到当前行,全速执行当前地址行与当前光标行之间和程序。主要看一段程序运行情况,可以加快程序的调试。

:全速执行,是指一行程序执行完以后紧接着执行下一行程序,中间不停止,主要看程序执行的最终结果,如果程序有错,则难以确认错误出现在哪些程序行。

程序调试中,这几种运行方式都要用到。灵活应用这几种方法,可以大大提高查错的效率。

图2-32 选择P1口进行观察

图2-33 观察P1.0输出的电平

四、单片机烧写器及烧写软件的使用

(一)烧写及烧写器

1.为什么称为“烧写”

早期一般是将调试好的单片机程序写入到ROM、EPROM中,这种操作就像刻制光盘一样,是在高电压方式下写入的,PROM是一次性写入的,存储器内部发生变化,有些线路或元件就被烧断,不可再恢复,所以称为烧写,EPROM可以使用紫外线将原来写入的内容擦除,重新烧写,目前大量采用EEPROM,是可以电擦写的存储器。单片机启动时会直接运行这些芯片中的程序,完成既定的功能。

所谓烧写,其实就是对单片机中的ROM进行擦写。现代工艺下,ROM已经可以进行多次擦写,但在早期,ROM只能一次性设计好,例如早期的PLC,把二极管上的熔丝烧断后就永久编码出1。而我们知道,单片机程序经编译连接后传递给机器的便是机器语言,简而言之就是很多1和0。在烧写过程中,我们用烧不烧MOS管和晶体管的熔丝或连不连上通道来表示这些1和0。

2.烧写的三种方式

(1)把单片机看作一个ROM芯片,早期的单片机都是如此。将单片机放在通用编程器上编程时,就像给28C256这样的ROM中写程序的过程一样。只是不同的单片机使用的端口,编程用的时序不一样。

(2)像AT89S系列单片机或AVR单片机一样,在单片机上有SPI接口,这时可用专用的下载线将程序烧写到单片机中。这时不同的是,单片机的CPU除了执行单片机本身的指令之外,还能执行对ROM进行操作的特殊指令,如ROM擦除、烧写和检验指令。在编程ROM时,下载线通过传输这些指令给CPU执行(擦除ROM、读入数据、烧写ROM和检验ROM),完成对单片机的ROM的烧写。此外,现在普遍使用的JTAG仿真器也是这样,单片机的CPU能执行JTAG的特殊指令,完成对ROM的烧写操作。

(3)引导程序,即单片机中已经存在了一个烧写程序。启动单片机时首先运行这个程序,程序判断端口状态,如果有“要烧写ROM”的状态,就从某个端口(串口、SPI等)读取数据,然后写入到单片机的ROM中。如果没有“要烧写ROM”的状态,就转到用户的程序开始执行。如AVR单片机的Bootloader方式、STC的串口下载方式,还有其他单片机的串口编程等都是这样。

3.烧写器

烧写器又称编程器、烧录器,只是每个人的叫法不一样而已。烧写器实际上是一个把可编程的集成电路写上数据的工具,烧写器主要用于单片机(含嵌入式)/存储器(含BIOS)之类的芯片的编程(又称“刷写”)。

(二)烧写软件

1.单片机烧写软件简介

简单说,就是把用户写好的代码(C语言程序或者是汇编)编译成机器语言,利用某种软件通过一定的方式下载到单片机中,这种软件就成为烧写软件。烧写软件很多,方式也很多,主要是看单片机的型号。比如,STC系列单片机需要STC_ISP程序下载软件,而AT89S系列单片机通常采用Easy 51pro下载软件。

2.Easy 51pro下载软件的使用

Easy 51pro下载软件可以烧录Atmel公司生产的AT89C51、AT89C52、AT89C55和最新的AT89S51、AT89S52单片机芯片,支持hex文件,具有性能稳定、烧录速度快、性价比高等优点,甚至可以让整套软件在其他编程器硬件上运行。下载线、编程器都有相关的调试程序,让用户制作时更轻松,提高了成功率。

下面就以本书所讲述的AT89S51单片机采用的Easy 51pro下载软件为例,介绍其使用方法。

首先把软件安装到计算机中。双击Easy 51pro.exe图标即可出现如图2-34所示的对话框。

单击右下角的设置按钮进行图2-35所示的设置,接着在检测器件的窗口中选择要下载的目标芯片,如AT89S52。

图2-34 Easy 51pro打开界面

图2-35 Easy 51pro软件设置界面

其次,AT89S51/S52芯片插到40P的锁紧座中,25针的并口线一端连计算机的并口,另一端与下载连接线相连,再把8P的排线和实验箱或开发板上的ISP下载接口相接,然后在烧录界面中单击“检测器件”按钮看是否可以检测到所烧的目标芯片,并听到相应的声音信号。否则请检查硬件连接和端口设置。

接着打开下载界面,单击“打开文件”按钮,选择需要下载的程序hex文件,可以一步一步地手动完成,也可以单击“自动完成”按钮,一项一项地往下进行,等烧录完成之后,就可以运行自己的实验程序了。

图2-34中相关操作说明如下:

(1)用“(自动)打开文件”打开要编写的.hex文件和.BIN文件。

(2)用“保存文件”可以保存读出来的文件。

(3)用“(自动)擦除器件”擦除芯片。

(4)用“(自动)写器件”编程。

(5)用“读器件”读取芯片中的程序,加密的读不出来。

(6)用“(自动)检验数据”检查编程的正确与否。

(7)用“自动完成”自动执行以上各步骤。

(8)用“加密”选择加密的级数。

五、C51语言源程序的结构特点

(一)概述

单片机C51语言是由C语言继承而来的。和C语言不同的是,C51语言运行于单片机平台,而C语言则运行于普通的桌面平台。C51语言具有C语言结构清晰的优点,便于学习,同时具有汇编语言的硬件操作能力。对于具有C语言编程基础的读者,可轻松地掌握单片机C51语言的程序设计。

Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编语言相比,C语言在功能上、结构性上、可读性上、可维护性上有明显的优势,因而易学易用。Keil C51以软件包的形式向用户提供,主要包括C51交叉编译器、A51宏汇编器、BL51连接定位器等一系列工具和基于Windows集成编译环境的μVision51,软件仿真器dScope51等开发平台。μVision51是一种集成化的文件管理编译环境,其中集成了文件编辑处理、编译连接、项目(project)管理、窗口和工具引用以及工作环境路径设置等多种功能。在μVision51中完成一个项目文件后,只要单击MakeAll按钮就可完成所有的编译工作,生成绝对目标代码。dScope是Windows集成编译环境下的多窗口软件仿真调试器,可以单独应用,也可以通过μVision51进行调用。dScope具有十分强大的仿真调试功能,支持软件模拟仿真和用户目标板调试两种工作方式。在软件模拟仿真方式下,不需要任何8051单片机硬件即可完成用户程序仿真调试,极大地提高了用户程序开发效率;与用户目标板相连时,可以直接进行硬件系统调试,可以节省用户购买昂贵硬件仿真器的费用。

(二)C51语言的基本程序结构

C语言源程序文件的扩展名为“.c”,如Timer.c,EX1_2.c等。C语言源程序由若干个函数单元组成,每个函数都是完成某个特殊任务的子程序段。一个C语言程序必须有而且只能有一个名为main()的函数,它是一个十分特殊的函数,又称该程序的主函数,程序的执行都是从main()函数开始的。下面先来看一个简单的程序例子:

【例】求两个输入数据中的较大者。

在本例程序的开始处使用了预处理命令#include,它告诉编译器在编译时将头文件stdio.h和reg51.h读入后一起编译。头文件stdio.h中包括了对标准输入输出函数的说明;头文件reg51.h中包括了8051单片机特殊功能寄存器的说明。

程序中,main是主函数名,要执行的内容称为主函数体,主函数体用花括号“{}”围起来。主函数体中包含若干条将被执行的程序语句,每条语句都必须以分号“;”为结束符。为了使程序便于阅读和理解,可以给程序加上一些注释。C语言的注释部分一般由符号“/*”开始,由符号“*/”结束,它们之间的内容即为注释,该注释方式可注释多行内容;另一种采用“∥”的方式,这种方式只能注释一行内容。注释内容可在一行写完,也可以分成几行来写。注释部分不参加编译,编译时,注释的内容不产生可执行代码。注释在程序中的作用是很重要的,一个良好的程序设计者应该在程序中使用足够的注释来说明整个程序的功能、有关算法和注意事项等。需要注意的是,C语言中的注释不能嵌套,即在“/*”和“*/”之间不允许再次出现“/*”和“*/”。

一般情况下,一个C语言程序除了必须有一个主函数之外,还可能有若干个其他的功能函数。本程序中除了main()函数之外,还用到了一个功能函数max()。函数max()的作用是求出变量x和y中较大者,并通过return语句将它的值返回到main()函数的调用处。变量x和y在函数max()中是一种形式变量,实际值是通过main()函数中的调用语句传送过来的。此外,ANSIC标准规定函数必须要“先说明、后调用”,因此,在调用函数max()之前必须先进行说明。函数是C语言程序的基本单位。函数调用类似于子程序调用,用户可以根据实际需要编制出各种不同用途的功能函数。可以说,C语言是函数式的语言。利用C语言的这一特点,可以很容易实现结构化的程序设计。

C51编译器提供了十分丰富的库函数,本例在main函数中调用了库函数scanf()和printf()来实现变量的输入和输出。C语言本身没有输入和输出功能,输入输出需要通过函数调用来实现。需要注意的是,C51提供的输入和输出库函数是通过8051单片机的串行口来实现的。因此,在调用库函数scanf()和printf()之前,必须先对8051单片机的串行口进行初始化。但是对于单片机应用系统来说,由于具体要求的不同,应用系统的输入和输出方式也多种多样,不可能一律采用串行口作输入和输出。应该根据实际需要,由应用系统的研制人员自己来编写满足特定需要的输入和输出函数,这一点对于单片机应用系统的开发研制人员来说是十分重要的。

另外C语言规定,同一个字母由于其大小写的不同可以代表两个不同的变量,例如,SCON和scon在C语言程序中会被认为是两个完全不同的变量,这也是C语言程序的一个特点。一般的习惯是,在普通情况下采用小写字母,对一些具有特殊意义的变量或常数采用大写字母,如本例中,8051单片机特殊功能寄存器SCON,TMOD,TCON和TH1等均采用了大写字母。

从以上说明可以看到,C语言程序一般具有如表2-1所示的结构。

表2-1 C语言程序一般具有的结构

C语言程序的开始部分通常是预处理命令,如上面程序中的#include命令。这个预处理命令通知编译器在对用户程序进行编译时,将所需要的头文件(*.h)读入后,再一起进行编译。一般在头文件中包含程序编译时的一些必要的信息。通常C语言编译器会提供若干个不同用途的头文件,头文件的读入是在对程序进行编译时才完成的,此外还有其他一些预处理命令。

一个C语言程序至少应包含一个主函数main(),也可以包含一个main()函数和若干个其他的功能函数。函数之间可以相互调用,但main()函数只能调用其他的功能函数,而不能被其他函数所调用。功能函数可以是C语言编译器提供的库函数,也可以由用户按实际需要自行编写。不管main()函数处于程序中的什么位置,程序总是从main()函数开始执行。一个函数由“函数定义”和“函数体”两个部分组成。函数定义部分包括函数类型、函数名、形式参数说明等。函数名后面必须跟一个圆括号(),形式参数说明在()内进行。函数也可以没有形式参数,如main()。函数体由一对花括号“{}”组成,在“{}”里面的内容就是函数体。如果一个函数有多个“{}”,则最外面的一对“{}”为函数体的范围。函数体的内容为若干条语句,一般有两类:一类为说明语句,用来对函数中将要用到的变量进行定义;另一类为执行语句,用来完成一定的功能或算法处理。有的函数体仅有一对“{}”,其中既没有变量定义语句,也没有执行语句,这也是合法的,称为“空函数”。

(三)C51语言标识符与关键字

C51语言的标识符是用来标识源程序中某个对象名字的。这些对象可以是函数、变量、常量、数组、数据类型、存储方式、语句等。一个标识符由字母、数字和下画线等组成,第一个字符必须是字母或下画线,C语言对大小写字母敏感,如“max”与“MAX”是两个完全不同的标识符。程序中标识符的命名应当简洁明了,含义清晰,便于阅读理解,如用标识符“max”表示最大值,用“TIMER0”表示定时器0等。

关键字是一类具有固定名称和特定含义的特殊标识符,有时又称保留字。在编写C语言源程序时,一般不允许将关键字另作别用,也就是标识符的命名不要与关键字相同。与其他计算机语言相比,C语言的关键字是比较少的,ANSIC标准一共规定了32个关键字,表2-2按用途列出了ANSIC标准的关键字。

表2-2 按用途列出ANSIC标准的关键字

续表

C51编译器除了支持ANSIC标准的关键字以外,还根据8051单片机自身特点扩展了如表2-3所示的关键字。

表2-3 根据8051单片机自身特点扩展的关键字

续表