几个单片机汇编语言教学例程及详细分析

几个单片机汇编语言教学例程及详细分析
几个单片机汇编语言教学例程及详细分析

最近,我们在课上讲了几个小例子,在此再把Proteus图及程序的详细解释列出来,供大家参考。

1.应用查询方式,对连接在P1.4管脚上的按键次数进行计数,

每5次在P1.0上连接的红色LED亮或不亮。

本题考虑点:

A.应用查询方式,即读和检测P1.4管脚的状态,是1或0;

B.每5次翻转一次,因此可设一个寄存器作为计数器,看是否到了5次,5次后清零;

C.P1.0上的LED亮或不亮,即状态翻转,CPL P1.0。

Proteus图

应用元器件:单片机80C51(或80C52)、按键Button、电阻Res、LED

图1 找元器件的方法

单片机属于微处理器库里面的,因此,应再点击Microprocessor ICS,后同。

图2. 1题图

程序:

ORG 0H ;程序从程序存储器的0单元开始存放MAIN: MOV R0,#0 ;设R0为计数器,赋初始值0,注意,在这儿不赋值0,单片机一上电R0也等于0

LOOP: JB P1.4,$ ;若P1.4为高,表明没键按下,等待

JNB P1.4,$ ;若P1.4为低,表明有键按下,等待该键的弹起

INC R0 ;按键弹起后,表明按键一次,计数器加1

CJNE R0,#6,LOOP ;若R0不等于6,表明还没按够5次,继续查询按键信息

MOV R0,#0 ;若R0=6,表明已经被按下5次,计数器清零

CPL P1.0 ;P1.0翻转,即LED的状态转换

AJMP LOOP ;进入下一个循环

END ;程序结束

图3 调试状态

1.应用定时器,控制从P1.0和P1.1输出周期为300us和600us

的方波程序。

本题考虑点:

首先明确为应用定时器,且输出波形为方波,周期300us和600us,也就是说,如果用这两个管脚输出波形的话,其翻转的时间分别为150us和300us。

然后确定应用定时器的工作方式,对于6MHz的晶振来说,对于12分频的单片机的机器周期为2us,即对机器周期的计数分别为75和150,都小于256,因此,可用8位定时器,并且300us是150us的整数倍,因此可用一个定时器解决。在此选用自动装入的8位定时器,即工作方式2,设用T0。

则TMOD的取值为:

先看TMOD的各位: GATE C\T M1 M0 GATE C\T M1 M0

因为用T0来计时,且在本题目中T1不用,因此,TMOD的取值可为:00000010B ,16进制:02H

初始值的计算,应用公式:

计算得:X=106,16进制为6AH,即TH0和TL0的赋值都为6AH(因方式2位自动装入模式)

Proteus图:

图4 题2图及调出示波器的位置

程序及解释:

ORG 0H ;程序从程序存储器的0单元开始存放

AJMP MAIN ;跳转至以MAIN为标号的主程序

ORG 0BH ;0B是定时器0的中断子程序入口

AJMP T0INT ;跳转到以T0INT为标号的中断子程序

ORG 30H ;主程序从30H单元开始存放

MAIN: MOV TMOD,#20H ;设置定时器的工作方式,采用工作方式2即自动装入的8位 MOV TH0,#8AH ;给TH0赋初值

MOV TL0,#8AH ;给TL0赋初值

SETB EA ;打开总中断

SETB ET0 ;打开T0的中断

SETB TR0 ;让T0开始工作

SJMP $ ;踏步,等待中断

T0INT: CPL P1.0 ;时间到,翻转P1.0

INC R0 ;因为300us正好是150us的整数倍,因而可用一个定时器

CJNE R0,#2,GOON ;用R0作为中断几次的计数器,若中断2次既达到150us的两倍 MOV R0,#0 ;若达到了两倍,翻转,计数器清零

CPL P1.1 ;P1.1翻转

GOON: RETI ;中断子程序返回

END ;程序结束

图5 波形图

1.应用164带3只数码管,显示从000-999的单个跳数;

本题考虑点:

164是移位寄存器,因此最好直接用串口,与164连接;

3位数,可把三位数设为一个计数器,设从30H-32H,其中30H为最低位,31H为中间位,32H为最高位,然后从30H开始加1,当30H加到10后,30H清零,31H再加1,31H

为10后,变为零,32H再加1,当32H为10后,清零。

