自学51单片机-2

时间: 2023-08-15 admin 互联网

自学51单片机-2

自学51单片机-2

第2章 点亮你的LED

本章的标题是点亮LED,虽然任务很简单,但是需要大家了解的单片机基础知识却很多,特别是对于初学者,刚开始要在头脑中建立一个单片机的概念,然后通过点亮一个LED小灯来增加初学者对单片机的兴趣和自信。

2.1 单片机的内部资源

	在这里所讲到的单片机内部资源,和传统单片机书籍中讲单片机内部结构不同,这里讲到的内部资源是指作为单片机用户,单片机提供给读者可使用的东西。总结起来,主要是三大资源:
	(1)Flash----程序存储空间,早期单片机是OTPROM。
	(2)RAM------数据存储空间。
	(3)SFR------特殊功能寄存器。
	在早期的单片机中,主要是用OTPROM(One Time Programmable Read-Only Memory,即一次可编程只读存储器)来存储单片机的程序,程序只能写入一次,如果发现错了,没 有办法,只能换一片重新写入。随着技术的发展,Flash以其可重复擦写且容量大、成本低的优点成为现在绝大多数单片机的程序存储器。对于单片机来说,Flash最大的意义是断电后数据不丢失,这个概念类似于计算机的硬盘,保存了电影、文档、音乐等文件,把电源关掉后,下次重开计算机,所有的文件都还照样存在。
	RAM是单片机的数据存储空间,用来存储程序运行过程中产生的和需要的数据,跟计算机的内存是相似的概念,其实最典型的比喻是计算器。用计算器计算加减法,一些中间的数据都会保存在RAM里边,断电后数据丢失,所以每次打开计算器都是从归零开始计算。但是它的优点是读写速度非常快,理论上是可无限次写入的,即寿命无限,不管程序怎么运行和怎么读写,它都不会坏。
	第三个资源是SFR,特殊功能寄存器。这个概念大家可能刚开始理解不了,但是一定要记住。单片机有很多功能 ,每个功能都会对应一个或多个SFR,用户就是通过对SFR的读写来实现单片机的多种多样的功能的。
	讲到这里,首先来了解一下51单片机。通常一说到51单片机,指的都是兼容Intel MCS-51体系架构的一系列单片机,而51是它的一个通俗的简称。全球有众多的 半导体厂商推出了无数款这一系列的单片机,比如Atmel的AT89C52,NXP(Philips)的P89V51,宏晶科技的STC89C52......具体型号千差万别,但它们的基本原理和操作都是一样的,程序开发环境也是一样的。这里要分清楚51这个统称和具体的单片机型号之间的关系。
	单片机内部资源的三个主要部分清楚了,那么就选择STC89C52这款单片机来进行学习。STC89C52是宏晶科技出品的一款51内核的单片机,具有标准的51体系结构,全部的51标准功能,程序下载方式简单,方便学习,后面就用它来学习单片机。它的资源情况:Flash程序空间8K字节(1K=1024, 1字节=8位),RAM数据空间是512字节,SFR后边会逐一提到并且应用。
	2.2	单片机最小系统
		什么是单片机最小系统呢?单片机最小系统也称为单片机最小应用系统,是指用最少的原件组成的单片机可以工作的系统。单片机最小系统的三要素就是电源、晶振和复位电路,如下图所示。

这张最小系统的电路图节选自KST-51开发原理图,下面就照这张电路图来具体分析最小系统的三要素。

2.2.1 电源

	这个很好理解,电子设备都需要供电,就连家用电器(手电筒)也不例外。目前主流单片机的电源分为5V和3.3V这两个标准,当然现在还有对电压要求更低的单片机系统,一般多用在一些特定场合,在学习中不做过多的关注。
	选用STC89C52,它需要5V的供电系统,开发板是使用USB口输出的5V直流电直接供电的。从图2-1可以看到,供电电路在40引脚和20引脚的位置上,40引脚接的是+5V, +5V和GND之间还有个电容,作用在后面介绍。
	这个地方还要普及一个看原理图的知识。电路原理图是为了表达这个电路的工作原理而存在的很多器件在绘制的时候更多考虑的是方便原理分析,而不是表达各个器件实际位置。比如原理图中的单片机引脚图,引脚的位置是可以随意放的,但是每个引脚上有一个数字标号,这个数字标号代表的才是单片机真正的引脚位置。一般情况下,这种双列直插封装的芯片,左上角是1引脚,逆时针旋转引脚号依次增加,一直到右上角是最大脚位。现在选用的 单片机一共是40个引脚,因此右上角就是40(在表示芯片的方框的内部),如图2-2所示。大家要分清原理图引脚标号和实际引脚位置的区别。

