文档视界 最新最全的文档下载
当前位置:文档视界 › 51单片机汇编程序范例

51单片机汇编程序范例

51单片机汇编程序范例
51单片机汇编程序范例

16位二进制数转换成BCD码的的快速算法-51单片机2010-02-18 00:43在做而论道上篇博文中,回答了一个16位二进制数转换成BCD码的问题,给出了一个网上广泛流传的经典转换程序。

程序可见:https://www.docsj.com/doc/3f9377438.html,/%D7%F6%B6%F8%C2%DB%B5%C0/blog/item/6154551f93ba5614403417 32.html中的HEX2BCD子程序。

.

说它经典,不仅是因为它已经流传已久,重要的是它的编程思路十分清晰,十分易于延伸推广。做而论道曾经利用它的思路,很容易的编写出了48位二进制数变换成16位BCD码的程序。

但是这个程序有个明显的缺点,就是执行时间太长,转换16位二进制数,就必须循环16遍,转换48位二进制数,就必须循环48遍。

上述的HEX2BCD子程序,虽然长度仅仅为26字节,执行时间却要用331个机器周期。

.

单片机系统多半是用于各种类型的控制场合,很多时候都是需要“争分夺秒”的,在低功耗系统设计中,也必须考虑因为运算时间长而增加系统耗电量的问题。

为了提高整机运行的速度,在多年前,做而论道就另外编写了一个转换程序,程序的长度为81字节,执行时间是81个机器周期,(这两个数字怎么这么巧!)执行时间仅仅是经典程序的1/4!

.

近来,在网上发现了一个链接:https://www.docsj.com/doc/3f9377438.html,/news/Article/uc/uc8051/200803/4751.html,也对这个经典转换程序进行了改进,话是说了不少,只是没有实质性的东西。这篇文章提到的程序,一直也没有找到,也难辩真假。

这篇文章好像是选自某个著名杂志,但是在术语的使用上,有着明显的漏洞,不像是专业人员的手笔。比如说文中提到的:“使用51条指令代码,但执行这段程序却要耗费312个指令周期”,就是败笔。51条指令代码,真不知道说的是什么,指令周期是因各种机型和指令而异的,也不能表示确切的时间。

.

下面说说做而论道的编程思路。

;-----------------------------------------------------------------------

;已知16位二进制整数n以b15~b0表示,取值范围为0~65535。

;那么可以写成:

; n = [b15 ~ b0]

;把16位数分解成高8位、低8位来写,也是常见的形式:

; n = [b15~b8] * 256 + [b7~b0]

;那么,写成下列形式,也就可以理解了:

; n = [b15~b12] * 4096 + [b11~b0]

;式中高4位[b15~b12]取值范围为0~15,代表了4096的个数;

;上式可以变形为:

; n = [b15~b12] * 4000 + {[b15~b12] * (100 - 4) + [b11~b0]}

;用x代表[b15~b12],有:

; n = x * 4000 + {x * (100 - 4) + [b11~b0]}

;即:

; n = 4*x (千位) + x (百位) + [b11~b0] - 4*x

;写到这里,就可以看出一点BCD码变换的意思来了。

;

;上式中后面的位:[b11~b0] - 4*x,如果小于256,那就太简单了,马上就可以去按照常规转换BCD了。

;如果数值较大,就要把[b11~b7]看成128的个数y;在百位中加上y、在十位加上3*y、并在[b6~b0]中减去2*y。

;那么就有:

; n = 4*x (千位) + x (百位) + [b11~b0] - 4*x

; n = 4*x (千位) + (x + y) (百位) + 3*y (十位) + [b6~b0] - 2*y

;由此,就可以明确由高9位[b15~b7]变换出来十进制的各个位的数值,可能大于9,到最后整理一下即可。

;剩下的低7位[b6~b0],已经是单字节数据,变换成BCD码那就十分简单了。

;-----------------------------------------------------------------------

从最后的表达式中可以看出,高9位变换的计算方法极为简单,只是使用左移、加减等指令即可,基本上不涉及多字节的运算。

编程的时候,要充分利用单字节、单周期的指令,使程序的长度和执行时间尽量缩短。

做而论道的编程思路已经给出,程序代码还是过一段时间再公布,给大家留下一个发挥的时间。

感兴趣的网友可以留言,写出自己编写的程序。

51单片机把4位16进制数转成10进制数的方法2010-02-10 23:33, 2位16进制转10进制,用除以10求商跟余数的方法,即可。

4位16进制数呢?DIV指令只可以对2位16进制数进行除法运算啊,求高手解答。

例如把TH1 TL1的数值转成十进制, 分别存入R4 R3 R2 R1 R0。

我要的是汇编的方法,C语言还没学到。

悬赏分:30 - 解决时间:2010-2-10 22:47

;------------------------------------------------------------------

最佳答案:两个字节的二进制数转换成BCD码,必须编写程序来解决。

下面把这段转换程序,写成子程序的结构,便于网友移植。

;

程序经过仿真调试通过,如下所示:

;------------------------------------------------------------------

;

MOV R0, TH1

MOV R1, TL1

CALL HEX2BCD ;调用子程序把R0 R1中的数字,转换成压缩的BCD码,送到R2 R3 R4

;-------下面,把万千百十个位,分别存入R4 R3 R2 R1 R0

MOV A, R4 ;先分离R4中的压缩型BCD码,包含的是十位与个位的数MOV B, #16

DIV AB ;除以16,目的是分离出高、低四位

MOV R1, A ;存放十位

MOV R0, B ;存放个位

;

MOV A, R2 ;万位数不超过6,即R2中的压缩型BCD码只有一个,直接放到万位R4中

MOV R4, A ;存放万位

;

MOV A, R3 ;分离R3中的压缩型BCD码,其包含的是千位和百位数

MOV B, #16 ;半字节分离

DIV AB

MOV R3, A

MOV R2, B

SJMP $ ;到此,完成了题目要求

;------------------------------------------------------------------

;两个字节的二进制数转换成BCD码的程序如下:

;功能:16位二进制数变换成为BCD 码;

;入口:R0 R1 中是16 位二进制数,其中R0中是高8 位;

;出口:R2 R3 R4 中是BCD 码,其中R2中是万位,R3中是千、百位,R4中是十、个位。HEX2BCD:

CLR A

MOV R2, A ;先对要放入转换后的压缩型BCD码的寄存器通通清零

MOV R3, A

MOV R4, A

MOV R5, #16 ;共转换十六位数

LOOP:

CLR C

MOV A, R1 ;从待转换数的高端移出一位到Cy(从低8位R1开始转换) RLC A

MOV R1, A

MOV A, R0

RLC A

MOV R0, A

MOV A, R4 ;送到BCD码的低端

ADDC A, R4 ;带进位加。自身相加,相当于左移一位

DA A ;十进制调整,变成BCD码

MOV R4, A

MOV A, R3

ADDC A, R3

DA A

MOV R3, A

MOV A, R2

ADDC A, R2

MOV R2, A

DJNZ R5, LOOP ;共转换十六位数

RET

将A中的二进制数转换为3位的BCD码,其中百位数存放......2010-01-11 09:13请各位懂得帮写下这个程序片段。

将A中的二进制数转换为3位的BCD码。其中百位数存放到31H中,十位和个位数压缩后,存放到30H中。

