ImageVerifierCode 换一换
格式:DOCX , 页数:118 ,大小:98.52KB ,
资源ID:23316628      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/23316628.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(51系列单片机的程序设计.docx)为本站会员(b****9)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

51系列单片机的程序设计.docx

1、51系列单片机的程序设计程序设计及试验 汇编语言是一种面相机器的程序设计语言,单片机内核不一样,汇编的语言和指令格式也不相同.下面我们以51单片机的汇编语言为基础,详细讲解一下51单片机的程序设计,中间穿插了一些试验例子,以便于大家好掌握. 第一课 51单片机汇编程序流程图和设计格式 11序流程图: 在设计程序之前我们都会理一理设计思路,这就是原始的程序流程图,在实际设计中,特别是比较大的项目中,就必须将程序的设计思路先开始定下来,这个思路先开始是一种理想状态,我们认为它是对的,只有在设计和调试中我们才会去纠正某些出错的地方,也就是说,程序流程图只起方向指导的作用,在设计时有可能会一步一步纠正

2、他,有些书上将一些规则讲得很详细,我在此不再累述,我要讲的就是,如果程序只是为自己设计的,你可以自己定义一个熟悉的规则,将程序的设计思路表达出来就行了,没有必要像书上写得那幺正规,但是一定要注意,你的表达方式必须要在你日后能够看得懂它,其中最重要的是在程序语句后面加上注释,小的程序可以不写程序流程图,有一些算法最好是写写程序流程图并最好注释,有必要时可以将入口和出口参数标示出来,以便在今后调用是直接输入入口参数,再取出口参数即可,这里的入口和出口参数分别指的是开始参数和结果参数,比如说:你有一个2个字节乘法程序算法,乘数放在40H,41H,被乘数放在43H,44H单元中,经过此算法后,结果放在

3、放在50H,51H,52H,53H,那幺入口就是40H,41H和43H,44H,在计算开始时,我们将数据放在这些单元中,调用算法后,我们就可以在50H,51H,52H,53H取结果就行,50H,51H,52H,53H就是出口。 12 汇编语言通常是典型的四分段格式,如下: 标号段 操作码段 操作数段 注释段 LABLE OPCODE OPRAND COMMENT 标号段和操作码段之间要用”:”相隔,操作码和操作数段间要用空格分隔;双操作数之间要用”,”分隔,操作数段和注释间要用”;分隔”,操作码段势必选项,其它是任选项: 例如: ORG 0080H START: MOV A,#0 MOV R1

4、,#01H MOV R2,#08H LOOP: ADD A,R1 ;将累加器A加1 DJNZ R2,LOOP NOP LJMP START END 上例中的START,LOOP就是标号字段,MOV ,ADD,NOP就是操作码段,08H,01H就是操作数段, ”将累加器A加1”就是注释; END是整个程序的结束标识. 下面我简单的描述一下指示性语句的用法: 1. ORG XXXXH (16位) 表示程序执行的起始地址; 2.ENG: 表示整个主程序的结束; 3.EQU: 汇编语言的赋值指令,相当于C语言的 “=”; 4.DATA: 汇编语言的数据地址赋值指令; 5.DB: 汇编语言的字节定义指令

5、(8位),常常应用于查表程序中; 6.DW: 汇编语言的字定义指令(16位),常常应用于查表程序中; 7.BIT: 汇编语言的位赋值指令, 相当于C语言的 “SBIT”; 8.DS: 汇编语言的地址预留指令,从它的标号地址开始预留一定数量的单元,已备源程序执行过程中使用,例如: ORG 0400H START: MOV A,#0 LP: DS 09H DB 25H END 上述源程序汇编时,当碰到DS语句时便会自动的从LP地址开始预留9格内存单元; 第二课 I/O口操作程序的设计 I/O口顾名思义就是中文的”输入输出”的意思,51单片机的I/O口操作较简单,不像其它的单片机在程序初始化时要定义

