讲到了指令MOV P3,#0FFH 能使P3 口全部为高电平,而在第四课中LED 灯闪烁程序中给R7 送数用的指令是MOV R7,#250 ,那么这#250 和#0FFH 到底有什么不同?它们又代表什么意思呢?
复习一下数字电路中学过的数制概念:
一.数制
1.十进制数(Decimal Number)
在日常生活中,我们表示数的多少用的是十进制数,即0,1,2,3,4,5,6,7,8,9。它遵循“逢十进一,借一当十”的原则,通常我们把计数符号的个数叫做基数,十进制的基数就是十。
比如一个十进制数5847=5*1000+8*100+4*10+7*1 ,它的每一个数码都有一个系数1000,100,10,1;这个系数叫做权或位权。十进制数虽然非常符合我们的使用习惯,但计算机中却无法采用,因为计算机只能有两种状态:“0”和“1”,所以我们还得应用二进制数。
2.二进制数(Binary Number)
二进制的基数为二,0 和1,它遵循的是“逢二进一,借一当二”的进借位原则。也就是当某位计数到两个数时就向高位进“1”,同时本位变为“0”。
比如二进制数1100=1*23+1*22+0*21+0*20,二进制数只有0 和1 两个数,正好代表了计算机中电路的两种状态,所以它在计算机中被广泛应用。下面是二进制的加法和乘法运算规则:
加法:0+0=0;1+0=0+1=1;1+1=10
乘法:0*0=0;1*0=0*1=0;1*1=1
二进制数虽然在计算机中处理很方便,但当位数较多时,就不容易**和书写了,所以计算机中又有了十六进制数。
3.十六进制数(Hexadecimal Number)
十六进制也遵循两个规则,一是有十六个基数,即0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F;另一个规则是“逢十六进一,借一当十六”。
比如我们前面提到的#0FFH 就是一个十六进制数,#--我们已经明白了,它表示的是传递数的本身,“H”叫数制简码,它表示这个数是十六进制数,为什么前面我在标题后面都加了英文注释,相信大家也应该明白了吧(这里随便提一下,二进制简码B 和十进制简码D 通常是可以省略的,我们以后的课程中用到的数都是这样写的),那么0FFH 这个十六进制数的表示方法是怎么样的呢?用十进制表示0FFH=F*161+F*160,即等于255 。(大家也许会疑问?这里的“0”到哪里去了呢?原来,在单片机中,当我们用十六进制格式表示一个数时,如果高位的数字为“A-F ”时,高位前面就得加上个“0”,不然,编译软件会出错,就象#0FFH。二.进制之间的转换
十进制有使用比较习惯的特点,二进制有易于表示和运算方便的特点,十六进制又有表示位数较多的特点,但有时我们常常要把十进制数转换成二进制数或十六进制数来处理;把二进制数逆转换成十六进制数,如何进行这种转换呢?下面就举几个例子:
1. 十进制数与非十进制数之间的转换
(1)非十进制数转换为十进制数
具体做法是:将一个非十进制数按权展开成一个多项式,每项是该位数码与相应权值之积,把多项式按十进制的规则进行计算求和,所得的结果就是该数的十进制形式。
比如:二进制数1011B 转换成十进制为1*23+0*22+1*21+1*20=8+2+1=11D ,再比如:十六进制数FFH 转换成十进制为255D。
(2)十进制数转换为非十进制数
十进制数转换为非十进制数时,可将其分为整数部分和小数部分分别进行转换,最后将结果合并为目的数。为了简单,我这里只讲整数部分的转换。这种转换叫做除基取余法,具体做法是用欲转换数制的基数去除十进制数的整数部分,第一次除所得余数为目的数的最低位,把得到的商再除以该基数,所得余数为目的数的次低位,依次类推,继续上面的过程,直至商位为0,此时所得余数为目的数的最高位。
比如:将十进制数53D 转换成二进制数为53D=110101B。
2└53
2└26⋯⋯1
2└13⋯⋯0
2└6⋯⋯1
2└3⋯⋯0
2└1⋯⋯1
0 ⋯⋯1
2. 二进制数与十六进制数之间的转换
四位二进制共有16 种组合,而这16 种组合正好与十六进制数的16 个基数一致,所以每4 位二进制数对应一位十六进制数,我们只要把二进制数的整数部分自右向左每4 位一组,最后不足4 位的用0 补足;小数部分自左向右每4 位一组,最后不足4 位的在右面补0,再将每4 位二进制数对应的十六进制数写出即可。相反,如果将十六进制数转换为二进制数只需将每位十六进制数写成对应的4 位二进制数即可。
比如:将1101011B 转换成十六进制数为D6H,再比如:将F0FH 转换成二进制数为111100001111B 。
上面的表格就是二进制数、十进制数和十六进制数之间的对应关系。
三.立即数的写法
通过前面一小节的讲解,我们已经懂了,MOV R7,#250 和MOV R7,#OFFH 中#250 和#0FFH 原来是十进制数250D 和十六进制数FFH 的区别,在单片机中,通常我们把这个数称之为立即数,那么如果我在编写指令时把立即数#0FFH 写成二进制数(即11111111 )或用十进制写法(255 )是不是可以呢?当然可以,立即数既可以是二进制数,也可以是十进制数或十六进制数。不过有一点再重复一遍:那就是当用十六进制格式表示一个立即数时,如果高位的数字为“A-F”时,高位前面要加上个“0”,请大家务必记住了。
这里再讲一下,关于数制以及二进制、十进制和十六进制数的关系,大家可以在以后的实践中慢慢去理解和掌握,如果您一时记不住,千万不要刻意地去死记硬背!下面让我们来讨论另一个问题:
四.存储器的地址
什么是存储器的地址,地址和数据又有什么关系呢?这个问题往往让初学者非常的难以理解,既然单片机存储器内存放的是数据,为什么还要有地址的概念?让我们从生活中的一个例子谈起:大家都知道寄信是怎么回事吧!我们要寄一封信就必须写好信的内容,然后在信的封面写上详细地址,邮局才能按地址把它寄出去;我们给单片机送数也一样,除了要给出立即数(犹如信的内容),还必须知道这个数送达的地址(犹如信的地址或邮政编码),所以就必须给每个寄存器(即半导体存储器)都规定不同的地址,只不过在单片机中地址的编码也是用数字来表示的,那么单片机中有多少个寄存器呢?它们的地址又是如何规定的呢?
前面我们学过,单片机有两种存储器,即只读存储器ROM 和随机存储器RAM,它们都被规定了各自的地址,我们把它称做寻址空间。既然是空间,就必然有一个范围的概念,接下来就让我们看看MCS-51 单片机中程序存储器ROM 的寻址范围:
1.内部R0M 的寻址范围
89C51 的内部有4K 的FLASH ROM 空间,其寻址范围为000H-0FFH(16*16*16),这4K 的ROM 空间就是用来存放我们为单片机编写的程序的,单片机执行指令时就是一条一条地顺序地从ROM 中寻找指令进行执行。了解了ROM 的寻址范围,让我们接着来看另一种存储器:内部RAM 的寻址范围
单片机的内部RAM 共有256 个字节,寻址范围为00H-FFH(即16*16),它被分为两个部分:第一部分从00H-7FH 共128 个字节是真正的RAM 区,可以用来读写各种数据,在这128 个字节中,又分成三个区域:第一个区域00H-1FH 安排了4 组工作寄存器,每组用8 个字节,共32 个字节,分别为R0-R7,当然在同一时刻,只能用其中的一组工作寄存器,怎么来控制它,就要用程序状态字PWS 中的RS0、RS1 两位,(这我们后面再讲);第二个区域20H-2FH 共16 个字节除了可以作为一般的RAM 单元读写外,还可以对每个字节的每一位(即每一个抽屉中的每一个小盒子)进行操作,并且对这些位都规定了固定的位地址:从20H 单元的第0 位开始到2FH 单元的第7 位结束共128 位;第三个区域就是一般的RAM 单元,地址为30H-7FH,共80 个字节;第二部分从80H-FFH 是专门用于特殊功能寄存器(SFR)的,89C51 共用21 个特殊功能寄存器(这些我们都将在下一课中讲解),它们每个也都有8 位,这部分的128 个字节并没有全部用完。
|
|
|