模板单片机实验报告

  

单片机实验报告

              学院  信 息 工 程 学院   

              专业:    电子信息工程     

              班级:               

              学号:             

              姓名                


                  实验一 存储器块清零

一、实验要求

1. 指定存储器中某块的起始地址和长度,要求能将其内容清零。

、实验目的

1. 掌握存储器读写方法

2. 了解存储器的块操作方法

三、实验说明

通过本实验,学生可以了解单片机读写存储器的读写方法,同时也可以了解单片机编程,

调试方法。如何将存储器块的内容置成某固定值(例全填充为0FFH)? 请学生修改程序,完

成此操作。

四、程序框图

五、程序设计:

      MOV DPTR,#1000H;

      MOV B,#64H;

      CLR A

LOOP:

      MOVX @DPTR,A;

      INC DPTR;

      DJNZ B,LOOP;

      LJMP $

      END

遇到的问题及解决方法

问题:直接给存储器清零

解决方法:在给存储器赋值时只有一条语句即:MOVX @DPTR,A不存在MOVX @DPTR,#data所以要实现给存储器清零则需要首先将累加器A清零,然后通过A给存储器清零。

                     实验二   内存块移动

一、实验要求

将指定源地址和长度的存储块移到指定目标位置

、实验目的

1.了解内存的移动方法。

2.加深对存储器读写的认识。

三、实验说明

块移动是计算机常用操作之一,多用于大量的数据复制和图象操作。本程序是给出起

始地址,用地址加一方法移动块,请思考给出块结束地址,用地址减一方法移动块的算法。

另外,若源块地址和目标块地址有重叠,该如何避免?

四、程序框图


程序:     

        MOV DPTR,#1000H;

        MOV B,#64H;

        MOV A,#09H

LOOP:

        MOVX @DPTR,A;

        INC DPTR;

        DJNZ B,LOOP;

        MOV R0,#10H

        MOV R1,#00H

        MOV R2,#30H

        MOV R3,#00H

        MOV B,#64H

LOOP1:

        MOV DPH,R0

        MOV DPL,R1

        MOVX A,@DPTR

        MOV DPH,R2

        MOV DPL,R3

        MOVX @DPTR,A

        CJNE R1,#0FFH,Goon1

        INC R0

Goon1:

        INC R1

        CJNE R3,#0FFH,Goon2

        INC R2

Goon2:

        INC R3

        DJNZ B,LOOP1

        LJMP $

        END


遇到的问题及解决方法。

问题:使用一个8位寄存器,若移动的数据超出256个会出现数据丢失。

解决方法:如果是一个寄存器,如:INC  R1一旦R1为0FFH再增加1后就会清零从新由1000H处移动数据而1100H后的数据就会丢失。所以增加一个8位寄存器后,依然如上例当R1加到0FFH后将高8位地址加1即R0为11H就实现了1100H后的数据移动。


                        硬件实验三  外部中断实验

一、实验要求

用单次脉冲申请中断,在中断处理程序中对输出信号进行反转。

、实验目的

1、学习外部中断技术的基本使用方法。

2、学习中断处理程序的编程方法。

三、实验电路及线

、实验说实明

中断服务程序的关键是:

1.保护进入中断时的状态,并在退出中断之前恢复进入时的状态。

2.必须在中断程序中设定是否允许中断重入,即设置EXO位。

3.对于80C196,要选择相应的中断源,并设置中断屏蔽寄存器的相应位。

本例中使用了INTO中断(80C196为EXTINT 中断),一般中断程序进入时应保护PSW,

ACC以及中断程序使用但非其专用的寄存器。本例的中断程序保护了PSW,ACC等三个寄存

器并且在退出前恢复了这三个寄存器。另外中断程序中涉及到关键数据的设置时应关中断,

即设置时不允许重入。本例中没有涉及这种情况。

INTO(P32)端(80C196为EINT 端)接单次脉冲发生器。P1.0接LED灯,以查看信号

反转.

五、实验框图


程序:

ORG 0000H

LJMP MAIN

ORG 0003H

LJMP INT

ORG 0100H

MAIN:

SETB EX0

SETB IT0

SETB EA

HERE:

AJMP HERE

INT:

CLR EA