6、一下I/O口的输入输出方向,然后才能操作, 51单片机的I/O口操作较随意,在不同的情况下可任意输入输出,下面我们来学习I/O口操作程序的设计的方法. 2.1 用I/O口点亮LED发光二极管 2.1.1 用P1.0点亮一个LED发光二极管 ORG 0000H ;程序执行的起始地址 LJMP START ORG 0080H START: SETB P1.0 ;关LED LOOP: NOP CLR P1.0 ;开LED LJMP LOOP ;让LED一直被点亮 END 从以上程序我们可以知道,51单片机控制如此容易,下一步我们让LED眨眼睛 2.1.2用P1.0点亮一个LED发光二极管, 并且LE

7、D 亮一秒,灭一秒 在编程序前,我们来认识”延时”的真正涵义: 单片机的延时就是然单片机停在某个地方等一段时间的意思,不要简单认为此时的单片机没有执行操作,只不过是我们让单片机在一个循环程序中执行加减操作,一至运行到此程序的最后一条指令为止,根据单片机机器周期的执行时间,我们可以进行不太精确的延时,下面我们来看一看延时子程序的编写方法. DELAY: MOV R6,#0FFH TN1: MOV R5,#0FFH ; 1个机器周期 TN0: DJNZ R5,TNO ;R5减1,如果R5等于0,从新为R5赋值0FFH; 2个机器周期 DJNZ R6,TN1 ;R6减1,如果R5等于0,退出程序 ;

8、2个机器周期 RET 假设我们用的振荡器频率为12.000M,那幺一个机器周期的时间为: Tx= 12/12M S=0.000001S=1uS 那幺上面的延时程序的时间为: 256 x (256+1) x 1uS=65.8ms 如果我们要做1秒中的延时,就必须将以上程序执行1000/65.8=15次 在实际应用中,我们不可能调用15次以上程序,因而我们会再加上15次循环即可,程序如下: DELAY1mS: MOV R7,#0FH DELAY: MOV R6,#0FFH TN1: MOV R5,#0FFH ; 1个机器周期 TN0: DJNZ R5,TNO ;R5减1,如果R5等于0,从新为R5

9、赋值0FFH; 2个机器周期 DJNZ R6,TN1 ;R6减1,如果R5等于0,退出程序 ;2个机器周期 DJNZ R7,DELAY ;15到了码?没有,返回DELAY RET 有时候,主程序调用延时程序之前,会用到R6,R5,R7积存器,如果调用延时程序后,这些寄存器的值会改变,为了避免这种情况的出现,修改如下: DELAY1Ms: PUSH 05H ;保存R5值 PUSH 06H ;保存R6值 PUSH 07H ;保存R7值 MOV R7,#0FH DELAY: MOV R6,#0FFH TN1: MOV R5,#0FFH ; 1个机器周期 TN0: DJNZ R5,TNO ;R5减1,

10、如果R5等于0,从新为R5赋值0FFH; 2个机器周期 DJNZ R6,TN1 ;R6减1,如果R5等于0,退出程序 ;2个机器周期 DJNZ R7,DELAY ;15到了码?没有,返回DELAY POP 07H ;先弹出R7,注意先进后出的顺序 POP 06H ;然后弹出R6 POP 05H ;最后弹出R5 RET 好了,下面我们再来完成让LED 亮一秒,灭一秒的程序: ORG 0000H ;程序执行的起始地址 LJMP START ORG 0080H START: SETB P1.0 ;关LED LOOP: NOP CLR P1.0 ;开LED CALL DELAY1Ms ;延时1S SE

11、TB P1.0 CALL DELAY1Ms ;延时1S LJMP LOOP ;让LED一直被点亮 END 以上程序,我们也可以让其它的LED灯闪烁,只是变化一下P1口的设置即可,如果我们想要所有的P1口都运作起来,程序怎样编写呢?不要急,我们下一步就来实现它. 2.1.3 将P1口的LED逐个点亮,每个亮一秒,灭一秒. 未了方便初学者了解,我先用一个较为”笨”的办法设计一个程序演示给大家看: ORG 0000H ;程序执行的起始地址 LJMP START ORG 0080H START: MOV A,#0FFH ;关所有的LED MOV P1,A LOOP: CLR P1.0 ;开P10 LE

