MTS-88.C和I / O BOARD -08有8个(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 。在这个实验中,我还没有理解我在下面显示的汇编代码中的一些行。我在那些我不理解的界限旁边做了评论。
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
我上面标记的那些线实际上做了什么?
答案 0 :(得分:2)
我很困惑显示器和键盘如何使用端口B.我猜测有一些逻辑检测到低4位是1
,这对于数字来说是无效的显示然后它切换到键盘模式。
测试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操作
您需要将4F
,3F
,2F
,1F
,0F
输出到端口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;