PUSH PSW

PUSH Acc

SETB EA

CPL P1.0

CLR EA

POP Acc

POP PSW

SETB EA

RETI

END


遇到的问题及解决方法

问题:等待中断指令混淆如将LJMP $中的$与AJMP组成AJMP $.

解决方法:使用LJMP $或者HERE:AJMP HERE等规定的指令。

          


                   硬件实验四  定时器实验

一、实验要求

    用CPU内部定时器中断方式计时,实现每一秒钟输出状态发生一次反转.

、实验目的

    1、学习8031内部计数器的使用和编程方法。

    2、进一步掌握中断处理程序的编程方法。

三、实验电路及线

、实验说明

    1、关于内部计数器的编程主要是定时常数的设置和有关控制寄存器的设置。内部计

数器在单片机中主要有定时器和计数器两个功能。本实验使用的是定时器。

    2、定时器有关的寄存器有工作方式寄存器TMOD和控制寄存器TCON。TMOD用于设置

定时器/计数器的工作方式0-3,并确定用于定时还是用于计数。TCON 主要功能是为定时器

在溢出时设定标志位,并控制定时器的运行或停止等。

    3、内部计数器用作定时器时,是对机器周期计数。每个机器周期的长度是12个振

荡器周期。因为实验系统的晶振是6MHZ,本程序工作于方式2,即8位自动重装方式定时器,

定时器100us中断一次, 所以定时常数的设置可按以下方法计算:机器周期=12÷6MHZ=2uS

(256-定时常数)×2uS=100us  定时常数=206. 然后对100us中断次数计数10000次,就是1秒钟.

    4、在例程的中断服务程序中,因为中断定时常数的设置对中断程序的运行起到关键

作用,所以在置数前要先关对应的中断,置数完之后再打开相应的中断。

    5、对于80C196,与定时器有关的寄存器为IOC1.2和INT-MASK。IOC1.2为定时器1

溢出中断允许/禁止位。INT-MASK的第0位为定时器溢出屏蔽位。

    6、对于80C196,在设置中断定时常数时,要注意先设置窗口寄存器WSR,设置完常

数后,再恢复原WSR值。

五、实验框图


定时1s:

ORG 0000H

LJMP MAIN

ORG 000BH

LJMP IT0P

ORG 1000H

MAIN:

MOV SP,#60H

MOV R1,#32H

MOV R2,#28H

MOV TMOD,#02H

MOV TH0,#06H

MOV TL0,#06H

SETB TR0

SETB ET0

SETB EA

HERE:

SJMP HERE

IT0P:

DJNZ R1,LOOP

MOV R1,#32H

DJNZ R2,LOOP

CLR EA

PUSH PSW

PUSH Acc

SETB EA

CPL P1.0

CLR EA

POP Acc

POP PSW

SETB EA

LOOP:

RETI


遇到的问题及解决方法

1.问题:定时器工作在方式一

解决方法:工作在方式一不能自动重新装载定时器,需要用软件来从新设置初值。改正后使用方式二,可以实现自动从新装载定时器。

2.问题:定时一秒误差比较大

解决方法:可以尽量使定时器循环的次数减少,如将每次定时器计时100us(计数50次T0初值为0CEH,循环10000次)改为每次计时500us(计数250次T0初值为06H循环2000次)。

          


        硬件实验五  D/A 转换实验

一、实验要求

利用DAC0832,编制程序产生锯齿波、三角波、正弦波。三种波轮流显示,用示波器

观看。

、实验目的

1、了解D/A转换的基本原理。

2、了解D/A转换芯片0832的性能及编程方法。

3、了解单片机系统中扩展D/A转换的基本方法。

三、实验电路及线

用电压表或示波器探头接-5V~+5V输出,观察显示电压或波形。

、实验说明

   1、D/A转换是把数字量转换成模拟量的变换,实验台上D/A电路输出的是模拟电压

信号。要实现实验要求,比较简单的方法是产生三个波形的表格,然后通过查表来实现波

形显示。

   2、产生锯齿波和三角波的表格只需由数字量的增减来控制,同时要注意三角波要分

段来产生。

   要产生正弦波,较简单的方法是造一张正弦数字量表。即查函数表得到的值转换成