12、D CALL DELAY1Ms ;延时1S SETB P1.0 CALL DELAY1Ms ;延时1S CLR P1.1 ;开P11 LED CALL DELAY1Ms ;延时1S SETB P1.1 CALL DELAY1Ms ;延时1S CLR P1.2 ;开P12 LED CALL DELAY1Ms ;延时1S SETB P1.2 CALL DELAY1Ms ;延时1S CLR P1.3 ;开P13 LED CALL DELAY1Ms ;延时1S SETB P1.3 CALL DELAY1Ms ;延时1S CLR P1.4 ;开P14 LED CALL DELAY1Ms ;延时1S SE

13、TB P1.4 CALL DELAY1Ms ;延时1S CLR P1.5 ;开P15 LED CALL DELAY1Ms ;延时1S SETB P1.5 CALL DELAY1Ms ;延时1S CLR P1.6 ;开P16 LED CALL DELAY1Ms ;延时1S SETB P1.6 CALL DELAY1Ms ;延时1S CLR P1.7 ;开P17 LED CALL DELAY1Ms ;延时1S SETB P1.7 CALL DELAY1Ms ;延时1S LJMP LOOP ;让LED一直被点亮 END 下面我再用一种通用的程序设计方法设计此程序演示给大家看: ORG 0000H ;

14、程序执行的起始地址 LJMP START ORG 0080H START: MOV A,#0FFH ;关所有的LED MOV P1,A MOV A,#0FEH LOOP: MOV P1,A ;开LED CALL DELAY1mS ;延时1S MOV P1,#0FFH ;关LED CALL DELAY1mS ;延时1S RL A LJMP LOOP END 大家注意一下,上面两个程序有啥区别?第1个程序通俗易懂,第二个程序比较简明,但是不好懂,里面有一个简单的算法,至于其它的跑马灯花样,希望大家自己设计一下程序,我在这里不再累述. 第三课 按键程序的设计 按键的硬件通常有两种形式: 1.独立式:

15、 独立式键盘较为单一,通过判断键盘接入口的状态就能判断有无键按下; 2.矩阵式也叫行列式: 所谓矩阵式就是说每一个按键不是单独的,键与键之间有一定的硬件联系,它的判断是通过先设置某行或某列的状态再来读某列或某行的状态来实现的. 相比之下,两种方式各有千秋,如果单片机资源充足的情况下,用独立式键盘较方便,如果单片机资源紧缺,当然要用矩阵式键盘,下面我们来简单的讲一下独立式键盘的程序编写原理: 试验板上P1为按键输入口,当有按键按下时,对应的P3.2,P3.3的LED会闪动,我们这样做的目的在于让初学者知道散转指令的一些用法,知道按键的实际应用意义,因程序中有延时,有时候按键会没有效,后面的讲课我

16、们会教你如何去克服这种现象,程序设计如下: 89c51 程序编号为: ORG 0000H LJMP START0 ORG 0050H START0: MOV P1,#0FFH MOV A,P1 START: JNB ACC.0,PG0 ;是P1.0被按下吗?是的,转PG0 JNB ACC.1,PG1 ;是P1.1被按下吗?是的,转PG1 JNB ACC.2,PG2 ;是P1.2被按下吗?是的,转PG2 JNB ACC.3,PG3 ;是P1.3被按下吗?是的,转PG3 JNB ACC.4,PG4 ;是P1.4被按下吗?是的,转PG4 JNB ACC.5,PG5 ;是P1.5被按下吗?是的,转PG

