实验题目

给出使用Proteus仿真软件搭建的一个数码管显示的电路(截图如下),要求编程实现以下功能:

1.两个数码管显示2位十六进制数,初始值为0

2.开关SW1输入为0时,显示的数字每隔一段时间自动增1

exp2_1.png

3.按复位键复位

Alt text

学习路径

1.学习74LS164元件

74LS164元件是一个8位边沿触发式移位寄存器,主要功能是将串行输出转换为并行输出。形象的说,如果想让数码管显11111111B这个段码,可以直接从单片机的8个引脚连线到数码管,让单片机一次输出8位的段码,但是这样占用太多引脚了。一种改进方法是:从单片机连接1个引脚到74LS164元件,然后再从这个元件连接8条线到数码管。单片机输出8次,每次输出1位,然后由74LS164一次性输出8位到数码管,这样就减少了单片机的针脚占用。 在编写代码之前,还需要弄清74LS164的引脚功能,串行转并行的具体原理,以及多片74LS164元件串联使用的方法。

2.看懂电路图

电路中连接了三个8段数码管,左上角的数码管直接连接至单片机P0口,右下角两个数码管通过两个串联的74LS164元件连接至单片机。

3.学习MCS-51体系结构和汇编语言、

主要学习MCS-51寄存器,存储结构,指令系统等内容。 可以参考附录三_MCS-51系统结构与指令系统。

3.学习使用Proteus软件

proteus软件只在本次实验中使用,所以只需要学习本次实验用到的的编程,运行和调试功能即可。

编程思路

本实验的程序逻辑并不复杂,我们可以想想如果是用c语言,如何编程。

程序可以将要显示的两个数字分别存储在两个寄存器中,程序的主体内容就是一个死循环。

死循环分为三部分。

  • 第一部分,检查开关SW1状态是否按下,如果为1,跳过第二部分。
  • 第二部分,将存储在寄存器里的两个数字显示出来,并且数字+1。
  • 第三部分,延迟一段时间

显示的部分比较复杂,这里再展开讲讲。(文末参考代码并未使用这个思路)

  • 首先,根据要显示的数字的个位,使用MOVC指令,从段码表中取出要显示的段码。
  • 然后,使用LRC或RRC指令,取出要显示的段码的最高位或最低位,输出给74LS164元件
  • 重复上一步骤8次,将8位段码依次输出给74LS164元件,将个位显示在数码管上
  • 重复以上全部步骤,将十位显示在数码管上

快速开始

1.首先给出一个编程框架,我们要编写的代码都在start标签之后

ORG  0000H        ;复位初始地址
     JMP START
ORG  0100H        ;程序起始地址
START:	

2.给出点亮左上数码管的代码,即不使用74LS164元件点亮左上数码管的代码

ORG  0000H        ;复位初始地址
     JMP START
ORG  0100H        ;程序起始地址
START:	
     MOV A,#3FH;   ;将数字0的段码赋值给寄存器A
     MOV P0,A;     ;将寄存器A中的值输出至P0端口
ED:  JMP ED

3.给出使用74LS164元件点亮右下角一个数码管中的一位的代码

ORG  0000H        ;复位初始地址
     JMP START
ORG  0100H        ;程序起始地址
START:	
     CLR P1.4     ;P1.4用于产生上升沿
     SETB P1.5    ;P1.5用于输出数据
     SETB P1.4
ED:  JMP ED

参考代码

org   0100h
TABLE: 
DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H
Start:  
      ;设置DPTR寄存器为段码表首址
      MOV DPTR,#TABLE

      ;关闭第一组数码管
      MOV A,#00H;
      MOV P0,A; 
      
init:  
      ;RO置0
      MOV R0,#0
      ;R1置0
      MOV R1,#0 
      
display:
    ;数码管复位
    CLR P1.4
    CLR P1.1
    SETB P1.1
      
    ;在数码管显示R0
    MOV A,R0
    MOVC A,@A+DPTR
    MOV R2,A
    LCALL displayone
      
    ;在数码管显示R1
    MOV A,R1
    MOVC A,@A+DPTR
    MOV R2,A
    LCALL displayone
      
    ;延迟
    LCALL DELAY
      
    ;判断按键是否按下
    MOV C,P1.0
      
        ;按键没有按下,无操作
        JC display
          
        ;按键被按下,R0自增
        INC R0
        ;R0增加到16时清零
        MOV A,R0
          
        CJNE A,#16,display;比较不相等转移指令
          
        ;此处为R0=16的代码
        INC R1
        MOV A,R1
        MOV R0,#0 
      
    JMP display 

delay:
    ;delay
    MOV R7,#2
    K1:MOV R6,#255
    K2:MOV R5,#255
    K3:DJNZ R5,K3
    DJNZ R6,K2
    DJNZ R7,K1
    RET

displayone:
    ;显示R2的内容 R2=0011 1111
    MOV R4,#8
      
    ;R2左移
    MOV A,R2
    RL A 
    MOV R2,A ;R2=0111 1110
      
    lp:
        ;取r2最低位
        MOV A,#1
        ANL A,R2
            
        ;将r2最低位赋值给c
        CLR C
        JZ lpend
        SETB C
        lpend:
                
        ;输出
        CLR P1.4
        MOV P1.5, C
        SETB P1.4
                
        ;R2左移
        MOV A,R2
        RL A
        MOV R2,A
                
        ;循环
        DJNZ R4,lp
    RET

避坑指南

1.在数码管显示部分,注意移位输出时,是左移还是右移,以及为什么是左移或者右移。

2.实验要求按复位键之后数字清零。复位键的实际功能是通过中断让代码从头开始执行,而没有清空存储器和寄存器。所以如果想要按复位键后,让显示的数字回到零,就需要在程序开始部分给寄存器清零。

3.建议将显示的部分模块化,并标记好在每一个模块使用的寄存器。在实验箱上有3个数码管,也是通过类似的原理连接在一起。数码管显示未来会作为实验的子任务,比如控制电机转动,在数码管上显示圈数。