十六进制数填表。

   D/A 转换取值范围为一个周期,采样点越多,精度越高些。本例采用的采样点为256

点/周期。

   3、8 位D/A转换器的输入数据与输出电压的关系为

   U(0∽-5V)=Uref/256×N

   U(-5V∽+5V)=2·Uref/256×N-5V (这里 Uref为+5V)

五、 实验框图

       


程序:

ORG 0000H

START:

MOV R0,#0FEH

MOV A,#00H

LOOP:

MOVX @R0,A

INC A

CJNE A,#00H,LOOP

UP:

MOVX @R0,A

INC A

JNZ UP

DOWN:

DEC A

MOVX @R0,A

JNZ DOWN

LOOP1:

MOV R2,#02H

MOV R4,#0FFH

SJMP LOOP3

LOOP2:

MOV @R0,A

INC R2

DJNZ R4,LOOP3

AJMP START

LOOP3:

MOV A,R2

ADD A,#02H

MOVC A,@A+PC

SJMP LOOP2


TAB:DB 80H,83H,86H,89H,8DH,90H,93H,96H  

DB 99H,9CH,9FH,0A2H,0A5H,0A8H,0ABH,0AEH         

DB 0B1H,0B4H,0B7H,0BAH,0BCH,0BFH,0C2H,0C5H         

DB 0C7H,0CAH,0CCH,0CFH,0D1H,0D4H,0D6H,0D8H         

DB 0DAH,0DDH,0DFH,0E1H,0E3H,0E5H,0E7H,0E9H         

DB 0EAH,0ECH,0EEH,0EFH,0F1H,0F2H,0F4H,0F5H         

DB 0F6H,0F7H,0F8H,0F9H,0FAH,0FBH,0FCH,0FDH 

DB 0FDH,0FEH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH         

DB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FEH,0FDH         

DB 0FDH,0FCH,0FBH,0FAH,0F9H,0F8H,0F7H,0F6H         

DB 0F5H,0F4H,0F2H,0F1H,0EFH,0EEH,0ECH,0EAH         

DB 0E9H,0E7H,0E5H,0E3H,0E1H,0DEH,0DDH,0DAH         

DB 0D8H,0D6H,0D4H,0D1H,0CFH,0CCH,0CAH,0C7H         

DB 0C5H,0C2H,0BFH,0BCH,0BAH,0B7H,0B4H,0B1H         

DB 0AEH,0ABH,0A8H,0A5H,0A2H,9FH,9CH,99H         

DB 96H,93H,90H,8DH,89H,86H,83H,80H         

DB 80H,7CH,79H,76H,72H,6FH,6CH,69H         

DB 66H,63H,60H,5DH,5AH,57H,55H,51H         

DB 4EH,4CH,48H,45H,43H,40H,3DH,3AH

DB 38H,35H,33H,30H,2EH,2BH,29H,27H         

DB 25H,22H,20H,1EH,1CH,1AH,18H,16H         

DB 15H,13H,11H,10H,0EH,0DH,0BH,0AH         

DB 09H,8H,7H,6H,5H,4H,3H,2H         

DB 02H,1H,0H,0H,0H,0H,0H,0H         

DB 00H,0H,0H,0H,0H,0H,1H,2H         

DB 02H,3H,4H,5H,6H,7H,8H,9H 

DB 0AH,0BH,0DH,0EH,10H,11H,13H,15H         

DB 16H,18H,1AH,1CH,1EH,20H,22H,25H         

DB 27H,29H,2BH,2EH,30H,33H,35H,38H         

DB 3AH,3DH,40H,43H,45H,48H,4CH,4EH         

DB 51H,51H,55H,57H,5AH,5DH,60H,63H         

DB 69H,6CH,6FH,72H,76H,79H,7CH,80H

遇到的问题及解决方法

问题:转换出的三种波形出现叠加现象。

解决方法:


原程序:

MOV R0,#0FEH

MOV R7,#00H

MOV A,#00H

LOOP:

MOVX @R0,A

INC A

CJNE A,#00H,LOOP

DJNZ R7,LOOP

UP:

MOVX @R0,A

INC A

JNZ UP

DOWN:

DEC A

MOVX @R0,A

JNZ DOWN