悬赏分:80 - 解决时间:2009-10-19 09:59

最佳答案:

;------------------------------------------

看来这个题目是属于MCS-51单片机的。

下面用51单片机的汇编语言来求解。

MOV B, #100

DIV AB

MOV 31H, A ;存百位数

MOV A, #10

XCH A, B

DIV AB

SW AP A ;十位数换到高四位

ADD A, B ;加上个位数

MOV 30H, A ;保存

R0中的8位二进制数转换成3位BCD码-单片机编程2010-01-10 23:18单片机的不难编

程题!急!!!!!!

将R0中的8位二进制数转换成3位BCD码,结果存入外部RAM的1002H~1000H(从高位到低位)单元中。

例如:地址:R0 执行后:1002H 1001H 1000H

数据:81H 01 02 09

悬赏分:15 - 解决时间:2009-10-15 19:10

提问者:stefine_ - 一级

最佳答案:

;-------------------------------------------------------

呵呵,楼上的程序,使用了DEC DPTR,要知道,51单片机指令系统里面,是没有DEC DPTR 指令的。

按照下面的思路做,还可以再简练些。

R0中的8位二进制数转换成3位BCD码:

MOV DPTR, #1000H ;个位的地址

MOV A, R0

MOV B, #10

DIV AB

XCH A, B

MOVX @DPTR, A

INC DPTR

MOV A, #10

XCH A, B

DIV AB

XCH A, B

MOVX @DPTR, A

INC DPTR

XCH A, B

MOVX @DPTR, A

RET

仅用了24字节

16位二进制转BCD码--单片机2010-01-03 14:19要求:编写一段程序,把计数器中T0中计的数(TH0和TL0)转成8421BCD码。

并且高8位给p1口,低8位给p0口,要是转成BCD码超过16位,则给p2.0高电平。

我是做单片机课设的,这段程序实在编不明白了,向各位大侠请教了!无比感谢中!

答对有额外加分啊!!!!

悬赏分:200 - 解决时间:2010-1-3 13:03

最佳答案:16bit 表示:65536,万位不超6

――――――――――――――――――――――――――

程序如下:

MOV R0, TL0 ;

MOV R1, TH0 ;待转换的16bit数分别放入(由高到低)R1R0中

;

CLR A

MOV R2, A ;先清零

MOV R3, A

MOV R4, A

MOV R5, #16 ;共转换16位数

LOOP:

CLR C ;c=0

MOV A, R0 ;从待转换低8bit数的高端移出一位到Cy(转换最先由低8位开始)

RLC A ;R0中的最高位移入到A中

MOV R0, A

MOV A, R1 ;(高8位二进制数)

RLC A ;此时C中的由低8位所移入的数重新移入高8位的低端

MOV R1, A ;相当于16bit的高端移出了1bit到C中了

MOV A, R4 ;送到BCD码的低端

ADDC A, R4 ;带进位加。自身相加,相当于左移一位

DA A ;十进制调整,变成BCD码

MOV R4, A

MOV A, R3

ADDC A, R3

DA A

MOV R3, A

MOV A, R2

ADDC A, R2

MOV R2, A

DJNZ R5, LOOP ;循环16遍, 转换即完成

;

MOV P0, R4 ;按照要求输出

MOV P1, R3

CLR P2.0

MOV A, R2

JZ P20_L

SETB P2.0

P20_L:

RET

如果随意对一个累加器A中的二进制数据进行“二进制转十进制”调整是没有任何实际意义的!

DA调整的对象是在ADD或ADDC之后的结果,而且是以BCD码相加以后才能够调整,否则没有实际意义!

比如,现在要执行12D+39D也就是两个十进制数相加这样一个加法(有时候程序处理的需要,数据在单片机中是以BCD码的形式存储的,也就是12H和39H(十六进制),但我们可以人为将它们看为12D和39D(十进制),而且还希望相加以后的结果为51H,也就是说符合十进制运算规则12+39=51,而不是4BH的结果),但这样的十进制加法运算在单片机中是不能够直接实现的。因为单片机只能够执行二进制加法指令,也就是所有的运算都按照

二进制中的规则进行!

于是就出现了DA调整指令!

现在12H+39H,将12H放于A中,执行ADD A,#39H指令,则结果为4BH,这不是我们希望的51H的数据形式!!这时执行DA A 指令后,就会将A中的数据调整为51H(具体调整过程和原理你可以详细看书,如果单片机书中讲的不详细,那么微机原理中一定说的非常详细),而我们按照BCD码规则就将其看为51D,符合我们的要求!

也就是说加数和被加数都是BCD码的形式,最大也只可能是99H,也就是我们十进制数中的99,只有这样才会有实际的意义!所以你说的当A=#24H的时候的情况是不会存在的,严格的说是没有意义的!

而且DA A指令只用于十进制BCD码加法指令ADD/ADDC 以后,否则是没有实际意义的!

定义:用4位二进制数来表示1位十进制数中的0~9这10个数码,简称BCD码

即BCD代码。Binary-Coded Decimal?,简称BCD,称BCD码或二-十进制代码,亦称二进码十进数。是一种二进制的数字编码形式,用二进制编码的十进制代码。这种编码形式利用了四个位元来储存一个十进制的数码,使二进制和十进制之间的转换得以快捷的进行。这种编码技巧,最常用于会计系统的设计里,因为会计制度经常需要对很长的数字串作准确的计算。相对于一般的浮点式记数法,采用BCD码,既可保存数值的精确度,又可免却使电脑作浮点运算时所耗费的时间。此外,对于其他需要高精确度的计算,BCD编码亦很常用。

由于十进制数共有0、1、2、……、9十个数码,因此,至少需要4位二进制码来表示1位十进制数。4位二进制码共有2^4=16种码组,在这16种代码中,可以任选10种来表示10个十进制数码,共有N=16!/(16-10)!约等于2.9乘以10的10次方种方案。常用的BCD代码列于末。

常用BCD编码方式

最常用的BCD编码,就是使用"0"至"9"这十个数值的二进码来表示。这种编码方式,在中国大陆称之为“8421码”。除此以外,对应不同需求,各人亦开发了不同的编码方法,以适应不同的需求。这些编码,大致可以分成有权码和无权码两种:

有权BCD码,如:8421(最常用)、2421、5421…

无权BCD码,如:余3码、格雷码…

以下为三种常见的BCD编码的比较。

十进数8421-BCD码余3-BCD码2421-A码

(M10) D C B A C3 C2 C1 C0 a3 a2 a1 a0

0 0 0 0 0 0 0 1 1 0 0 0 0

1 0 0 0 1 0 1 0 0 0 0 0 1

2 0 0 1 0 0 1 0 1 0 0 1 0

3 0 0 1 1 0 1 1 0 0 0 1 1

4 0 1 0 0 0 1 1 1 0 1 0 0

5 0 1 0 1 1 0 0 0 0 1 0 1

6 0 1 1 0 1 0 0 1 0 1 1 0

7 0 1 1 1 1 0 1 0 0 1 1 1

8 1 0 0 0 1 0 1 1 1 1 1 0

9 1 0 0 1 1 1 0 0 1 1 1 1

常用BCD码

十进制数8421码5421码2421码余3码余3循环码

0 0000 0000 0000 0011 0010

1 0001 0001 0001 0100 0110