17、5 JNB ACC.6,PG6 ;是P1.6被按下吗?是的,转PG6 JNB ACC.7,PG7 ;是P1.7被按下吗?是的,转PG7 SJMP START PG0: MOV P3,#0FFH CLR P3.2 ;点亮D7 SJMP START PG1: MOV P3,#0FFH CLR P3.3 ;点亮D8 SJMP START PG2: MOV P3,#0FFH CLR P3.2 ;点亮D7 CLR P3.3 ;点亮D8 SJMP START PG3: MOV P3,#0FFH MOV A,#8 NEXT0: CLR P3.2 ; ;点亮D7 CALL DELAY1Ms ;延时1S SET

18、B P3.2 ;灭D7 DEC A CJNE A,#00,NEXT0 ;循环8次 SJMP START PG4: MOV P3,#0FFH CLR P3.3 SJMP START PG5: MOV P3,#0FFH CLR P3.2 SJMP START PG6: MOV P3,#0FFH CLR P3.2 CLR P3.3 SJMP START PG7: MOV P3,#0FFH SJMP START END 那幺矩阵式键盘的程序又是怎样设计的呢?通常有三种方法来设计按键扫描程序:计算法;查表法;查寻法。下面我用计算法来设计一下按键扫描程序: 程序标号为: KEY01.ASM P1.4 P1

19、.5 P1.6 P1.7 P1.0 P1.1 P1.2 P1.3 89C51 ORG 0000H LJMP START ORG 0050H START: MOV P1,#0FH ;按键初始化 LCALL KEYIN ;调按键输入子程序 JNZ LKOUT ;有按键吗? LJMP START LKOUT: MOV R2,#0EFH ;首列扫描码送入R2 MOV R4,#00H ;首列偏移值送R4 CONU: MOV P1,R2 ;列扫描码送P1 MOV A,P1 ;读按键值 JB ACC.0,L0NE ;检查按键是否在第0行. MOV A,#00H ;此行有键按下,将列号放入A AJMP KCO

20、DE ;求出键号 LONE: JB ACC.1,LTWO ; 检查按键是否在第1行. MOV A,#04H ; 此行有键按下,将列号放入A AJMP KCODE ; 求出键号 LTWO: JB ACC.2,LTHREE ; 检查按键是否在第2行. MOV A,#08H ; 此行有键按下,将列号放入A AJMP KCODE ; 求出键号 LTHREE: JB ACC.3,LFOUR ; 检查按键是否在第2行. MOV A,#0CH ; 此行有键按下,将列号放入A LKP: ; 求出键号 ADD A,R4 ;行号加列号进行编码 PUSH A ;将A中的值保存起来 LCALL KEYIN ;等待按键

21、释放 JNZ WKFE ; 按键松开了码? POP A ;按键松开,键值放在A中 LJMP KJMP ;根据键值处理相关事项 LFOUR: INC R4 ;此列没有键按下,继续检查下一列 MOV A,R2 ; JNB ACC.7,KND ;4列检查完了码? RL A ;没有,继续检查. MOV R2,A ; LJMP CONU ; KND: ; 4列检查完,返回 RET KEYIN: MOV P1,#0FH ;想将按键初始化 MOV A,P1 ;读按键 CPL A ;取反 ANL A,#0FH ;屏蔽高四位,在这里其实是检查有无按键按 ;下,如A不等于0,表示有按键按下. RET KJMP:

22、;后面的显示程序中我们会将此转散程序加 ;上的 从上面的程序我们知道,按键的编码其实就是按照我们预先定义的键号来做的,至于键号是多少,我们不要去理会,因为我们可以根据自己想要的一个键号值去处理相关的事务.光有按键程序,我们看不到按键执行的效果,下面我重点讲一下用查表法来设计按键扫描程序的设计: 程序编号为: ORG 0000H LJMP START ORG 0050H START: MOV A,#0FFH ;请按键 MOV P1,A MOV P2,A ;关显示 START1: MOV R3,#0F7H ;按键扫描码送R3 MOV R1,#00H ;先将按键值置0 START2: MOV A,R

