先说某一组端口接一排8个LED灯的情况,如何做到让这八个灯想亮哪个就亮哪个,想不亮哪个就不亮哪个。
比如说,8个灯,全部负极接地电位,正极接P1的8个端口,则此种情况下,如果要某个灯亮,则对应的那一个单片机的端口就应该为高电位,照此推算下来,如果要让从P1.7到P1.0对应的灯为灭亮灭灭亮亮灭亮,则端口的电位应为低高低低高高低高,写成二进制八位数,就是01001101。
要实现这个,在单片机的设计上,就只需要把01001101送到P1端口就完成任务了。
这里就有一个问题,这个01001101在送到P1端口之前它在哪儿呢?在不同的位置,送法也肯定是不同的。
我们先说一种情况,就是我们的程序不做其它任何事,就只是实现这个功能,那么,最简单的做法,就是这个01001101已存在程序存储器中某个单元中,我们把程序存储器中的这个数,直接抓出来送到P1端口就行了,用语言描述其过程,就是:将程序存储器中的某一单元中的数据,当作数值,送入P1。
按这个思路,在单片机设计中,要考虑几个问题,首先要考虑的是,让其如何区分命令与数值,因为,在计算机中,命令与数值,都是以二进制数来表示的,而51单片机采用哈佛结构,存在程序存储器中的同一个区域,且并未做命令与数值的区别性标记,也就是说,单片机控制器即不可能根据数据的特征来区分,也不可能根据其存在的物理区域来区分是命令还是数值,所以必然另想办法。
在这个问题上,单片机是这样设计的:程序的执行过程,是随时钟一步一步地按程序存储器单元顺序从低到高地从程序存储中取出数据并送入控制器中(遇跳转指令则在跳转后,从跳转指令指定的地址开始,依然按这个规则进行),程序存储器中的第一个单元中的数据是必然的命令,每一命令紧随其后的单元中的数据是否是数值、如果是,有多少个单元是数值,均由这条命令来指定,取完这一个或几个单元的数据后,再下一个单元中的数据,规定为命令。
我们可以认为单片机可以采用这样一种方式进行处理(当然还有其它方式):从程序存储器中取出的数据,进入控制通道,通道最前面有两道并联且不会同时开同时关的门,命令进甲道门,数值进乙道门。对于将数值送入P1这个操作,其流程是:控制系统先收到将紧随其后第二个单元中的数据送入P1的命令后,关闭甲门并打开乙门,之后再根据紧随其后第一个单元中的数值所指向的P1的地址,将通向P1的门(而不是别的单元的门)全部打开,然后下一步,从程序存储器中收到的数据就直接送到P1口了。如果仅有一个单元的数据被当作数值传到端口,则这三步操作完成后,乙门关而甲门开,接收下一个数据并被当作命令送入控制器中。
再一个要解决的问题是:这个要被送入的数值存在哪个单元中?
单片机数值存放地的设计是这样的:前面说过,它们与命令一同都存在程序存储器中,那么存放的方式就有两种,一种是可以由程序员任意存放于任一单元中,也可以就近存放于操作这个数值的命令之后。程序员在编程中可以任选取这两者中的任何一种进行数值存放,对了,后一种,就是汇编语言中说的立即数,也就是上面所说到的那种处理方式。
对于前一种存放方式,我们在操作时,就必须在编程中确定并输入其地址。至于立即数方式,则直接在立即数的操作命令中指明:这个数你们别再找了,就在我身后,也就是说,前一种方式,需要向控制系统专门提交(源数值)地址值,而立即数方式,不再需要提交地址值。为什么有这两种设计?立即数方式具有一定的专用性,命令少速度快,前一种方式具有通用性但命令长而执行时间相对较长。
下面,我们就来说具体编程,流程是找到那个将立即数送入P1的命令,然后写出这个命令,再后面跟一个立即数,这个就可以运行了。但这里还有一个问题:51机是8位机,其命令最多只能做到256条,所以,理论上,在单片机设计时,可以设计这么一条直接将立即数送入P1的命令,但是,因为256条的限制,综合考虑,设计人员不一定会给这条命令让路也就是说,这个单片机中不一定有这条命令。
下面,我们就来在51单片机的机器指令中找一下,看有没有这么一条指令:我们知道,单片机中,P1属于片内存储单元,其地址是90H,而在其指令系统表中,我们找到了一条MOV direct,#data,这条汇编指令的意思是将立即数传递到片内存储器中指定的一个单元,这个命令的机器码就是75H,这个机器码本身已经指明紧随之后的程序存储器单元中的两个数据为数值而不是命令,其中第一个数值direct是接收数值的单元地址,第二个数值就是要被传送的数值01001101(4DH),三字节指令。这个指令比” MOV A, #data”要多一个字节,它的机器命令是74H,这个命令中,已经指明了接收数据的地址为RAM中的E0H单元,也就是累加器A,所以,不用你再写一个接收地址了,二字节指令,专用性很强,就是针对累加器A,当然,你也可以写成那个三字节指令,也当然,这样做真不当然。
好了,写汇编程序:“MOV direct,4DH”,再加一条让其不断重复执行的程序,汇编编程就完成了。当然,别忘了end,至于前面的ORG,可以不用,如果用的话,要么地址是0000H,要么前面还得加一条跳转。
不想写汇编,那就可以直接写机器语言:“75H 90H 4DH”,再加一条跳转指令,完成。
如果你用汇编,那就得用上汇编工具;如果你用机器语言,那你可以不用汇编工具,直接在烧写工具中,在第一个单元(0000H)中写入75H,在第二个单元中写入90H,在第三个单元中写入4DH,再写入一个跳转到第一个单元的指令,搞定,然后烧入、运行。当然,在这个程序中,你也可以不加跳转,但程序存储器中后面的单元必须全部清空,否则结果不定。
说明:在以上例子中,单片机中控制器的作用,就只是开门关门。控制器接收到命令后,就是根据这个命令开相应的门关相应的门。
PS:精神不太好,发一下神经,如果有错,千万要指出,免得害人啊。
|