2 0010 0010 0010 0101 0111

3 0011 0011 0011 0110 0101

4 0100 0100 0100 0111 0100

5 0101 1000 1011 1000 1100

6 0110 1001 1100 1001 1101

7 0111 1010 1101 1010 1111

8 1000 1011 1110 1011 1110

9 1001 1100 1111 1100 1010

-----------------------

特点:

8421编码直观,好理解。

5421码和2421码中大于5的数字都是高位为1,5以下的高位为0。

余3码是8421码加上3,有上溢出和下溢出的空间。

格雷码相邻2个数有三位相同,只有一位不同。————————————————————

什么是BCD码2006-3-19 13:24:45

bcd码也叫8421码就是将十进制的数以8421的形式展开成二进制,大家知道十进制是0~9十个数组成,着十个数每个数都有自己的8421码:

0=0000

1=0001

2=0010

3=0011

4=0100

5=0101

6=0110

7=0111

8=1000

9=1001

举个例子:

321的8421码就是

3 2 1

0011 0010 0001

原因:0011=8x0+4x0+1x2+1x1=3 0010=8x0+4x0+2x1+1x0=2. 0001=8x0+4x0+2x0+1x1=1

具体:

bcd码是四位二进制码, 也就是将十进制的数字转化为二进制, 但是和普通的转化有一点不同, 每一个十进制的数字0-9都对应着一个四位的二进制码,对应关系如下: 十进制0 对应

二进制0000 ;十进制1 对应二进制0001 ....... 9 1001 接下来的10就有两个上述的码来表示10 表示为00010000 也就是BCD码是遇见1001就产生进位,不象普通的二进制码,到1111才产生进位10000

举例:

某二进制无符号数11101010,转换为三位非压缩BCD数,按百位、十位和个位的顺序表示,应为__C__。

A.00000001 00000011 00000111

B. 00000011 00000001 00000111

C.00000010 00000011 00000100

D. 00000011 00000001 00001001

解:(1)11101010转换为十进制:234

(2)按百位、十位和个位的顺序表示,应为__C__。

附注:压缩BCD码与非压缩BCD码的区别——压缩BCD码的每一位用4位二进制表示,一个字节表示两位十进制数。例如10010110B表示十进制数96D;非压缩BCD码用1个字节表示一位十进制数,高四位总是0000,低4位的0000~1001表示0~9.例如00001000B 表示十进制数

关于MCS-51单片机是如何将单字节二进制数转化为BCD码的问题

悬赏分:20 - 解决时间:2010-5-5 15:15

程序如下:BINBCD:MOV B, #100 (100作为除数送入B中)

DIV AB (十六进制数除以100)

MOV R3, A (百位数送r3,余数放入B中)

MOV A, #10 (分离十位数与个位数)

XCH A,B (余数放入A中,除数放入B中)

DIV AB (分离出十位在A中,个位在B中)

SWAP A (十位数交换到A的高4位)

ADD A,B (十位数与个位数相加送入A中)

END

1 请问这个程序求解的思路是什么?

2 该程序的第二句"DIV AB"的解释是十六进制数除以100,可是A中应该存放的是一个八位的二进制数,这是怎么回事?

3 最后为什么要十位数与个位数相加,不是要分离十位数与个位数吗?

乘除法的时候可以不考虑进制的,比如说#0FFH这个十六进制数存放于A中,#100这个十进制数放于B中然后DIV AB 这时A等于#02H B等于#37H等于55

在然后

假设A中的数为FFH

BINBCD:

MOV B, #100 (B=100,十进制100,)