DJNZ R7,UP

LOOP1:

MOV R2,#02H

MOV R4,#0FFH

SJMP LOOP3

LOOP2:

MOV @R0,A

INC R2

DJNZ R4,LOOP3

DJNZ R7,LOOP1

RET

LOOP3:

MOV A,R2

ADD A,#02H

MOVC A,@A+PC

SJMP LOOP2


   分析此程序可以发现产生的三种波形方式为分时显示即先产生256个锯齿波然后产生256个三角波最后产生256个正弦波。理论上可以显示但实际上各种波形显示的时间非常短,上个波形的余晖尚未消失下一个的波形就显示出来以至于出现波形叠加。

   程序应该改为将三种波同时显示然后循环,即将锯齿波、三角波、正弦波三个波连起来作为一个波,周期为三个波的周期之和。

改正后的程序:


LOOP:

MOVX @R0,A

INC A

CJNE A,#00H,LOOP

UP:

MOVX @R0,A

INC A

JNZ UP

DOWN:

DEC A

MOVX @R0,A

JNZ DOWN

LOOP1:

MOV R2,#02H

MOV R4,#0FFH

SJMP LOOP3

LOOP2:

MOV @R0,A

INC R2

DJNZ R4,LOOP3

AJMP START

LOOP3:

MOV A,R2

ADD A,#02H

MOVC A,@A+PC

SJMP LOOP2


    


             硬件实验六   外部中断(急救车与交通)

一、实验要求

本实验模拟交通信号灯控制,一般情况下正常显示,有急救车到达时,两个方向交通

信号灯全红,以便让急救车通过。设急救车通过路口时间为10 秒,急救车通过后,交通恢

复正常,本实验用单次脉冲申请外部中断,表示有急救车通过。

、实验目的

1、学习外部中断技术的基本使用方法。

2、学习中断处理程序的编程方法。

三、实验电路及线

、实验说明

中断服务程序的关键是:

1、保护进入中断时的状态,并在退出中断之前恢复进入时的状态。

2、必须在中断程序中设定是否允许中断重入,即设置EXO位。

本例中使用了INTO中断(80C196为EINT中断),一般中断程序进入时应保护PSW,ACC

以及中断程序使用但非其专用的寄存器。本例的中断程序保护了PSW,ACC等三个寄存器并

且在退出前恢复了这三个寄存器。另外中断程序中涉及到关键数据的设置时应关中断,即

设置时不允许重入。本例中没有涉及这种情况。

对于8051CPU 外部中断由INTO(P32)端接入。对于80C196CPU外部中断由EINT接入。

中断信号由单次脉冲发生器产生。

对中断的处理可参见硬件实验十一

本实验提供了用8255 的PA 口和用单片机的I/O 端口控制交通信号灯两种方法,其中196

用8255,51 用P1口,可以互相参考51和196的程序。

五、实验框图

程序:


LED1 EQU P1.0

LED2 EQU P1.1

LED3 EQU P1.2

LED4 EQU P1.3

LED5 EQU P1.4

LED6 EQU P1.5

ORG 0000H

LJMP DIR

ORG 0003H

LJMP INT0

ORG 0100H

MAIN:

SETB LED1

SETB LED4

CLR LED2

CLR LED3

CLR LED5

CLR LED6

SETB EA

SETB EX0

SETB IT0

LOOP1:

CLR LED6

CLR LED1

SETB LED2

SETB LED4

LCALL DL3s

LOOP2:MOV R7,#02H

CLR LED2

SETB LED3

LCALL DL1s

LOOP21:CPL LED3

LCALL DL1s

DJNZ R7,LOOP21

LOOP3:

CLR LED3

CLR LED4

SETB LED1

SETB LED5

LCALL DL3s

LOOP4:MOV R7,#02H

CLR LED5

SETB LED6

LCALL DL1s

LOOP41:CPL LED6

LCALL DL1s

DJNZ R7,LOOP41

LJMP LOOP1

INT0:

CLR EA

MOV Acc,P1

PUSH R1

PUSH R2

PUSH R3

PUSH R4

PUSH Acc

SETB EA

SETB LED1

SETB LED4

CLR LED2

CLR LED3

CLR LED5

CLR LED6