2.2.2 晶振

晶振,又叫晶体振荡器,从这个名字就可以看出来,它注定一生都要不停振荡的。它起到的作用是为单片机系统提供基准时钟信号,类似于部队训练时喊口令的人,单片机内部所有的工作都是以这个时钟信号为步调基准来进行工作的。STC89C52单片机的18引脚和19引脚是晶振引脚,接了一个11.0592MHz的晶振(它每秒振荡11059200次),外加两个20pF的电容,电容的作用是帮助晶振起振,并维持振荡信号的稳定。
2.2.3	复位电路
在图2-1左侧是一个复位电路,接到了单片机的9引脚RST(Reset)复位引脚上,这个复位电路如何起作用后边再讲,现在着重讲一下复位对单片机的作用。单片机复位一般分三种情况:上电复位、手动复位和程序自动复位。
假如单片机程序有100行,当某一次运行到第50行的时候,突然停电了,这个时候单片机内部有的区域数据会丢失掉,有的区域数据可能还没有丢失。那么下次打开设备的时候,人们希望单片机能正常运行,所以 上电后,单片机要进行一个内部的初始化过程,这个过程就可以理解为上电复位。上电复位保证单片机每次都从一个固定的相同的状态开始工作。这个过程跟打开计算机电源的过程是一致的。
当程序运行时,如果遭受到意外干扰而导致程序死机,或者程序起跑飞的时候,就可以按下一个复位按键,让程序重新初始化重新运行,这个过程就叫作手动复位,最典型的就是计算机的重启按钮。
当程序死机或者跑飞的时候,单片机往往有一套自动复位机制,比如看门狗,具体应用以后再了解。在这种情况下,如果程序长时间失去响应,单片机看门狗模块会自动复位重启。还有一些情况是程序故意重启复位单片机。
电源、晶振、复位构成了单片机最小系统的三要素,也就是说一个单片机具备了这三个条件,就可以运行下载的程序了,其他的比如LED小灯、数码管、液晶等设备都是属于单片机的外部设备,即外设。最终完成用户想要的功能就是通过对单片机编程来控制各种各样的外设实现的。
2.3 	LED小灯
LED(Light-Emitting Diode),即发光二极管,俗称LED小灯,它的种类很多,参数了不尽相同,KST-51开发板用的是普通的贴片发光二极管。这种二极管通常的正向导通电压是1.8~2.2V,工作电流一般在1~20mA。其中,当电流在1~5mA变化时,随着通过LED的电流越来越大,人们的肉眼会明显感觉到这个灯越来越亮,而当电流在5~20mA变化时,看到的发光二极管的亮度变化就不太明显了。当电流超过20mA时,LED就会有烧坏的危险了,电流越大,烧坏的速度也就越快。所以在使用过程中应该特别注意它在电流参数上的设计要求。
下面来看一下这个发光二极管在开发板上的设计应用,USB接口电路如图2-3所示。

