我们已经了解了单片机的基本引脚功能,现在我们就来看一看要让单片机能够工作,我们应该做些什么呢。
上面的图就是单片机的最小系统示意,一般来说,单片机的最小系统包括电源(地),晶振(一般使用11.0592M或者12M),复位电路。有了以上三块内容,单片机就能够工作了。另外要注意的一点是,EA(31脚)也要接高电平,告诉单片机不使用片外存储器,这样单片机系统才会老老实实地执行你烧写进去的程序。
在以上的最小系统中,我们还接了一个发光二极管电路,来验证我们的最小系统是不是能够正常工作。
还记得Keil的使用方法吗?用Keil把以上代码编译一下,生成.hex文件,然后就可以烧写了。
什么是HEX文件呢?HEX文件格式是Intel公司提出的按地址排列的数据信息,数据宽度为字节,所有数据使用16进制数字表示,,常用来保存单片机或其他处理器的目标程序代码。它保存物理程序存储区中的目标代码映象。一般的编程器都支持这种格式。接下来,将.hex烧写到单片机的ROM里面。当然,烧写的方法有很多种,你可以买一个通用的烧写器,也可以直接并口在线下载(比如:Atmel的S系列都支持),也可以采用USB-串口下载的(比如:STC系列的支持)。如果你是直接买的开发板,肯定会给你提供一个切实可行的烧写方法,如果你是自己焊的最小系统,那么你可以选择用烧写器或者借用别人的开发板烧写,Whatever,烧写程序并不困难,写程序才是关键!
一切就绪后,接上电源,复位一下,如果最小系统工作的话,应该显示出一个一闪一闪的发光二极管。
下面我们简单看一下程序。良好的注释习惯是编程序必备的要素,首先看一下Keil C编译器所支持的注释语句。一种是以“//”符号开始的语句,符号之后的语句都被视为注释,直到有回车换行。另一种是在“/*”和“*/”符号之内的为注释。注释不会被C 编译器所编译。与C语言一样,Keil C也应该有一个main主函数,main函数可以调用别的功能函数,但其它功能函数不允许调用main函数。不论main函数放在程序中的那个位置,总是先被执行。
程序中P1_0是在头文件中声明的,有兴趣可以打开AT89X51.h看看所有定义。它的意思就是单片机I/O口的P1.0,P1_0=0意思就是把P1.0置低电平,反之,P1_0=1就是置高电平。
while循环是所有单片机程序必须的要素,因为单片机程序不像普通的C程序,算完后printf出来就行了,单片机要能够
永远工作下去,所以必须做成死循环,不然单片机程序结束了,单片机就失去控制了,这就是程序跑飞了~常见的用法就是直接在单片机main函数最后加上while(1);,意思是单片机执行到这里就停止了,但是先前处理过的数据,I/O状态等都还没有丢失,并且一旦来了中断,单片机就能够继续响应中断,再次运行中断程序。
在示例中,我们采用的是do-while循环构成死循环,这样做可以实现单片机不断重复某一个操作,比如流水灯,按键扫描等等。for循环实质是一个延时程序,我们知道,程序每执行一步都要花时间,将a自加50000次,这个时间足够人眼分辨灯的闪烁了。当然,这种计时是相当不精确的。首先C语言不像汇编那样能够精确控制执行时间(执行一条汇编语句需要一个机器周期,一个机器周期通常等于12个时钟周期,所以12M晶振大约1us),每条C语句通过不同的编译器生成的对应的汇编代码都不一定一样,当然不能够知道C语言一条语句需要多长时间了;其次不同的单片机执行语句的机器周期也不一定一样(比如:Atmel 51系列及大多数51的一个机器周期是12个时钟周期,华邦的只需要4个时钟周期)。不过大体来说,一条for循环大概8个机器周期,在12M晶振下,通常用以下代码实现1ms的延时:
大概算一下,120*8*1us=1ms,如果需要精确的定时,还是得用定时器,我们以后介绍。
到这里,我们大概了解了单片机硬件和软件的最小系统,俗话说得好,好的开始是成功的一半~