LCALL DL1s

CLR EA

POP Acc

POP R1

POP R2

POP R3

POP R4

MOV P1,Acc

SETB EA

RETI

DL3s:

MOV R1,#250

MOV R2,#200

MOV R3,#30

DL31:

DJNZ R1,DL31

MOV R1,#250

DL32:

DJNZ R2,DL31

MOV R2,#200

DL33:

DJNZ R3,DL31

MOV R3,#30

RET

DL1s:

MOV R1,#250

MOV R2,#200

MOV R4,#10

DL11:

DJNZ R1,DL11

MOV R1,#250

DL12:

DJNZ R2,DL11

MOV R2,#200

DL13:

DJNZ R4,DL11

MOV R4,#10

RET


遇到的问题及解决方法

问题:中断返回时无法恢复中断前的状态(如:中断前南北绿灯刚好亮了一秒这时中断来了,待中断执行完后恢复之前状态沿着中断前南北绿灯亮一秒继续执行)。

解决方法:按之前的程序MOV Acc,P1;PUSH Acc只保护中断前的状态并没有保护各状态执行了多长时间。所以改正后应增加对各寄存器状态也保护起来即下列程序

PUSH R1

PUSH R2

PUSH R3

PUSH R4          
                  硬件实验七   八数码管显示

一、实验要求

利用实验仪提供的显示电路,动态显示一行数据.

、实验目的

1. 了解数码管动态显示的原理。

2. 了解用总线方式控制数码管显示

三、 实验线路及线

这里只是显示草图,详细原理参见图1

、实验说明

1.本实验仪提供了6 位8 段码LED 显示电路,学生只要按地址输出相应数据,就

可以实现对显示器的控制。显示共有6位,用动态方式显示。8 位段码、6位位码是由两片

74LS374输出。位码经MC1413或ULN2003倒相驱动后,选择相应显示位。

本实验仪中 8 位段码输出地址为0X004H,位码输出地址为 0X002H。此处X 是由

KEY/LED CS 决定,参见地址译码。做键盘和LED实验时,需将KEY/LED CS 接到相应的地

址译码上。以便用相应的地址来访问。例如,将KEY/LED CS 接到CS0 上,则段码地址为

08004H,位码地址为08002H。

五、程序框图

程序:

ORG 0000H    LJMP MAIN

ORG 0003H

MAIN:MOV A,#05H     MOV 79H,A     MOV A,#04H     MOV 74H,A    MOV A,#03H

      MOV 7BH,A     MOV A,#02H    MOV 7CH,A      MOV A,#01H   MOV 7DH,A

      MOV A,#00H    MOV 7EH,A     DIR:MOV R0,#79H MOV R3,#01H  MOV A,R3

LD0:MOV DPTR,#8002H  MOVX @DPTR,A   INC DPTR   INC DPTR  MOV A,@R0  ADD A,#0FH

      MOVC A,@A+PC   DIR1:MOVX @DPTR,A   ACALL DL1ms   INC R0   MOV A,R3

     JB Acc.5,LD1  RL A  MOV R3,A  AJMP LD0   LD1:LJMP MAIN

TAB:   DB 3FH,06H,5BH,4FH,66H,6DH       DB 7DH,07H,7FH,6FH,77H,7CH

      DB 39H,5EH,79H,71H,73H,3EH        DB 31H,6EH,1CH,23H,40H,03H

      DB 18H,00

DL1ms:MOV R7,#04H

DL:MOV R6,#7DH

DL6:   DJNZ R6,DL6   DJNZ R7,DL  RET  

END

遇到的问题及解决方法

1.问题:错误使用查表指令MOVC A,@A+DPTR

解决方法:查表指令有两种上面一种和MOVC A,@A+PC,如果使用第一种必须在DPTR未被使用,一旦使用需要在查表以前保护DPTR,这样会增加程序的复杂度所以改用第二种查表方法只需在前面加一条偏移量指令即可。

2.问题:无法显示数据

解决方法:

原程序:

DIR:MOV R0,#79H  MOV R3,#01H   MOV A,R3

LD0:MOV DPTR,#8002H   MOVX @DPTR,A  INC DPTR   INC DPTR   MOV A,@R0   ADD A,#0FH

    MOVC A,@A+PC