DIV AB (A等于#02H,B等于#37H等于55)

MOV R3, A (A=02H)

MOV A, #10 (A=10=0AH,B=55=37H)

XCH A,B (A=55=37H, B=10=0AH)

DIV AB (A=05H=5 , B=5=05H)

SWAP A (A=50H,B=05H)

ADD A,B (A=55H,这时十位各位的BCD吗已经求出来了,将

37H=55转换为55H

END

1 请问这个程序求解的思路是什么?

思路就是对一个数求模和求于来分离百位十位和个位

例如168

168/100=1余68

68/10=6余8

8/1=8余0

这样就分离了百位十位和个位

2 该程序的第二句"DIV AB"的解释是十六进制数除以100,可是A中应该存放的是一个八位的二进制数,这是怎么回事?

这个是你没理解cpu存数据的方式,A中存放的其实归根结底说是二进制数,机器只认识二进制数,对这段程序编译之后我们输入的十进制100也变成二进制数了,我们通常说十六进制数是因为十六进制数和二进制数有位上的对应关系,比如1100 0110B=C6H 也就是说二进制数每4位一段各自写成十六进制数就把二进制转换成十六进制了,

3 最后为什么要十位数与个位数相加,不是要分离十位数与个位数吗?

我想如果你清楚BCD码的含义你就明白了

BCD码就是用十六进制数来表示十进制的数

例如:45H是等于十进制的69的,但如果你说他是BCD码他就代表十进制数45

这样你就会发现不是每个十六进制数都是BCD码的,例如AAH就不是BCD码,因为没有AA这样的十进制数

我最后总结一下,就是我们所说的十进制数也好十六进制数也好,归根到底机器都是要把他变为二进制数的,机器也只认识二进制数,这样你就好理解了,我们不会处理不同进制数之间的运算,运算时必须要把他转换同进制的数,机器也是这样,只不过我们擅长的是十进制的运算,而机器擅长的是二进制运算,二进制数位数多不方便我们就找了一个帮手十六进制数

希望你能看得懂

51单片机实例程100讲全集

目录 目录 (1) 函数的使用和熟悉 (4) 实例3:用单片机控制第一个灯亮 (4) 实例4:用单片机控制一个灯闪烁:认识单片机的工作频率 (4) 实例5:将P1口状态分别送入P0、P2、P3口:认识I/O口的引脚功能 (5) 实例6:使用P3口流水点亮8位LED (5) 实例7:通过对P3口地址的操作流水点亮8位LED (6) 实例8:用不同数据类型控制灯闪烁时间 (7) 实例9:用P0口、P1 口分别显示加法和减法运算结果 (8) 实例10:用P0、P1口显示乘法运算结果 (9) 实例11:用P1、P0口显示除法运算结果 (9) 实例12:用自增运算控制P0口8位LED流水花样 (10) 实例13:用P0口显示逻辑"与"运算结果 (10) 实例14:用P0口显示条件运算结果 (11) 实例15:用P0口显示按位"异或"运算结果 (11) 实例16:用P0显示左移运算结果 (11) 实例17:"万能逻辑电路"实验 (11) 实例18:用右移运算流水点亮P1口8位LED (12) 实例19:用if语句控制P0口8位LED的流水方向 (13) 实例20:用swtich语句的控制P0口8位LED的点亮状态 (13) 实例21:用for语句控制蜂鸣器鸣笛次数 (14) 实例22:用while语句控制LED (15) 实例23:用do-while语句控制P0口8位LED流水点亮 (16) 实例24:用字符型数组控制P0口8位LED流水点亮 (17) 实例25:用P0口显示字符串常量 (18) 实例26:用P0 口显示指针运算结果 (19) 实例27:用指针数组控制P0口8位LED流水点亮 (19) 实例28:用数组的指针控制P0 口8 位LED流水点亮 (20) 实例29:用P0 、P1口显示整型函数返回值 (21) 实例30:用有参函数控制P0口8位LED流水速度 (22) 实例31:用数组作函数参数控制流水花样 (22) 实例32:用指针作函数参数控制P0口8位LED流水点亮 (23) 实例33:用函数型指针控制P1口灯花样 (25) 实例34:用指针数组作为函数的参数显示多个字符串 (26) 实例35:字符函数ctype.h应用举例 (27) 实例36:内部函数intrins.h应用举例 (27) 实例37:标准函数stdlib.h应用举例 (28) 实例38:字符串函数string.h应用举例 (29) 实例39:宏定义应用举例2 (29) 实例40:宏定义应用举例2 (29) 实例41:宏定义应用举例3 (30)

最全最好的课程设计-51单片机电子日历时钟( 含源程序)

LED日历时钟课程设计 院系: 班级: 姓名: 学号: 指导教师: 2012 年06 月16 日

目录

摘要 单片机自20世纪70年代问世以来,以其极高的性能价格比,受到人们的重视和关注,应用很广、发展很快。单片机体积小、重量轻、抗干扰能力强、环境要求不高、价格低廉、可靠性高、灵活性好、开发较为容易。由于具有上述优点,在我国,单片机已广泛地应用在工业自动化控制、自动检测、智能仪器仪表、家用电器、电力电子、机电一体化设备等各个方面,而51单片机是各单片机中最为典型和最有代表性的一种。这次毕业设计通过对它的学习、应用,以AT89S51芯片为核心,辅以必要的电路,设计了一个简易的电子时钟,它由4.5V直流电源供电,通过数码管能够准确显示时间,调整时间,从而到达学习、设计、开发软、硬件的能力。 第一章前言 数字电子钟具有走时准确,一钟多用等特点,在生活中已经得到广泛的应用。虽然现在市场上已有现成的电子钟集成电路芯片,价格便宜、使用也方便,但是人们对电子产品的应用要求越来越高,数字钟不但可以显示当前的时间,而且可以显示期、农历、以及星期等,给人们的生活带来了方便。另外数字钟还具备秒表和闹钟的功能,且闹钟铃声可自选,使一款电子钟具备了多媒体的色彩。单片机具有体积小、功能强可靠性高、价格低廉等一系列优点,不仅已成为工业测控领域普遍采用的智能化控制工具,而且已渗入到人们工作和和生活的各个角落,有力地推动了各行业的技术改造和产品的更新换代,应用前景广阔。 时钟电路在计算机系统中起着非常重要的作用,是保证系统正常工作的基础。在一个单片机应用系统中,时钟有两方面的含义:一是指为保障系统正常工作的基准振荡定时信号,主要由晶振和外围电路组成,晶振频率的大小决定了单片机系统工作的快慢;二是指系统的标准定时时钟,即定时时间,它通常有两种实现方法:一是用软件实现,即用单片机内部的可编程定时/计数器来实现,但误差很大,主要用在对时间精度要求不高的场合;二是用专门的时钟芯片实现,在对时间精度要求很高的情况下,通常采用这种方法,典型的时钟芯片有:DS1302,DS12887,X1203等都可以满足高精度的要求。 AT89S51是一个低功耗,高性能CMOS 8位单片机,片内含4k B ytes ISP(In-system programmable)的可反复擦写1000次的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统及80C51引脚结构,芯片内集成了通用8位中央处理器和ISP Flash存储单元,功能强大的微型计算机的AT89S51可为许多嵌入式控制应用系统提供高性价比的解决方案。 AT89S51具有如下特点:40个引脚,4k Bytes Flash片内程序存储器,128 bytes的随机存取数据存储器(RAM),32个外部双向输入/输出(I/O)口,5个中断优先级2层中断嵌套中断,2个16位可编程定时计数器,2个全双工串行通信口,看门狗(WDT)电路,片内时钟振荡器。

单片机编程全集(含源代码)

前言 (2) 基础知识:单片机编程基础 (2) 第一节:单数码管按键显示 (4) 第二节:双数码管可调秒表 (6) 第三节:十字路口交通灯 (7) 第四节:数码管驱动 (9) 第五节:键盘驱动 (10) 第六节:低频频率计 (15) 第七节:电子表 (18) 第八节:串行口应用 (19)

前言 本文是本人上课的一个补充,完全自写,难免有错,请读者给予指正,可发邮件到ZYZ@https://www.docsj.com/doc/3f9377438.html,,或郑郁正@中国;以便相互学习。结合课堂的内容,课堂上的部分口述内容,没有写下来;有些具体内容与课堂不相同,但方法是相通的。https://www.docsj.com/doc/3f9377438.html, 针对当前的学生情况,尽可能考虑到学生水平的两端,希望通过本文都学会单片机应用。如果有不懂的内容,不管是不是本课的内容,都可以提出来,这些知识往往代表一大部分同学的情况,但本人通常认为大家对这些知识已精通,而在本文中没有给予描述,由此影响大家的学习。对于这些提出问题的读者,本人在此深表谢意。 想深入详细学习单片机的同学,可以参考其它有关单片机的书籍和资料,尤其是外文资料。如果有什么问题,我们可以相互探讨和研究,共同学习。 本文根据教学的情况,随时进行修改和完善,所以欢迎同学随时注意本文档在课件中的更新情况。 基础知识:单片机编程基础 单片机的外部结构: 1、DIP40双列直插; 2、P0,P1,P2,P3四个8位准双向I/O引脚;(作为I/O输入时,要先输出高电平) 3、电源VCC(PIN40)和地线GND(PIN20); 4、高电平复位RESET(PIN9);(10uF电容接VCC与RESET,即可实现上电复位) 5、内置振荡电路,外部只要接晶体至X1(PIN18)和X0(PIN19);(频率为主频的12倍) 6、程序配置EA(PIN31)接高电平VCC;(运行单片机内部ROM中的程序) 7、P3支持第二功能:RXD、TXD、INT0、INT1、T0、T1 单片机内部I/O部件:(所为学习单片机,实际上就是编程控制以下I/O部件,完成指定任务) 1、四个8位通用I/O端口,对应引脚P0、P1、P2和P3; 2、两个16位定时计数器;(TMOD,TCON,TL0,TH0,TL1,TH1) 3、一个串行通信接口;(SCON,SBUF) 4、一个中断控制器;(IE,IP) https://www.docsj.com/doc/3f9377438.html, 针对AT89C52单片机,头文件AT89x52.h给出了SFR特殊功能寄存器所有端口的定义。教科书的160页给出了针对MCS51系列单片机的C语言扩展变量类型。 C语言编程基础: 1、十六进制表示字节0x5a:二进制为01011010B;0x6E为01101110。 2、如果将一个16位二进数赋给一个8位的字节变量,则自动截断为低8位,而丢掉高8位。 3、++var表示对变量var先增一;var—表示对变量后减一。 4、x |= 0x0f;表示为 x = x | 0x0f; 5、TMOD = ( TMOD & 0xf0 ) | 0x05;表示给变量TMOD的低四位赋值0x5,而不改变TMOD的高四位。 6、While( 1 ); 表示无限执行该语句,即死循环。语句后的分号表示空循环体,也就是{;} 在某引脚输出高电平的编程方法:(比如P1.3(PIN4)引脚)

基于51单片机FAT32文件系统程序

基于51单片机FAT32文件系统程序 #ifndef __ZNFAT_H__ #define __ZNFAT_H__ #include "mytype.h" //类型重定义 /*******************************************************/ //znFAT的裁减宏--------------------------------------------------------- //#define ZNFAT_ENTER_DIR //有此宏,函数 znFAT_Enter_Dir() 参与编译 #define ZNFAT_OPEN_FILE //有此宏,函数 znFAT_Open_File() 参与编译 //#define ZNFAT_SEEK_FILE //有此宏,函数 znFAT_Seek_File() 参与编译 //#define ZNFAT_READ_FILE //有此宏,函数 znFAT_Read_File() 参与编译 //#define ZNFAT_READ_FILEX //有此宏,函数 znFAT_Read_FileX() 参与编译 //#define ZNFAT_ADD_DAT //有此宏,函数 znFAT_Add_Dat() 参与编译 //#define ZNFAT_CREATE_DIR //有此宏,函数 znFAT_Create_Dir() 参与编译 //#define ZNFAT_CREATE_FILE //有此宏,函数 znFAT_Create_File() 参与编译 //#define ZNFAT_DEL_FILE //有此宏,函数 znFAT_Del_File() 参与编译 //#define ZNFAT_XCOPY_FILE //有此宏,函数 znFAT_XCopy_File() 参与编译 //#define ZNFAT_RENAME_FILE //有此宏,函数 znFAT_Rename_File() 参与编译 //#define ZNFAT_GET_TOTAL_SIZE //有此宏,函数 znFAT_Get_Total_Size() 参与编译 //#define znFAT_GET_REMAIN_CAP //有此宏,函数 znFAT_Get_Remain_Cap() 参与编译 #include "cj.h" #include "cj.h" //---------------------------------------------------------------------- #define SOC(c) (((c-pArg->FirstDirClust)*(pArg->SectorsPerClust))+pArg->FirstDirSector) // 用于计算簇的开始扇区#define CONST const //设备表 #define SDCARD 0 //SD卡 #define UDISK 1 //U盘 #define CFCARD 2 //CF卡 #define OTHER 3 //其它 //这里的存储设备表,可以灵活扩充,以实现对更多存储设备的支持 //------------------------------------------- #define MAKE_FILE_TIME(h,m,s) ((((unsigned int)h)<<11)+(((unsigned int)m)<<5)+(((unsigned int)s)>>1)) /* 生成指定时分秒的文件时间数据 */ #define MAKE_FILE_DATE(y,m,d) (((((unsigned int)y)+20)<<9)+(((unsigned int)m)<<5)+((unsigned int)d)) /* 生成指定年月日的文件日期数据 */ //DPT:分区记录结构如下 struct PartRecord { UINT8 Active; //0x80表示此分区有效 UINT8 StartHead; //分区的开始磁头 UINT8 StartCylSect[2];//开始柱面与扇区 UINT8 PartType; //分区类型 UINT8 EndHead; //分区的结束头 UINT8 EndCylSect[2]; //结束柱面与扇区 UINT8 StartLBA[4]; //分区的第一个扇区 UINT8 Size[4]; //分区的大小

(完整版)51单片机汇编指令(全)

指令中常用符号说明 Rn当前寄存器区的8个工作寄存器R0~R7(n=0~7) Ri当前寄存器区可作为地址寄存器的2个工作寄存器R0和R1(i=0,1) Direct8位内部数据寄存器单元的地址及特殊功能寄存器的地址 #data表示8位常数(立即数) #data16表示16位常数 Add16表示16位地址 Addr11表示11位地址 Rel8位代符号的地址偏移量 Bit表示位地址 @间接寻址寄存器或基址寄存器的前缀 ( )表示括号中单元的内容 (( ))表示间接寻址的内容 指令系统 数据传送指令(8个助记符) 助记符中英文注释 MOV Move 移动 MOV A , Rn;Rn→A,寄存器Rn的内容送到累加器A MOV A , Direct;(direct)→A,直接地址的内容送A MOV A ,@ Ri;(Ri)→A,RI间址的内容送A MOV A , #data;data→A,立即数送A MOV Rn , A;A→Rn,累加器A的内容送寄存器Rn MOV Rn ,direct;(direct)→Rn,直接地址中的内容送Rn MOV Rn , #data;data→Rn,立即数送Rn MOV direct , A;A→(direct),累加器A中的内容送直接地址中 MOV direct , Rn;(Rn)→direct,寄存器的内容送到直接地址 MOV direct , direct;(direct)→direct,直接地址的内容送到直接地址 MOV direct , @Ri;((Ri))→direct,间址的内容送到直接地址 MOV direct , #data;8位立即数送到直接地址中 MOV @Ri , A;(A)→@Ri,累加器的内容送到间址中 MOV @Ri , direct;direct→@Ri,直接地址中的内容送到间址中 MOV @Ri , #data; data→@Ri ,8位立即数送到间址中 MOV DPTR , #data16;data16→DPTR,16位常数送入数据指针寄存器,高8位送入DPH,低8位送入DPL中(单片机中唯一一条16位数据传送指令) (MOV类指令共16条)

单片机C语言模块化编程初步资料全

下面让我们揭开模块化神秘面纱,一窥其真面目。 C语言源文件*.c 提到C语言源文件,大家都不会陌生。因为我们平常写的程序代码几乎都在这个XX.C文件里面。编译器也是以此文件来进行编译并生成相应的目标文件。作为模块化编程的组成基础,我们所要实现的所有功能的源代码均在这个文件里。理想的模块化应该可以看成是一个黑盒子。即我们只关心模块提供的功能,而不管模块内部的实现细节。好比我们买了一部手机,我们只需要会用手机提供的功能即可,不需要知晓它是如何把短信发出去的,如何响应我们按键的输入,这些过程对我们用户而言,就是是一个黑盒子。 在大规模程序开发中,一个程序由很多个模块组成,很可能,这些模块的编写任务被分配到不同的人。而你在编写这个模块的时候很可能就需要利用到别人写好的模块的借口,这个时候我们关心的是,它的模块实现了什么样的接口,我该如何去调用,至于模块内部是如何组织的,对于我而言,无需过多关注。而追求接口的单一性,把不需要的细节尽可能对外部屏蔽起来,正是我们所需要注意的地方。 C语言头文件*.h 谈及到模块化编程,必然会涉及到多文件编译,也就是工程编译。在这样的一个系统中,往往会有多个C文件,而且每个C文件的作用不尽相同。在我们的C文件中,由于需要对外提供接口,因此必须有一些函数或者是变量提供给外部其它文件进行调用。 假设我们有一个LCD.C文件,其提供最基本的LCD的驱动函数 LcdPutChar(char cNewValue) ; //在当前位置输出一个字符 而在我们的另外一个文件中需要调用此函数,那么我们该如何做呢? 头文件的作用正是在此。可以称其为一份接口描述文件。其文件内部不应该包含任何实质性的函数代码。我们可以把这个头文件理解成为一份说明书,说明的内容就是我们的模块对外提供的接口函数或者是接口变量。同时该文件也包含了一些很重要的宏定义以及一些结构体的信息,离开了这些信息,很可能就无法正常使用接口函数或者是接口变量。但是总的原则是:不该让外界知道的信息就不应该出现在头文件里,而外界调用模块内接口函数或者是接口变量所必须的信息就一定要出现在头文件里,否则,外界就无法正确的调用我们提供的接口功能。因而为了让外部函数或者文件调用我们提供的接口功能,就必须包含我们提供的这个接口描述文件----即头文件。同时,我们自身模块也需要包含这份模块头文件(因为其包含了模块源文件中所需要的宏定义或者是结构体),好比我们平常所用的文件都是一式三份一样,模块本身也需要包含这个头文件。 下面我们来定义这个头文件,一般来说,头文件的名字应该与源文件的名字保持一致,这样我们便可以清晰的知道哪个头文件是哪个源文件的描述。

步进电机控制程序(c语言+51单片机)

步进电机控制程序(c语言+51单片机) 发布:2011-05-31 | 作者: | 来源: guozhangfu | 查看:720次 | 用户关注: 摘要:实现了一种全集成可变带宽中频宽带低通滤波器,讨论分析了跨导放大器-电容(OTA—C)连续时间型滤波器的结构、设计和具体实现,使用外部可编程电路对所设计滤波器带宽进行控制,并利用ADS软件进行电路设计和仿真验证。仿真结果表明,该滤波器带宽的可调范围为1~26 MHz,阻带抑制率大于35 dB,带内波纹小于0.5 dB,采用1.8 V电源,TSMC 0.18μm CMOS工艺库仿真,功耗小于21 mW,频响曲线接近理想状态。关键词:Butte #include #define uint unsigned int #define uchar unsigned char #define ms *77 // f = 12 M #define LEDLen 4 #define Dj_star() {IE=0x81; pri_dj=0; } #define Dj_stop() {IE=0x00; pri_dj=1; P1=0xff; shache="0"; delay(800ms); delay(800ms);delay(400ms); shache = 1; } #define Chilun_Num 8 /* 齿轮数 8 个*/ #define set_display_num() { LEDBuf[0] = tmp / 1000; LEDBuf[1] = tmp / 100 % 10; LEDBuf[2] = tmp / 10 % 10; LEDBuf[3] = tmp % 10; } uchar LEDBuf[LEDLen] = {0,0,0,0}; void read_num (); /* 读播码盘到 set_round_num * 8 */ void display (); void delay(uint delay_time) { uint i; for (i=0; i < delay_time ; i++) ; } void run (); void fx_run(); uint round_num = 0; /* 记录已转的齿轮数 , 中断1次加1*/ uint set_round_num = 0; /* 播码盘设置圈数 */ uint set_pwm_width = 0; /* 播码盘设置步进电机正向速度 */ bit one_round_flg = 0; sbit led_1000 = P0^7; //use for display sbit led_100 = P0^6; //use for display sbit led_10 = P0^5; //use for display sbit led_1 = P0^4; //use for display

51单片机汇编语言教程:28课音乐程序设计

51单片机汇编语言教程:第28课-音乐程序设计 (基于HL-1、HJ-C52、HJ-3G实验板) (图片HL-1开发板) 利用单片机(或单板机)奏乐大概是无线电爱好者感兴趣的问题之一。本文从单片机的基本发间实验出发,谈谈音乐程序的设计原理,并给出具体实例,以供参考。 单片机的基本发音实验 我们知道,声音的频谱范围约在几十到几千赫兹,若能利用程序来控制单处机某个口线的“高”电平或低电平,则在该口线上就能产生一定频率的矩形波,接上喇叭就能发出一定频率的声音,若再利用延时程序控制“高”“低”电平的持续时间,就能改变输出频率,从而改变音调。 例如,要产生200HZ的音频信号,按图1接入喇叭(若属临时实验,也可将喇叭直接接在P1口线上),实验程序为: 其中子程序DEL为延时子程序,当R3为1时,延时时间约为20us,R3中存放延时常数,对200HZ 音频,其周期为1/200秒,即5ms。这样,当P1.4的高电平或低电平的持续时间为2.5ms,即R3的时间常数取2500/20=125(7DH)时,就能发出200HZ的音调。将上述程序键入学习机,并

持续修改R3的常数能感到音调的变化。乐曲中,每一音符对应着确定的频率,表1给出C调时各音符频率及其对应的时间常数。读者能根据表1所供给的常数,将其16进制代码送入R3,反复练习体会。根据表1能奏出音符。仅这还不够,要准确奏出一首曲子,必须准确地控制乐曲节奏,即一音符的持续时间。 音符的节拍我们能用定时器T0来控制,送入不一样的初值,就能产生不一样的定时时间。便如某歌曲的节奏为每分钟94拍,即一拍为0.64秒。其它节拍与时间的对应关系见表2。但时,由于T0的最大定时时间只能为131毫秒,因此不可能直接用改变T0的时间初值来实现不一样节拍。我们能用T0来产生10毫秒的时间基准,然后设置一个中断计数器,通过判别中断计数器的值来控制节拍时间的长短。表2中也给出了各种节拍所对应的时间常数。例如对1/4拍音符,定时时间为0.16秒,对应的时间常数为16(即10H);对3拍音符,定时时间为1.92秒,对应时间长数为192(即C0H)。 我们将每一音符的时间常数和其对应的节拍常数作为一组,按次序将乐曲中的所有常数排列成一个表,然后由查表程序依次取出,产生音符并控制节奏,就能实现演奏效果。此外,结束符和体止符能分别用代码00H和FFH来表示,若查表结果为00H,则表示曲子终了;若查表结果为FFH,则产生对应的停顿效果。为了产生手弹的节奏感,在某些音符(例如两个相同音符)音插入一个时间单位的频率略有不一样的音符。 下面给出程序序清单,可直接在TD-III型学习机上演奏,对其它不一样型号的学习机,只需对应地改变一下地址即可。本程序演奏的是民歌“八月桂花遍地开”,C调,节奏为94拍/分。读者也能自行找出一首歌,按表1和表2给定的常数,将乐曲翻译成码表输入机器,而程序不变。本实验办法简便,即使不懂音乐的人,将一首陌生的曲子翻译成代码也是易事,和着机器的演奏学唱一首歌曲,其趣味无穷。 程序清单(略,请参看源程序的说明)。 程序框图如图2所示。

51单片机电子琴程序

#include #include #include #include #define uchar unsigned char #define uint unsigned int uchar STH0; //定时器计数初值 uchar STL0; bit FY=0; //放乐曲时FY=1,电子琴弹奏时FY=0 uchar Song_Index=0,Tone_Index=0; //放音乐的参数 uchar k,key; sbit SPK=P3^7; sbit LED1=P1^0; sbit LED2=P1^1; uchar code DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6f,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79 ,0x71}; uchar code Song[][50]={{1,2,3,5,7,8,4,3,4,3,4,5,4,6,3,4,5}, {5,5,3,5,4,2,4,5,7,4,2,10,10,10,2,1,2,1,2,10,10}, {5,5,10,9,8,5,5,5,5,10,9,8,6,6,6,11,12,9,6,8-1}, {13,14,13,12,12,10,12,13,14,15,14,14}, {6,6,11,10,9,12,12,12,12,13,12,11,9,8,10,10,10,-1}, {9,13,13,13,13,8,13,13,13,13,14,15,14,13,13,14,12,13}, }; uchar code Len[][50]={{1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,1,1,1,2,2,2,1,2,2,1,2,2}, {1,1,1,1,1,1,2,1,1,1,2,2,1,1,1,1,-1}, {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1}, {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1}, {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1}, {1,1,2,0,1,1,2,0,1,1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,2,0,1,2,1,2,1,2,1,2,1,2}, {2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1},}; //音符与计数值对应表 uint code tab[]={0,63628,63835,64021,64103,64260,64400, 64524,64580,64684,64777, 64820,64898,64968,65030, 65058,65110,65157,65178,65217,65252,65283}; void delay1(uint ms) //播放歌曲时实现节拍的延时函数 { uchar t; while(ms--) for(t=0;t<120;t++); }

单片机原理习题集(全)

习题集——MCS-51单片机原理 吴锤红制

第一章引导 1、列举出单片微机在工业、民用及军事上的应用例子。 2、单片机与系统型微机在应用上有什么主要差别? 3、如果让你用单片机开发一项产品,你准备开发什么产品?该产品的功能及应用前景 如何?单片机在该产品中的作用是什么? 4、用从课文介绍的应用实例中所学习的知识回答以下问题: a.高级语言与机器语言的主要不同点? b.MCS-51开机或复位后机器语言程序从哪里开始执行? c.人用什么语言编机器语言程序? d.机器语言指令中的A、B、C等表示的是符号还是数字? e.单片机中处理的是数字量还是模拟量?它们与高电平、低电平或+5伏与0伏的关 系是怎样的? 5、分别举出5个硬件和软件的例子。 6、I/O对应的英文单词是哪些?表示什么意思? 7、“汇编语言源程序”、“汇编程序”、“机器目标代码程序”等术语各是什么意思? 8、选择题: ①高级语言,如Basic、Pascal等,这所以能在IBM-PC微机上或Apple机上执行,是 因为__________。 a.这些机器的CPU能识别这些高级语言并能执行它们。 b.高级语言与计算机的CPU无关,可以在任何计算机上执行。 c.这些计算机上配备了能将高级语言转化为(编译器与解释器)机器语言的软件。 d.CPU能将高级语言转化为机器语言并执行它。 ②ROM,用形象比喻来说明它的特性,更像__________。 a.黑板,写上的字与原来的字会叠加在一起。 b.相片,暴光一次成像,可看读任意多次。 c.装物的盒子,能存储信息。 d.生物的大脑,能大量存储信息。 ③RAM,用形象比喻来说明它的特性,更像__________。 a.算盘,由算盘珠摆出了一种状态。 b.装物盒子,可存入也可取出。 c.黑板,可写可擦。 d.生物大脑,可记又会忘。 ④存储单元的地址的作用是__________。 a.用于形成序列联系。 b.用于访问这些单元。 c.用于硬件接线。 d.用于降低成本。 ⑤寄存器__________。

AT89C51引脚全部和功能

AT89C51单片机简介 AT89C51是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—Falsh Programmable and Erasable Read Only Memory)的低电压,高性能CMOS8位微处理器,俗称单片机。AT89C2051是一种带2K字节闪烁可编程可擦除只读存储器的单片机。单片机的可擦除只读存储器可以反复擦除100次。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL 的AT89C51是一种高效微控制器,AT89C2051是它的一种精简版本。AT89C单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。

1.主要特性: ·与MCS-51 兼容 ·4K字节可编程闪烁存储器 寿命:1000写/擦循环 数据保留时间:10年 ·全静态工作:0Hz-24Hz ·三级程序存储器锁定 ·128*8位内部RAM ·32可编程I/O线 ·两个16位定时器/计数器 ·5个中断源 ·可编程串行通道 ·低功耗的闲置和掉电模式 ·片内振荡器和时钟电路 2.管脚说明: VCC:供电电压。 GND:接地。 P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。

在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。 P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。 P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。 P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。 P3口也可作为AT89C51的一些特殊功能口,如下表所示:

基于51单片机的计算器设计程序代码(汇编)

DBUF EQU 30H TEMP EQU 40H YJ EQU 50H ;结果存放 YJ1 EQU 51H ;中间结果存放GONG EQU 52H ;功能键存放 ORG 00H START: MOV R3,#0 ;初始化显示为空MOV GONG,#0 MOV 30H,#10H MOV 31H,#10H MOV 32H,#10H MOV 33H,#10H MOV 34H,#10H MLOOP: CALL DISP ;PAN调显示子程序WAIT: CALL TESTKEY ;判断有无按键JZ WAIT CALL GETKEY ;读键 INC R3 ;按键个数 CJNE A,#0,NEXT1 ;判断是否数字键 LJMP E1 ;转数字键处理NEXT1: CJNE A,#1,NEXT2 LJMP E1 NEXT2: CJNE A,#2,NEXT3 LJMP E1 NEXT3: CJNE A,#3,NEXT4 LJMP E1 NEXT4: CJNE A,#4,NEXT5 LJMP E1 NEXT5: CJNE A,#5,NEXT6 LJMP E1 NEXT6: CJNE A,#6,NEXT7 LJMP E1 NEXT7: CJNE A,#7,NEXT8 LJMP E1 NEXT8: CJNE A,#8,NEXT9 LJMP E1 NEXT9: CJNE A,#9,NEXT10 LJMP E1 NEXT10: CJNE A,#10,NEXT11 ;判断是否功能键LJMP E2 ;转功能键处理NEXT11: CJNE A,#11,NEXT12 LJMP E2 NEXT12: CJNE A,#12, NEXT13 LJMP E2

51单片机教程(从原理开始基于汇编)及单片机C语言教程

51单片机教程(从原理开始基于汇编)及单片机C语言教程 1.单片机可以做什么? 目前单片机渗透到我们生活的各个领域,几乎很难找到哪个领域没有单片机的踪迹。小到电话,玩具,手机,各类刷卡机,电脑键盘,彩电,冰箱,空调,电磁炉,大到汽车,工业自动控制,机器人,导弹导航装置,甚至是美国的火星车,这些设备里面都含有一个或者多个单片机。单片机的数量不仅远超过PC机,甚至比人类的数量还要多。因此,单片机的学习、开发与应用将造就一大批软硬件工程师。2. 学习单片机需要哪些基本条件? 模拟电路,数字电路基础,对C语言或汇编语言有一定的了解。当然,这些也可以在学习过程中掌握。对此这套教程均有讲解. 硬件条件的话:电脑一台,实验开发平台一套。3、单片机的结构 一台能够工作的计算机要有这样几个部份构成:CPU(进行运算、控制)、RAM(数据存储-内存)、ROM(程序存储)、输入/输出设备(例如:串行口、并行输出口等)。在个人计算机上这些部份被分成若干块芯片,安装一个称之为主板的印刷线路板上。而在单片机中,这些部份,全部被做到一块集成电路芯片中了,所以就称为单片机。单片机是一种

控制芯片,一个微型的计算机,而加上晶振,存储器,地址锁存器,逻辑门,七段译码器(显示器),按钮(类似键盘),扩展芯片,接口等那是单片机系统。天!PC中的CPU一块就要卖几千块钱,这么多东西做在一起,还不得买个天价!再说这块芯片也得非常大了。不,价格并不高,从1元人民币到几十元人民币,体积也不大,一般用40脚封装,当然功能多一些单片机也有引脚比较多的,如68引脚,功能少的只有10多个或20多个引脚,有的甚至只8只引脚。为什么会这样呢?功能有强弱,打个比方,市场上面有的组合音响一套才卖几百块钱,可是有的一台功放机就要卖好几千。另外这种芯片的生产量很大,技术也很成熟,51系列的单片机已经做了十几年,所以价格就低了。既然如此,单片机的功能肯定不强,干吗要学它呢?话不能这样说,实际工作中并不是任何需要计算机的场合都要求计算机有很高 的性能,一个控制电冰箱温度的计算机难道要动用一台台式电脑不成?应用的关键是看是否够用,是否有很好的性能价格比。所以8051出来十多年,依然没有被淘汰,还在不断的发展中。4、MCS51单片机和8051、8031、89C51等的关系 我们平常老是讲8051,又有什么8031,现在又有89C51,89s51它们之间究竟是什么关系? MCS51是指由美国INTEL公司(对了,就是大名鼎鼎的INTEL)生产的一系列

单片机复习题(全)

一、填空题 1、MCS-51单片机扩展程序存储器所用的控制信号为(),扩展数据存储器所用的控制信号为() 和()。 2、关于堆栈类操作的两条指令分别是(PUSH)、(POP),操作遵循(先进后出,后进先出)原则。 3、(程序状态字PSW)寄存器的作用是用来保存程序运行过程中的各种状态信息。若累加器A中的数据 为01110010B,则PSW中的P=(0)。 4、若MCS-51单片机采用12MHZ的晶振,它的机器周期为(1us),ALE引脚输出正脉冲频率为(2MHZ) 5、要使MCS-51 单片机从片内的地址0000H 开始执行程序。那么EA应(接高电平)。 7、外部中断1(INT1)的中断入口地址为(0013H);定时器1的中断入口地为(001BH)。 8、8751有两个16位可编程定时/计数器,T0和T1。它们的功能可由控制寄存器(TMOD) 、(TCON) 的内容决定,且定时的时间或计数的次数与(TH)、(TL)两个寄存器的初值有关。 9、欲使P1口的低4位输出0,高4位不变,应执行一条(ANL P1,#0F0H)命令。 10、串行口的控制寄存器SCON中,REN的作用是(允许串行接收位)。 11、单片机(计算机)在进行(有符号)运算的情况下应使用补码。 12、单片机位寻址区的单元地址是从(20H)单元到(2FH)单元,若某位地址是09H,它所在单元的地 址应该是(21H)。 13、通常,单片机上电复位时PC=(0000)H,SP=(07)H。 14、单片机内部与外部ROM之间的查表指令是(MOVC A,@A+PC)。16、当P1口做输入口输入数据时,必须先向该端口的锁存器写入

51单片机所有伪指令

ASM-51汇编伪指令 一、伪指令分类 1.符号定义 SEGMENT, EQU, SET, DATA, IDATA, XDATA, BIT,CODE 2.存储器初始化/保留 DS, DB, DW, DBIT 3.程序链接 PUBILC, EXTRN, NAME 4.汇编程序状态控制 ORG, END 5.选择段的伪指令 RSEG, CSEG, DSEG, XSEG, ISEG, BSEG, USING 二、伪指令具体说明 1.符号定义伪指令 1)SEGMENT伪指令 格式:段名 SEGMENT 段类型 说明:SEGMENT 伪指令说明一个段。段就是一块程序代码或数据存储器。允许使用的段类型为: ●CODE代码空间 ●DATA 可以直接寻址的内部数据空间 ●XDATA外部数据空间 ●IDATA可以间接寻址的整个内部数据空间 ●BIT位空间 例子:(段符号用于表达式时,代表被连接段的基地址) STACK SEGMENT IDATA RSEG STACK DS 10H ;保留16字节做堆栈

MOV SP , #STACK-1 ;堆栈指针初始化 2)EQU伪指令 格式:符号名 EQU 表达式 符号名 EQU 特殊汇编符号 说明:EQU表示把一个数值或特殊汇编符号赋予规定的名字。 一个表达式赋予一个符号,必须是不带向前访问的表达式。 例子:N27 EQU 27; ACCUM EQU A ;定义ACCUM代替特殊汇编符号A(累加器) HERE EQU $; HERE为当前位置计数器的值 3)SET伪指令 格式:符号名 SET 表达式 符号名 SET 特殊汇编符号 说明:SET类似EQU,区别在于可以用另一个SET伪指令在以后对定义过的符号重新定义。 例子:COUNT SET 0 COUNT SET COUNT+1 4)BIT伪指令 格式:符号名 BIT 位地址 说明: BIT伪指令把一个地址赋予规定的符号名。该符号类型取段类型BIT. 例子: RSEG DATA_SEG; CONTROL: DS 1 ALATM BIT CONTROL.0; OPEN_BOARD BIT ALATM+1 ;下一位 RESET_BOARD BIT 60H ;下一个绝对的位 5)DATA伪指令 格式:符号名 DATA 表达式 说明:DATA伪指令把片内的数据地址赋予所规定的符号名。符号段类型为DATA.

51单片机实例程100讲全集

目录 目录1 函数的使用和熟悉4 实例3:用单片机控制第一个灯亮4 实例4:用单片机控制一个灯闪烁:认识单片机的工作频率4 实例5:将P1口状态分别送入P0、P2、P3口:认识I/O口的引脚功能5实例6:使用P3口流水点亮8位LED5 实例7:通过对P3口地址的操作流水点亮8位LED6 实例8:用不同数据类型控制灯闪烁时间7 实例9:用P0口、P1 口分别显示加法和减法运算结果8 实例10:用P0、P1口显示乘法运算结果9 实例11:用P1、P0口显示除法运算结果9 实例12:用自增运算控制P0口8位LED流水花样10 实例13:用P0口显示逻辑"与"运算结果10 实例14:用P0口显示条件运算结果10 实例15:用P0口显示按位"异或"运算结果11 实例16:用P0显示左移运算结果11 实例17:"万能逻辑电路"实验11 实例18:用右移运算流水点亮P1口8位LED12 实例19:用if语句控制P0口8位LED的流水方向12 实例20:用swtich语句的控制P0口8位LED的点亮状态13 实例21:用for语句控制蜂鸣器鸣笛次数14 实例22:用while语句控制LED15 实例23:用do-while语句控制P0口8位LED流水点亮16 实例24:用字符型数组控制P0口8位LED流水点亮17 实例25:用P0口显示字符串常量18 实例26:用P0 口显示指针运算结果19 实例27:用指针数组控制P0口8位LED流水点亮19 实例28:用数组的指针控制P0 口8 位LED流水点亮20 实例29:用P0 、P1口显示整型函数返回值21 实例30:用有参函数控制P0口8位LED流水速度21 实例31:用数组作函数参数控制流水花样22 实例32:用指针作函数参数控制P0口8位LED流水点亮23 实例33:用函数型指针控制P1口灯花样24 实例34:用指针数组作为函数的参数显示多个字符串25 实例35:字符函数ctype.h应用举例27 实例36:内部函数intrins.h应用举例27 实例37:标准函数stdlib.h应用举例28 实例38:字符串函数string.h应用举例28 实例39:宏定义应用举例229 实例40:宏定义应用举例229 实例41:宏定义应用举例330

相关文档
相关文档 最新文档