把显示部分编写为一个子程序,30-32H内的数每改变一次,调用一次显示;

由于人的视力跟不上单片机一条指令的运算时间,因此需要延时。

因此,在软件设计上可分为三部分:一是加数部分,一是显示部分,一是延时部分。Proteus图:

图6 题3图

(注意RXD、TXD的接法,以及后两只164的接法)

程序:

ORG 0H ;程序从程序存储器的0单元开始存放

AJMP MAIN ;跳转到主程序

ORG 30H ;主程序从程序存储器的30H单元开始存放

MAIN: MOV 30H,#0 ;给30H单元赋初始值0

MOV 31H,#0 ;给31H单元赋初始值0

MOV 32H,#0 ;给32H单元赋初始值0

LOOP: INC 30H ;30H单元内的数加1

MOV R1,30H ;将30H单元内的数赋值给R1,以便应用CJNE Rn,#DATA,REL 语言判断并跳转

CJNE R1,#10,NEXT ;若30H内的数不是10则跳转到调用显示

MOV 30H,#0 ;若30H内的数是10,则清零

INC 31H ;上位30H的数等于10时,下一位31H加1

MOV R1,31H ;将31H内的数赋值给R1

CJNE R1,#10,NEXT ;间接地判断31H内的数是否等于10,如不是,转显示

MOV 31H,#0 ;若31H等于10,则清零,将32H加1

INC 32H ;32H加1(此为最高位)

MOV R1,32H ;判断32H的数值

CJNE R1,#10,NEXT ;间接判断32H内的数是否等于10,不是转显示

MOV 32H,#0 ;若是32H清零

NEXT: ACALL DISPLAY ;调用显示子程序

ACALL DELAY ;调用延时子程序

SJMP LOOP ;跳转到加1部分,循环

DISPLAY:MOV R0,#30H ;将显示数据的存放首单元赋值给R0,以便调用循环将数值赋值给A

MOV DPTR,#TAB ;将显示码的首地址赋值给DPTR

DISLOP:MOV A,@R0 ;将以R0内的数30H内的数值赋值给A

MOVC A,@A+DPTR ;查表语句,将显示码赋值给A

MOV SBUF,A ;将显示码通过串行口送出去

JNB TI,$ ;如果TI不等于1,表明还没送出去,等待

CLR TI ;若TI=1表明数据已经送走,将送走的标志位TI清零,以便进行下次输送

INC R0 ;指向下一单元

CJNE R0,#33H,DISLOP ;判断是否将3个单元(30H,31H,32H)的数据都送完 RET ;子程序返回

DELAY: MOV R7,#0 ;延时子程序,给R7赋值0(相当于256)

DEL1: MOV R6,#0 ;给R6赋值0

DJNZ R6,$ ;若R6-1不等于0,在此语句循环

DJNZ R7,DEL1 ;如R0=0则判断R7-1是否为零,不为零则跳转到DEL1,给R6重新赋值

RET ;子程序返回

TAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;显示码表

END ;程序结束

图7 运行状态图

1.应用双机通讯,实现在A机上的数码管数字加到按另一键时

的将该数发送到B机的数码管上显示。

公共端接高。

图8 题4图

编程:

主机程序:

ORG 0H ;程序从程序存储器的0单元开始存放

AJMP MAIN ;跳转到以MAIN为标号的程序去

ORG 30H ;以下程序从程序存储器的30H开始存放

MAIN: MOV TMOD,#20H ;选用定时器2工作模式,即自动赋初始值的8位定时器 MOV TH1,#0F4H ;给TH1赋值0F4H;

MOV TL1,#0F4H ;给TL1赋值0F4H;

SETB EA ;打开总中断允许位;

SETB ET1 ;打开定时器1的中断允许位;

SETB TR1 ;使定时器1运行

MOV SCON,#50H ;设置串行口的工作模式,采用模式1

MOV DPTR,#TAB ;赋值显示码表的首地址

MOV R0,#0 ;设置R0为显示数字的计数器

MOV R1,#0 ;R1设置为讯显示码的中转寄存器

KEYSCAN:JB P1.0,KEY1 ;若按键1没有被按下,转去查询键2

JNB P1.0,$ ;如键1被按下,则等待键1弹起

INC R0 ;键1弹起后,显示数加1

CJNE R0,#10,NEXT ;如显示数等于10,则从0开始