DIR1:MOVX @DPTR,A   ACALL DL1ms   INC R0   MOV A,R3  JB Acc.5,LD1   RL A  MOV R3,A  AJMP LD0

LD1:LJMP MAIN

TAB:   DB 3FH,06H,5BH,4FH,66H,6DH   DB 7DH,07H,7FH,6FH,77H,7CH   DB 39H,5EH,79H,71H,73H,3EH

      DB 31H,6EH,1CH,23H,40H,03H    DB 18H,00

DL1ms:MOV R7,#04H

DL:MOV R6,#7DH

DL6:  DJNZ R6,DL6   DJNZ R7,DL  RET

END

由原程序可知,程序中并没有设置要显示的数据。即R0中没有内容,所以需要在原程序前给R0赋值程序如下

增加程序:

ORG 0000H   LJMP MAIN   ORG 0003H

MAIN:MOV A,#05H  MOV 79H,A   MOV A,#04H  MOV 74H,A  MOV A,#03H  MOV 7BH,A  MOV A,#02H 

     MOV 7CH,A   MOV A,#01H   MOV 7DH,A   MOV A,#00H   MOV 7EH,A

          


              硬件实验八   键盘扫描显示实验

一、实验要求

在上一个实验的基础上,利用实验仪提供的键盘扫描电路和显示电路,做一个扫描键盘

和数码显示实验,把按键输入的键码在六位数码管上显示出来。

实验程序可分成三个模块。

①键输入模块:扫描键盘、读取一次键盘并将键值存入键值缓冲单元。

②显示模块:将显示单元的内容在显示器上动态显示。

③主程序:调用键输入模块和显示模块。

、实验目的

1、掌握键盘和显示器的接口方法和编程方法。

2、掌握键盘扫描和LED八段码显示器的工作原理。

三、实验电路及线

这里只是键盘草图,详细原理参见图1

、 实验说明

本实验仪提供了一个6×4的小键盘,向列扫描码地址(0X002H)逐列输出低电平,然后

从行码地址(0X001H)读回。如果有键按下,则相应行的值应为低,如果无键按下,由于上拉

的作用,行码为高。这样就可以通过输出的列码和读取的行码来判断按下的是什么键。在

判断有键按下后,要有一定的延时,防止键盘抖动。地址中的X 是由KEY/LED CS 决定,

参见地址译码。做键盘和LED实验时,需将KEY/LED CS 接到相应的地址译码上。以便

用相应的地址来访问。例如将KEY/LED CS信号接CS0 上,则列扫描地址为08002H,行

码地址为08001H。列扫描码还可以分时用作LED的位选通信号。

五、实验框图

程序:

     ORG 0000H

     LJMP MAIN

     ORG 0030H

MAIN:MOV SP,#60H               ;第一条指令入口地址

KEYI:ACALL KS1            ;调用判定有无键闭合子程序KS1

     JNZ   LK1            ;有键闭合,跳转至LK1

NI:  ACALL  DIR           ;无键闭合,调用显示子程校 ,延迟6毫秒,跳转至KEYI

     AJMP   KEYI

LK1:ACALL  DIR            ;可能有键闭合,延迟12毫秒,软件去抖动

    ACALL  DIR            ;

    ACALL  KS1            ;调用判定有无闭合子程序

    JNZ    LK2            ;经去抖动,判定键确实闭合,跳转至LK2去处理

    ACALL  DIR            ;调用显示子程序延迟6毫秒

    AJMP   KEYI           ;是抖动引起,跳转至KEYI

LK2:MOV  R2,#0FEH         ;定义R2列选码

    MOV  R4,#00H          ;定义R4列号计数器

LK4:MOV DPTR,#08002H      ;列选码入口地址

    MOV A,R2

    MOVX @DPTR,A          ;送入列选码

    MOV DPTR,#08001H      ;行码地址

    MOVX A,@DPTR          ;读行码

    JB ACC.0,LONE         ;0行线为高电平,无键闭合,跳转,转判1行

    MOV  A,#00H           ;0行首建号

    AJMP LKP              ; 跳转,计算键号