图2-3是开发板上的USB接口电路,通过USB线,计算机给开发板供电和下载程序以及实现计算机和开发板之间的通信。从图上可以看出,USB座共有6个接口,其中2引脚和3引脚是数据通信引脚,1引脚和4引脚是电源引脚,1引脚是VCC正电源,4引脚是GND即地线。5引脚和6引脚是外壳,直接接到了GND上,大家可以观察一下开发板上的这个USB座的6个引脚。
现在主要来看1引脚VCC和4引脚GND。1引脚通过F1(自恢复保险丝)接到右侧,在正常工作的情况下,保险丝可以直接看成导线,因此左右两边都是USB电源+5V,自恢复保险丝的作用是,当后级电路哪个 地方有发生短路的时候,保险丝会自动切断电路,保护开发板以及计算机的USB口,当电路正常后,保险丝会自动切断电路,保护开发板以及计算机的USB口,当电路正常后,保险丝会恢复畅通,正常工作。
右侧有两条支路,第一条是在+5V和GND接了一个470uF的电容,电容是隔离直流的,所以这条支路是没有电流的,电容的作用后面再介绍,下面主要看第二条支路。把第二条支路摘取出来就是如图2-4所示。
发光二极管是二极管的一种,和普通二极管一样,这个二极管也有阴极和阳极,习惯上也称之为负极和正极。原理图里的LED画成这样方便在电路上观察,方向必须接对了才会有电流通过,让LED小灯发光。刚才提到了接入的VCC电压是5V,发光二极管自身压降大概是2V,那么在右边R34这个电阻上承受的电压就是3V。现在如果要求电流范围是1~20mA,就可以根据欧姆定律R=U/I,把这个电阻的上限和下限值求出来。
U=3V,当电流是1mA的时候,电阻值是3K欧;当电流是20mA的时候,电阻值是150欧,也就是R34的限值范围是150~3K欧。这个电阻值大小的变化,直接可以限制整条通路的电流的大小,因此这个电阻通常称为”限流电阻“。图2-3中用的电阻是1k欧,这条支路电流的大小大家可以轻松计算出来,而这个发光二极管在这里的作用是作为电源指示灯,使用USB线将开发板和计算机连起来,这个灯就会亮了。
同理,在板子后级开关控制的地方,又添加了一个LED10发光二极管,作用就是当打开开关时,这个二极管才会亮。
大家注意,这里的开关虽然只有一个,但是是2路的,2路的开关并联能更好地确保给后级提供更大的电流。电容C19和C10都是隔离断开直流的,作用在后面介绍,这里大家可以忽略。
下面把图2-4变化一下,把右侧的GND去掉,改成一个单片机的I/O口,如图2-6所示。
图2-4由于电源从正极到负极有电压差,并且电路是导通的,所以就会有电流通过,LED小灯因为有了电流通过,所以就会直接发光。把右侧的原GND处接到单片机P0.0引脚上,如果单片机输出一个低电平,也就是跟GND一样的0V电压,就可以让LED小灯发光了。
单片机 是可以编程控制的,可以让P0.0这个引脚输出一个高电平,就是跟VCC一样的5V电压,那么这个时候,左侧VCC电压和右侧P0.0的电压是一致的,那就没有电压差,没有电压差就不会产生电流,没有电流LED就不会亮,也就是会处于熄灭状态。下面就用编程软件来实现控制小灯的亮和灭。
2.4 程序代码编写
这是第一个实验程序,一定要耐心,先来了解一些51单片机特有的程序语法以及Keil软件的基本操作步骤。
2.4.1 特殊功能寄存器和位定义
一般是用C语言来对单片机编程,而有的单片机有那么几条很特殊的独有的编程语句,51单片机就有,先介绍两条。
第一条语句是:
sfr P0 = 0x80;
其中,sfr是关键字,是51单片机特有的,它的作用是定义一个单片机特殊功能寄存器(special function register)。51单片机内部有很多个小模块,每个模块居住在拥有唯一房间号的房间内,同时每个模块都有8个控制开关。P0就是一个功能模块,就住在0x80这个房间里,人们就是通过设置P0内部这个模块的8个开关,来让单片机的P0这个8个I/O口输出高电平或者低电平的。而51单片机内部有很多寄存器,如果想使用必须提前进行sfr声明。不过Keil软件已经把所有这些声明都预先写好并保存到一个专门的文件中去了,如果要用只需在文件开头添加一行#include<reg52.h>即可,这个在后边有用法详解。
第二条语句是:
sbit LED = P0^0;
sbit 就是对刚才所说的SFR里边的8个开关其中的一个进行定义。经过上边第二条语句后,以后只要在程序里写LED,就代表了P0.0口(”^"这个符号在数字键6上边),注意这个P必须大写,也 就是说给P0^0又取了一个更形象的名字叫作LED。
了解了这两个语句后,再看一下单片机的特殊功能寄存器。请注意,每个型号的单片机都配有生产厂商所编写的数据手册(Datasheet),所以来看一下STC89C52的数据手册,从21页到24页,全部是对特殊功能寄存器的介绍以及地址映射列表。在使用这个寄存器之前,必须对这个寄存器的地址进行说明。是不是花花绿绿的太多了,记不住啊,这个没关系的,不需要你记住,了解一下,后边大部分会慢慢给大家解释,少部分需要用到的时候,自己查手册就可以了,做技术不是为了应付考试,可以随时翻阅手册查找需要的资料。
如图2-7所示是截取的手册中第22页最下边的一个表格。

来看一下这个表,其中P4口STC89C52对标准51的扩展的,先忽略它,只看前边的P0、P1、P2、P3这4个,每个P口本身又有8个控制端口。大家可以结合开发板原理图或者图2-1来看,这样就确定了单片机一共有32个I/O口(Input Output,I/O,分别是输入和输出)。
其中P0口所有的地址是0x80,一共有从7到0这8个I/O口控制位,后边有个Reset Value(复位值),这个很重要,是看寄存器必看的一个参数,8个控制位复位值全部都是1。这就是说,每当单片机上电复位的时候,所有的引脚的值默认是都是1,即高电平,在设计电路的时候也要充分考虑这个问题。
前面那两条语句,写sfr的时候,必须根据手册里的这个地址(Add)去写,写sbit的时候,就可以直接将一个字节其中某一位取出来。编程的时候,也有现成的写好寄存器地址的头文件,直接包含该头文件就可以,不需要逐一去写。
2.4.2 新建一个工程
对于单片机程序来说,每个功能程序都必须有一个配套的工程(Project),即使是点亮LED这样简单的功能程序也不例外,因此首先要新建一个工程,打开Keil软件后,单击Project-New uVision Project,然后会出现一个新建工程的界面 。
在硬盘上建立一个lesson2的目录,然后把LED这个工程的路径指定到这里,这样方便今后管理程序,不同的功能程序放到不同的文件夹下,并且给这个工程起一个名字叫作LED,软件会自动添加扩展名.uvproj,如图2-9所示。
直接单击“保存”按钮,工程会自动保存成LED.uvproj文件,下次要打开LED这个工程时,可以直接找到文件夹,双击.uvproj文件就可以直接打开了。
保存之后会弹出一个对话框,这个对话框让人们选择单片机型号。因为Keil软件是外国人开发的,所以国内的STC89C52并没有上榜,但是只要选择同类型号就可以了。因为

51内核是由Intel公司创造的,所以这里直接选择Intel公司名下的80/87C52来代替,这个选项的选择对于后边的编程没有任何的不良影响,如图2-10所示。
单击OK按钮之后,会弹出一个对话框,如图2-11所示,每个工程都需要一段启动代码,如果单击“否”按钮,编译器会自动处理这个问题,如果单击“是”按钮,这部分代码会提供给用户,用户就可以按需要自己去处理这部分代码,这部分代码在初学51的这段时间内,一般是不需要修改的,但是随着技术的提高和知识的扩展,就有可能需要了解这块内容,因此这个地方单击“是”按钮,让这段代码出现,但是暂时不需要修改它,大家知道这么回事就可以了。
这样工程就建立好了,如图2-12所示,如果单击Target 1左边的加号,会出现刚才加入的初始化文件STARTUP.A51。


工程有了之后,要建立编写代码的文件,单击File-New,如图2-13所示,新建一个文件,也就是编写程序的平台。然后单击File-Save或者直接单击Save按钮,可以保存文件,保存时把它命名为LED.c,这个地方必须加上.c,因为如果写汇编语言,这个地方的扩展名是.asm,头文件就是.h等,这里编写的是C语言程序,这个地方必须自己添加文件的扩展名.c,如图2-14所示。

现在就可以在建立好的文件中输入程序代码了,在编写之前还有个工作要做。每做一个功能程序,必须新建一个工程,一个工程代表了单片机要实现的一个功能。但是一个工程有时可以把程序分为多个文件写,所以每写一个文件,都要添加到所建立的工程中去,右击Source Group 1, 单击Add Files to  Group 'Source Group 1' ...,如图2-15所示。
在弹出的对话框中单击LED.c选中它,然后单击Add按钮,或者直接双击LED.c都可以将文件加入这个工程下,然后单击Close按钮,关闭添加(如图2-16所示)。这时会看到在Source Group 1 下边又多了一个LED.c文件。


2.4.3 编写点亮小灯的程序
忙活了半天,准备工作做了那么多,终于要编写程序代码了。如果学过C语言,应该能轻松地编程,如果没学过C语言也没有关系,先照着抄,下面在合适的位置写出对C语言语法的解释,这样抄几次后再看看解释,就应该很明白了,抄的时候一定要认真,尤其标点符号不可以搞错。

先从程序语法上来分析一下。
(1)main是主函数的函数名字,每一个C程序都必须有且仅有一个main函数。
(2)void是函数的返回值类型,本程序没有返回值,用void表示。
(3){}在这里函数开始和结束的标志,不可省略。
(4)每条C语言语句以分号(;)结束。
从逻辑上来看,程序这样写就可以了,但是在实际单片机应用中存在一个问题,比如程序空间可以容纳100行代码,但是实际上的程序只用了50行代码,当运行完50行,再继续运行时,第51行的程序不是自己想运行的程序,而是不确定的未知内容,一旦执行下去程序就会出错,从而可能导致单片机自动复位,所以通常在程序中加入一个死循环,让程序停留在所希望的这个状态下,不要乱运行,有以下两种写法可以参考:
参考程序(1):

参考程序(2):

程序(1)的功能是程序在反复不断地无限次执行“LED=0;”这条语句,而程序(2)的功能是执行一次,然后程序直接停留下来等待,相对程序(1)来说程序(2)更简洁一些。针对图2-6,这个程序能够把小灯点亮,但是这个程序却点不亮板子上的小灯,这是为什么呢?
这里大家就要培养一个意识了,做单片机编程,实际上算是硬件底层驱动程序开发,这种程序的开发是离不开电路图的,必须根据电路图来进行程序的编写。如果电路板的电路图和图2-6一样,程序可以成功点亮小灯,但是如果不一样,就可能点不亮。
开发板上还有一个74HC138作为8个LED小灯的总开关,而P0.0仅仅是个分开关。好像家里总是有一个供电总闸,然后每个电灯又有一个专门的开关,刚才的程序仅仅打开了那个电灯的开关,但是没有打开那个总电闸,所以程序需要加上这部分代码。因为介绍的内容比较多,所以把74HC138的原理以及为什么要加额外的代码在后面统一介绍,下面直接加上这部分代码,大家知道有这么一回事就可以了。

写了这么多啰唆的语句,刚开始大家可能觉得很麻烦,为什么有的书上程序很简单就可以点亮小灯,这里却这么麻烦呢。大家要了解一点,就是这个学习板,虽然仅仅提供给大家简单学习使用,但是也得按照实际产品的开发模式去设计,所以综合考虑因素很多,学到后边就会明白它的设计价值了,这里大家只要跟着去做就可以了。
程序编好后,要对程序进行编译,生成需要的可以下载到单片机里的文件,在编译之前,先要勾选一个选项,单击Project-Options for Target ‘Target1’…,或者直接单击图2-17中框内的快捷图标。

在弹出的对话框中,单击Output选项页,选中其中的Create HEX File复选框,然后单击OK按钮,如图2-18所示。

设置好以后,单击Project-rebuild all targer files,或单击图2-19中框内的快捷图标,就可以对程序进行编译了。

编译完成后,在Keil下方的Output窗口会出现相应的提示,大家注意看图2-20,这个窗口告诉我们编译完成后的情况,data=9.0,指的是程序使用了单片机内部的256字节RAM资源中的9个字节,code=29的意思是使用了8K代码Flash资源中的29个字节,当提示“0Error(s),0Warning(s)“表示程序没有错误和警告,就会出现“creating hex file from “LED”…”,意思是从当前工程生成了一个HEX文件,要下载到单片机上的就是这个HEX文件。如果出现错误和警告提示,就是Error和Warning不是0,那么就要对程序进行检查,找出问题,解决好了再进行编译产生HEX才可以。

到此为止,程序就编译好了,下边就要把编译好的程序文件下载到单片机里了。
2.5 程序下载
首先连接好硬件,把板子插到计算机上,打开设备管理器查看所使用的是哪个COM口,如图2-21所示,找到USB-SERIAL CH340(COM5)这一项,这里最后的数字就是开发板目前所使用的COM端口号。

然后打开 STC系列单片机的下载软件------STC-ISP,如图2-22所示。

下载软件有5个步骤:
第1步:选择单片机型号,现在用的单片机型号是STC89C52RC,一定不要选错了。
第2步:单击”打开程序文件“,找到刚才建立工程的那个文件夹,找到*.hex文件,单击打开。
第3步:选择刚才查到的COM口,波特率使用默认的就行 。
第4步:这里的所有选项都使用默认设置,不要随便更改,有的选项改错了可能会产生麻烦。
第5步:因为STC单片机要冷启动下载,就是先点下载,然后再给单片机上电,所以先关闭板子上的电源开关,然后单击Download按钮,等待软件提示你请上电后,如图2-23所示,再按下板子的电源开关,就可以将程序下载到单片机里了。
当软件显示“已加密”就表示程序下载成功了。

程序下载完毕就会自动运行,大家可以在板子上看那一排LED中最右侧的小灯已经发光了。如果把LED=0改成LED=1,再重新编译程序下载进去新的HEX文件。灯就会熄灭。至此,点亮一个LED的实验已经完成,终于迈出了第一步,是不是还挺好玩的呢?