MOV R0,#0 ;清零

NEXT: MOV A,R0 ;将显示的数给A

MOVC A,@A+DPTR ;查表取显示的码值

MOV R1,A ;将码值给R1暂存

MOV P0,A ;将显示码值给P0显示

key1: JB P1.1,KEYSCAN ;检测第二个按键按下没有

JNB P1.1,$ ;按下了等待弹起

MOV A,R1 ;将显示码给A

MOV SBUF,A ;将显示码送去串行口

JNB TI,$ ;若TI不等于1,表明正在发送中

CLR TI ;TI=1,则表明已经发送完毕,将标志位清零,以便下次发送 SJMP KEYSCAN ;继续检测有按键是否被按下

TAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH ;显示码

END ;程序结束

从机程序:

ORG 0H ;程序从程序存储器的0单元开始存放

AJMP MAIN ;跳转到以MAIN为标号的程序去

ORG 30H ;以下程序从程序存储器的30H开始存放

MAIN: MOV TMOD,#20H ;选用定时器2工作模式,即自动赋初始值的8位定时器 MOV TH1,#0F4H ;给TH1赋值0F4H;

MOV TL1,#0F4H ;给TL1赋值0F4H;

SETB EA ;打开总中断允许位;

SETB ET1 ;打开定时器1的中断允许位;

SETB TR1 ;使定时器1运行

MOV SCON,#50H ;设置串行口的工作模式,采用模式1

LOOP: JNB RI,$ ;若RI不等于1,表明无数据通过串行口送入

CLR RI ;如RI=1,表明有数据送入,将RI清零,以便下次接收

MOV A,SBUF ;将串行口接收到的数据给A

MOV P0,A ;A将接收到的数据传送给P0,显示

SJMP LOOP ;继续等待接收到数据

END ;程序结束

图9 题4运行状态图

1.应用外部中断,对连接在P3.2管脚上的按键次数进行计数,

每5次在P1.0上连接的绿色LED亮或不亮。

本题考虑点:

要求应用外部中断,则必须应用中断子程序,且在子程序内计数,满5次让P1.0翻转。Proteus图:

图10 题5图

编程:

ORG 0H ;程序从程序存储器的0单元开始存放 AJMP MAIN ;跳转到以标号为MAIN处

ORG 03H ;外部中断0的9子程序入口

AJMP INT0 ;调用外部中断子程序INT0

ORG 30H ;主程序从程序存储器的30H单元开始存放MAIN: SETB EA ;打开总中断

SETB EX0 ;打开外部中断0的中断

SETB IT0 ;将外部中断0的触发信号设置为下降沿

SJMP $ ;在此等待中断发生

INT0: INC R0 ;用R0作为计数器,每中断一次加1 CJNE R0,#5,NEXT ;若没中断5次返回,等待下一次

MOV R0,#0 ;将计数器清零

CPL P1.0 ;将P1.0翻转

NEXT: RETI ;中断子程序返回

END ;程序结束

图11 题5运行状态图

1.应用计数器,对连接在P3.4管脚上的按键次数进行计数,每5

次在P1.0上连接的黄色LED亮或不亮。

本题考虑点:

题意用计数器,且在P3.4管脚上,即应用计数器T0;

未说明用查询还是中断方式,本题选用中断方式。

Proteus图:

图12 题6图

程序:

ORG 0H ;主程序入口

AJMP MAIN ;跳转到以MAIN为标号的程序

ORG 0BH ;计数器中断0的子程序入口

AJMP INT0 ;调用外部中断子程序INT0

ORG 30H ;主程序从程序存储器的30H单元开始存放MAIN: MOV TMOD,#06H ;设置计数器为8位自动装入模式 MOV TH0,#251 ;设置TH0初始值为256-5=251

MOV TL0,#251 ;设置TL0同上

SETB EA ;打开总中断

SETB ET0 ;打开计数器0的中断

SETB TR0 ;将计数器0打开

MOV R0,#0 ;给R0赋值0

SJMP $ ;在此等待中断发生

INT0: CPL P1.0 ;将P1.0翻转

NEXT: RETI ;中断子程序返回

END ;程序结束

完整的Word格式文档51黑下载地址:

近期的几个单片机例程及详细分析(1).doc(283.5 KB, 下载次数: 7)

相关主题
相关文档
最新文档