23、3 ;开始扫描按键 MOV P1,A MOV A,P1 ;读按键 MOV R4,A ;按键存入R4 SETB C MOV R5,#04H ;按键扫描4次 START3: RLC A ;看有没有按键按下 JNC KEYIN INC R1 ;没有,指针加一 DJNZ R5,START3 ;扫描四列了吗? MOV A,R3 ;扫描值送入A SETB C RRC A MOV R3,A JC START2 ;4行扫描完了吗? LJMP START1 ;是 KEYIN: MOV R7,#80 ;消抖延时程序 KEYIN1: MOV R6,#200 DJNZ R6,$ DJNZ R7,KEYIN1 KEYI

24、N2: MOV A,P1 ;在次读按键 XRL A,R4 ;与前一次按键值比较 JZ KEYIN2 ;按键松开了吗? MOV A,R1 ;是 MOV DPTR,#TAB1 ;查表 MOVC A,A+DPTR MOV 30H,A ;键值存在30H中 LJMP START1 TAB1: DB 0DH,0EH,00H,0FH DB 0CH,07H,08H,09H DB 0BH,04H,05H,06H DB 0AH,01H,02H,03H END 从上面的两个程序我们可以分析得出,查表法设计程序较为简洁,比较好懂,用查寻法设计程序,逻辑较差,程序似乎不紧奏,无论用那种方法,结果都一样,因此,初学者最好

25、定好一种格式,将自己的风格加进去,学会用自己的个性来设计程序。 第四课 LED段码管的显示程序的编写 关于段码显示器的显示原理,其实就是将8个LED集成在一起组成一个8字型的器件,从而显示出我们想要的数字,现将编码表列出如下: 显示字符共阴极段码 共阳极段码显示字符共阴极段码共阳极段码 0 3FH C0H 9 6FH 90H 1 06H F9H A 77H 88H 2 5BH A4H B 7CH 83H 3 4FH B0H C 39H C6H 4 66H 99H D 5EH A1H 5 6DH 92H E 79H 86H 6 7DH 82H F 71H 8EH 7 07H F8H 8. FFH

26、 00H 8 7FH 80H 灭 00H FFH 在试验板上我用的是HCF4056或CD4056,这种LED驱动器好处就是能直接将数据显示出来,比如:我们要讲“6”显示出来,我们可将ABCD=6,再开通片璇即可,缺点是不能显示BCDEF,列表如下: 显示字符ABCD 显示字符ABCD 0 0 9 9 1 1 L A 2 2 H B 3 3 P C 4 4 A D 5 5 - E 6 6 灭 F 7 7 8 8 下面我们来学习段码显示器的显示程序的编写方法. 4.1.1点亮一个段码显示器 试验板的原理图中, 我们下面讲的是直接I/O口操作,显示数据从P2口输出,让第一个显示器显示“6”,程序编写

27、如下: ORG 0000H LJMP START ORG 0050H START: MOV 50H,#6 MOV A,#0FFH ;关显示 MOV P2,A START1: MOV A,#0FH ;清第1个显示器 ADD A,#10H MOV P2,A MOV A,50H ;显示当前按键值 ADD A,#10H MOV P2,A LJMP START1 DELAY: PUSH 07H PUSH 06H MOV R7,#08H DELAY1: MOV R6,#200 DJNZ R6,$ DJNZ R7,DELAY1 POP 06H POP 07H RET END 上面的程序设计只是教我们如何去点亮一个段码显示器,在实际应用中这是毫无使用价值的,下面我们来讲试验板上的4位段码显示器全部显示为“6“. 4.1.2点亮4为段码显示器,让他们显示”6666”. 注: 今后如果没有特别说明,显存地址均为: 50-57H ORG 0000H LJMP START ORG 0050H START: MOV 50H,#6 MOV A,#0FFH ;请按键 MOV P2,A START1: MOV A,#0FH ;清第1个显示器 ADD A,#10H MOV P2,A MOV A,50H ;显示”6” ADD A,#10H MOV P2,A MOV A,#0FH ;清第2个显示器 ADD

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1