问题
MTS-88.C and I/O BOARD -08 has 8 (Eight) 7-segment displays and 20 key-pads on board. The displays are numbered from 7-SEG.1 to 7-SEG.8 and are connected to Port B’s PB7 to PB0 lines respectively. To display a character on a 7-segment display a byte has to be written to port B. The MSB 4 bits are the address of the 7-segment display and LSB 4 bits are the data. So if we write 58 H to port B then the 6th 7-segment display will show data 8.
20 key-pads are numbered from P01 to P20 and are arranged in 5 columns and 4 rows. Rightmost column is connected to PB0 while leftmost column is connected to PB4. Topmost row is connected to PA0 while bottom-most row is connected to PA3. For detecting a key press, first a column must be activated by writing a byte to port B. Next, port A should be read. The valid values are 1, 2, 4 and 8 for row 1, 2, 3 and 4 respectively.
The experiment is to read the keypad and display the pressed key id on the specified 7-segment display. In this experiment, I haven't understood some lines in the assembly code I have shown below. I have made comments beside those lines which I haven't understood.
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
What is actually being done with those lines I have marked above?
回答1:
I am puzzled how both the display and the keyboard uses port B. I guess there is some logic which detects the low 4 bits being 1
which would be invalid for a digit to display and then it switches into keyboard mode.
TEST AL,BL //what is testing here
It's testing through the 4 low bits of PA0-PA3 to see which one is set. This is the row number of the key pressed. Note that BL
has been initialized to 1 at line 0491
and it is shifted left on line 049E
in a loop. So it goes through 1, 2, 4 and 8 as required.
JE O4A7 //when we are jumping(what is the condition)
Apparently the keys use negative logic, that is you will get a 0 bit if a key is pressed. So the condition is looking for that 0 bit.
NOP //why is this operation needed
That's just part of a delay loop to make it longer.
INC DL // what are we storing in DL
JG 047A //why are we comparing DL with 9
I think the code only works for keys 0-9 because those can be represented by a single digit. So DL
is the digit counter and the JG is for the end condition.
Update: given the new information, I can also say:
MOV CX,0004H //why storing 4 here
CX
is the column counter, it is counting down from 4 to 0.
//why left shift for 4 times
Since the diagram shows you need the column index in the top 4 bits, this does that.
OR AL,BL //why doing OR operation here
You need to output 4F
, 3F
, 2F
, 1F
, 0F
to port B. The top 4 bits are already set to the correct column index, what's left is to set the low 4 bits to 1
. Since AL
has been loaded with 0F
, this achieves that.
The algorithm is as follows:
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;
来源:https://stackoverflow.com/questions/33502350/reading-a-keypad-and-displaying-it-using-microprocessor