LONE:JB ACC.1,LTWO        ; 1行线为高电平,无键闭合,跳转,转判2行

     MOV  A,#06H          ;1行首建号

     AJMP LKP             ; 跳转,计算键号

LTWO:JB ACC.2,LTHR      ;2行线为高电平,无键闭合,跳转,转判3行

     MOV  A,#0CH          ;2行首建号

     AJMP LKP             ;跳转,计算键号

LTHR:JB ACC.3,NEXT      ;3行线为高电平,无键闭合,跳转

       MOV  A,#12H        ;3行首建号

LKP:ADD A,R4              ;计算建号,即行首建号加列号

    PUSH A                ;键号进栈保护

LK3: ACALL DIR            ;调用显示子程序延迟6毫秒

     ACALL DIR

     ACALL KS1            ;调用判定有无键闭合子程序6毫秒

     JNZ   LK3            ;判定键是否释放,未释放,则循环

     POP  A               ;键已释放 ,建号出栈

     MOV B,#0AH            ; 赋值

     DIV AB                ; 除法运算

     MOV 5AH,A

     MOV A,B

     MOV 59H,A            ;置缓冲器指针初值

     RET                  ;返回

NEXT: INC R4              ;列计数器加1

      MOV A,R2            ;判定是否已扫到最后一列

      JNB ACC.5,KND       ;若扫到 最后一列,跳转,重新键盘扫描

      RL A                ;未扫到最后一列,位选码左移一位

      MOV R2,A

      AJMP LK4

KND:AJMP KEYI

KS1:MOV DPTR,#08002H      ;判定有无键闭合子程序

    MOV A,#00H            ; 列线全0

    MOVX @DPTR,A

    MOV DPTR,#08001H      ;行线

    MOVX A,@DPTR          ;读取状态

    CPL A                 ;行状态取反,无键按下,A中内容为0

    ANL  A,#0FH           ;屏蔽无用的高四位

    RET                   ; 返回

DIR:MOV R0,#59H

    MOV R3,#01H           ;把位选码的初值送R3

    MOV A,R3              ;(A)=01H

LD0:MOV DPTR,#08002H      ;置位选码的地址  (DPTR)=8002H

    MOVX @DPTR,A          ;((DPTR))=01H 向片外数据存储器写内容

    MOV DPTR,#08004H      ;置段码的地址  (DPTR)=8004H

    MOV A,@R0             ;读取第一个数据

    ADD A,#0DH            ; 加偏移量(下条指令到表首间所有指令占得单元数)

    MOVC A,@A+PC          ; 根据显示数据来查表取段码

DIR1:MOVX @DPTR,A         ; 数据对应的段码送到段码地址

    ACALL FY1ms           ; 延时1毫秒,即该位显示1毫秒

    INC R0                ; 显示数据缓冲区指针指向下个数据单元

    MOV A,R3              ; 位选码送入A中

    JB Acc.1,LOOP          ; 直接寻址位为1则转移,判断是否扫描到最右边的LED,如到最右边,则返回

    RL A                  ; 位选码向左移一位,准备让显示位右边的下一位LED亮

    MOV R3,A              ; 位选码送R3中保存

    AJMP LD0              ; 跳转

LOOP:    RET

TAB:  DB     3FH,06H,5BH,4FH,66H,6DH        ; 共阴极LED段码表

      DB     7DH,07H,7FH,6FH,77H,7CH

      DB     39H,5EH,79H,71H,73H,3EH

      DB     31H,6EH,1CH,23H,40H,03H

      DB     18H,00

FY1ms: MOV R7,#02H                          ; 延时1毫秒子程序

DL:    MOV R6,#0FFH

DL6:   DJNZ R6,DL6

       DJNZ R7,DL

       RET

遇到的问题及解决方法

1.问题:去除抖动调用显示子程序而不用延时子程序

解决方法:如果调用延时子程序不仅增加程序的复杂度而且会影响显示子程序的效果,调用显示子程序的作用除了能够消除抖动期还有一个作用是显示数据保证之前输入的数据不会消失。

2.问题:使用线反转法

解决方法:使用线反转法必须保证行线与列线都能够作为输入和输出线,但本试验中行线只能作为输入线,列线只能作为输出线。所以按键的识别方法只能使用扫描法。          

相关推荐