【问题标题】:Reading a Keypad and displaying it using Microprocessor读取键盘并使用微处理器显示它
【发布时间】:2015-11-03 15:03:14
【问题描述】:

MTS-88.C 和 I/O BOARD -08 板载有 8 个(八个)7 段显示器和 20 个键盘。显示器编号从 7-SEG.1 到 7-SEG.8,分别连接到端口 B 的 PB7 到 PB0 线。要在 7 段显示器上显示一个字符,必须将一个字节写入端口 B。MSB 4 位是 7 段显示器的地址,LSB 4 位是数据。因此,如果我们将 58 H 写入端口 B,那么第 6 个 7 段显示器将显示数据 8。

20 个键盘从 P01 到 P20 编号,排列为 5 列 4 行。最右边的列连接到 PB0,而最左边的列连接到 PB4。最上面一行连接到 PA0,而最下面一行连接到 PA3。为了检测按键,首先必须通过向端口 B 写入一个字节来激活一列。接下来,应该读取端口 A。第 1、2、3 和 4 行的有效值分别为 1、2、4 和 8。

实验是读取键盘并在指定的7段显示器上显示按下的键id。在这个实验中,我还没有理解下面显示的汇编代码中的一些行。在我没看懂的那些行旁边我做了cmets。

MEMORY ADDRESS   ASSEMBLY CODE    
0000:0476        MOV AL,90
0000:0478        OUT 13,AL
0000:047A        MOV DL,00
0000:047C        MOV CX,0004H  //why storing 4 here
0000:047F        MOV AL,0F
0000:0481        MOV BL,CL
0000:0483        SHL BL,01  //why left shift for 4 times
0000:0485        SHL BL,01   
0000:0487        SHL BL,01
0000:0489        SHL BL,01
0000:048B        OR AL,BL  //why doing OR operation here
0000:048D        OUT 11,AL
0000:048F        IN AL,10
0000:0491        MOV BL,01
0000:0493        TEST AL,BL  //what is testing here
0000:0495        JE O4A7     //when we are jumping(what is the condition)
0000:0497        INC DL   // what are we storing in DL
0000:0499        CMP DL,09
0000:049C        JG  047A  //why are we comparing DL with 9
0000:049E        SHL BL,01
0000:04A0        TEST BL,10  //what is being tested here
0000:04A3        JE 0493
0000:04A5        LOOP O47F
0000:04A7        MOV AL,DL
0000:04A9        OUT 11,AL
0000:04AB        PUSH CX
0000:04AC        MOV CX,500
0000:04AF        NOP   //why is this operation needed
0000:04B0        LOOP 04AF
0000:04B2        POP CX
0000:04B3        JMP 047A

我在上面标记的那些行实际上做了什么?

【问题讨论】:

  • 请不要破坏问题。

标签: assembly microcontroller x86-16 microprocessors


【解决方案1】:

我对显示器和键盘如何使用端口 B 感到困惑。我猜想有一些逻辑可以检测到低 4 位为 1,这对于显示数字无效并且然后切换到键盘模式。

TEST AL,BL //这里测试什么

通过 PA0-PA3 的 4 个低位进行测试,看看设置了哪一个。这是按下的键的行号。请注意BL 已在0491 行初始化为1,并在循环中在049E 行左移。所以它根据需要经过1、2、4和8。

JE O4A7 //我们在跳的时候(条件是什么)

显然键使用负逻辑,即如果按下键,您将获得 0 位。所以条件是寻找那个 0 位。

NOP //为什么需要这个操作

这只是延迟循环的一部分,以使其更长。

INC DL // 我们在 DL 中存储了什么

JG 047A //我们为什么要比较 DL 和 9

认为该代码仅适用于键 0-9,因为它们可以用单个数字表示。所以DL是数字计数器,JG是结束条件。

更新:鉴于新信息,我也可以说:

MOV CX,0004H //这里为什么要存4

CX是列计数器,从4倒数到0。

//为什么要左移4次

由于图表显示您需要前 4 位的列索引,所以这样做。

OR AL,BL //这里为什么要做OR运算

您需要将4F3F2F1F0F输出到端口B。前4位已经设置为正确的列索引,剩下的就是设置低4 位到1。由于AL 已经加载了0F,这就实现了。

算法如下:

start:
    key = 0;
    for(column = 4; column != 0; column--)
    {
        portB = (column << 4) | 0x0f;
        in = portA;
        for(row = 1; row != 0x10; row <<= 1)
        {
            if ((in & row) == 0)
            {
                portB = key;
                goto start;
            }
            if (++key == 10) goto start;
        }
    }
    goto start;

【讨论】:

  • DL 是在计算按键被按下的次数还是检查哪个键被按下? @小丑
  • 在数哪个。
  • 请您对 TEST AL,BL 行做更多解释好吗?我的意思是当一个键被按下时,行和列值发生了什么,我们通过 AL 和 BL 检查了什么? @小丑
  • BL 有一个位集,它被反复向左移动。这就是测试0001001001001000(二进制)。参见0491049E 行。它测试行值以找到一个为零的值。至于列值,应该在循环中类似地选择这些值,除了代码中(也不是文档中)不清楚的部分。
  • 4 厘米前刚刚告诉过你。 1、2、4 和 8 = 0001001001001000
猜你喜欢
  • 2015-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-02
  • 2012-12-11
  • 1970-01-01
  • 1970-01-01
  • 2017-04-24
相关资源
最近更新 更多